rewrite audio spec to improve logical hardware
This commit is contained in:
parent
d2277fc4a9
commit
b0f4a865ad
@ -6,258 +6,308 @@
|
||||
|
||||
O **Periférico AUDIO** é responsável pela **geração e mistura de som** no PROMETEU.
|
||||
|
||||
Assim como os demais subsistemas, o áudio:
|
||||
Assim como os demais subsistemas:
|
||||
|
||||
- **não é automático**
|
||||
- **não é gratuito**
|
||||
- **não é mágico**
|
||||
- não é automático
|
||||
- não é gratuito
|
||||
- não é mágico
|
||||
|
||||
Cada som ouvido é resultado de **comandos explícitos**, executados sob **orçamento de tempo e recursos**.
|
||||
Cada som é resultado de **comandos explícitos**, executados sob **orçamento de tempo e recursos**.
|
||||
|
||||
> Som também consome tempo.
|
||||
Som também consome memória.
|
||||
>
|
||||
> Som consome tempo.
|
||||
> Som consome memória.
|
||||
|
||||
---
|
||||
|
||||
## 2. Filosofia do Sistema de Áudio
|
||||
## 2. Filosofia
|
||||
|
||||
PROMETEU trata áudio como:
|
||||
|
||||
- um **periférico ativo**
|
||||
- com **canais limitados, previsíveis**
|
||||
- e **comportamento determinístico**
|
||||
- com **canais limitados**
|
||||
- comportamento **determinístico**
|
||||
- controle **explícito**
|
||||
|
||||
O objetivo não é realismo absoluto, mas **clareza arquitetural**.
|
||||
Objetivo: clareza arquitetural e didática, não realismo absoluto.
|
||||
|
||||
---
|
||||
|
||||
## 3. Componentes do Periférico AUDIO
|
||||
## 3. Arquitetura Geral
|
||||
|
||||
O sistema de áudio é composto por:
|
||||
|
||||
- **Canais de áudio** — fontes independentes de som
|
||||
- **Samples** — dados sonoros curtos
|
||||
- **Music streams** — trilhas contínuas
|
||||
- **Mixer** — combinação final dos canais
|
||||
- **Voices (canais)** — tocadores independentes
|
||||
- **Samples** — dados PCM
|
||||
- **Mixer** — soma das voices
|
||||
- **Saída** — buffer estéreo PCM
|
||||
|
||||
Cada componente tem custo explícito.
|
||||
Separação conceitual:
|
||||
|
||||
- Jogo envia **comandos a 60Hz**
|
||||
- Áudio é **gerado continuamente** em 48kHz
|
||||
|
||||
---
|
||||
|
||||
## 4. Canais de Áudio
|
||||
## 4. Formato de Saída
|
||||
|
||||
### 4.1 Definição
|
||||
- Sample rate: **48.000 Hz**
|
||||
- Formato: **PCM16 estéreo (signed i16)**
|
||||
- Clipping: saturação/clamp
|
||||
|
||||
Um **canal de áudio** representa uma fonte sonora independente.
|
||||
Esse formato é compatível com:
|
||||
|
||||
Características:
|
||||
- DACs I2S comuns
|
||||
- HDMI áudio
|
||||
- USB áudio
|
||||
- SBCs DIY (Raspberry Pi, Orange Pi, etc.)
|
||||
|
||||
- número máximo de canais é limitado
|
||||
- cada canal toca **um som por vez**
|
||||
- canais são misturados no output final
|
||||
---
|
||||
|
||||
Exemplo conceitual:
|
||||
## 5. Voices (Canais)
|
||||
|
||||
### 5.1 Quantidade
|
||||
|
||||
```
|
||||
Max Channels:8
|
||||
MAX_VOICES = 16
|
||||
```
|
||||
|
||||
Cada voice:
|
||||
|
||||
- toca **1 sample por vez**
|
||||
- é independente
|
||||
- é misturada no output final
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Uso dos Canais
|
||||
### 5.2 Estado de uma Voice
|
||||
|
||||
Quando um som é tocado:
|
||||
Cada voice mantém:
|
||||
|
||||
- `sample_id`
|
||||
- `pos` (posição fracionária no sample)
|
||||
- `rate` (pitch)
|
||||
- `volume` (0..255)
|
||||
- `pan` (0..255, esquerda→direita)
|
||||
- `loop_mode` (off / on)
|
||||
- `loop_start`, `loop_end`
|
||||
- `priority` (opcional)
|
||||
|
||||
---
|
||||
|
||||
### 5.3 Conflito de Voices
|
||||
|
||||
Se todas as voices estiverem ocupadas:
|
||||
|
||||
- aplica-se uma política explícita:
|
||||
- `STEAL_OLDEST`
|
||||
- `STEAL_QUIETEST`
|
||||
- `STEAL_LOWEST_PRIORITY`
|
||||
|
||||
|
||||
PROMETEU não resolve isso automaticamente sem regra definida.
|
||||
|
||||
---
|
||||
|
||||
## 6. Modelo Conceitual: “CPU de Áudio”
|
||||
|
||||
O AUDIO do PROMETEU é concebido como um **periférico independente**, assim como consoles clássicos tinham:
|
||||
|
||||
- CPU principal do jogo
|
||||
- CPU dedicada ao som
|
||||
|
||||
No PROMETEU:
|
||||
|
||||
- O **core lógico** assume essa separação conceitual
|
||||
- O **host decide** como implementar:
|
||||
- mesma thread
|
||||
- thread separada
|
||||
- core separado
|
||||
|
||||
### 6.1 Metáfora de Hardware
|
||||
|
||||
Conceitualmente:
|
||||
|
||||
```
|
||||
audio.play(sampleId, channel)
|
||||
[CPU do Jogo] → envia comandos 60Hz → [Periférico AUDIO]
|
||||
|
|
||||
v
|
||||
Voices + Mixer
|
||||
|
|
||||
v
|
||||
Saída PCM
|
||||
```
|
||||
|
||||
Se o canal estiver ocupado:
|
||||
|
||||
- o som anterior pode ser interrompido
|
||||
- ou a chamada pode ser ignorada
|
||||
### 6.2 Implementação é Papel do Host
|
||||
|
||||
(dependendo da política definida)
|
||||
O core:
|
||||
|
||||
- define o **modelo**
|
||||
- define os **comandos**
|
||||
- define os **limites**
|
||||
|
||||
PROMETEU **não gerencia prioridades automaticamente**.
|
||||
O host:
|
||||
|
||||
- escolhe:
|
||||
- threads
|
||||
- afinidade de CPU
|
||||
- backend de áudio
|
||||
- garante entrega contínua dos buffers
|
||||
|
||||
Assim:
|
||||
|
||||
> PROMETEU modela o hardware.
|
||||
> O host decide como realizá-lo fisicamente.
|
||||
|
||||
---
|
||||
|
||||
## 5. Samples (Efeitos Sonoros)
|
||||
## 7. Samples
|
||||
|
||||
### 5.1 Definição
|
||||
### 7.1 Formato
|
||||
|
||||
Um **sample** é um trecho curto de áudio pré-carregado.
|
||||
Samples do PROMETEU:
|
||||
|
||||
Usado para:
|
||||
- **PCM16 mono**
|
||||
- sample_rate próprio (ex.: 22050, 44100, 48000)
|
||||
- dados imutáveis em runtime
|
||||
|
||||
- efeitos (tiros, passos, colisões)
|
||||
- feedback imediato
|
||||
- sons repetitivos
|
||||
Campos:
|
||||
|
||||
Samples:
|
||||
|
||||
- ocupam memória
|
||||
- são imutáveis durante execução
|
||||
- devem ser carregados conscientemente
|
||||
- `sample_rate`
|
||||
- `frames_len`
|
||||
- `loop_start`, `loop_end` (opcional)
|
||||
|
||||
---
|
||||
|
||||
### 5.2 Custo dos Samples
|
||||
### 7.2 Uso
|
||||
|
||||
Cada sample tem custo associado a:
|
||||
|
||||
- tamanho em memória
|
||||
- taxa de reprodução
|
||||
- duração
|
||||
|
||||
Reproduzir muitos samples simultaneamente:
|
||||
|
||||
- consome mais ciclos
|
||||
- aumenta pressão no mixer
|
||||
|
||||
---
|
||||
|
||||
## 6. Music Streams (Trilha Sonora)
|
||||
|
||||
### 6.1 Definição
|
||||
|
||||
**Music streams** são sons contínuos, geralmente mais longos.
|
||||
|
||||
Características:
|
||||
|
||||
- tocados em loop ou sequência
|
||||
- geralmente ocupam um canal dedicado
|
||||
- podem ser streamados para reduzir uso de memória
|
||||
|
||||
---
|
||||
|
||||
### 6.2 Controle de Música
|
||||
|
||||
Operações típicas:
|
||||
Exemplo:
|
||||
|
||||
```
|
||||
audio.musicPlay(trackId)
|
||||
audio.musicStop()
|
||||
audio.musicSetVolume(v)
|
||||
audio.play(sample_id, voice_id, volume, pan, pitch, priority)
|
||||
```
|
||||
|
||||
Essas operações:
|
||||
|
||||
- têm custo explícito
|
||||
- afetam o mixer global
|
||||
|
||||
PROMETEU não faz crossfade automático sem instrução explícita.
|
||||
|
||||
---
|
||||
|
||||
## 7. Mixer de Áudio
|
||||
|
||||
### 7.1 Função do Mixer
|
||||
|
||||
O **mixer** combina os canais ativos em um único sinal de saída.
|
||||
|
||||
O custo do mixer depende de:
|
||||
|
||||
- número de canais ativos
|
||||
- complexidade do som
|
||||
- efeitos aplicados (se houver)
|
||||
|
||||
Mais canais ativos → mais custo por frame.
|
||||
|
||||
---
|
||||
|
||||
### 7.2 Efeitos Simples
|
||||
|
||||
PROMETEU pode suportar efeitos básicos:
|
||||
|
||||
- volume por canal
|
||||
- pan (esquerda/direita)
|
||||
- mute
|
||||
|
||||
Efeitos:
|
||||
|
||||
- são explícitos
|
||||
- têm custo mensurável
|
||||
- não são aplicados automaticamente
|
||||
|
||||
---
|
||||
|
||||
## 8. Sincronização Temporal do Áudio
|
||||
|
||||
### 8.1 Relação com o Clock do Sistema
|
||||
|
||||
O áudio em PROMETEU é sincronizado com o **clock base de 60 Hz**.
|
||||
|
||||
Isso significa:
|
||||
|
||||
- atualizações de áudio ocorrem por frame
|
||||
- eventos sonoros são disparados em ticks definidos
|
||||
- latência é previsível e estável
|
||||
|
||||
---
|
||||
|
||||
### 8.2 Áudio como Evento
|
||||
|
||||
PROMETEU incentiva tratar áudio como **evento**, não como estado contínuo:
|
||||
|
||||
- tocar som ao ocorrer uma ação
|
||||
- evitar chamadas repetidas por frame
|
||||
- desacoplar áudio da lógica pesada
|
||||
|
||||
Isso reduz custo e melhora clareza.
|
||||
|
||||
---
|
||||
|
||||
## 9. Áudio e CAP
|
||||
|
||||
O sistema de áudio participa do **Execution CAP**:
|
||||
|
||||
- reprodução de sons consome ciclos
|
||||
- mixagem entra no orçamento por frame
|
||||
- picos de áudio são registrados
|
||||
|
||||
Exemplo de relatório:
|
||||
Ou:
|
||||
|
||||
```
|
||||
Frame 24510:
|
||||
audio.play():120cycles
|
||||
audio.mixer():380cycles
|
||||
audio.playAuto(sample_id, volume, pan, pitch, priority)
|
||||
```
|
||||
|
||||
Excessos:
|
||||
|
||||
- não bloqueiam o jogo
|
||||
- aparecem na certificação
|
||||
(usa política de stealing)
|
||||
|
||||
---
|
||||
|
||||
## 10. Boas Práticas de Áudio
|
||||
## 8. Pitch e Interpolação
|
||||
|
||||
PROMETEU incentiva:
|
||||
- `rate = 1.0` → velocidade normal
|
||||
- `rate > 1.0` → mais agudo
|
||||
- `rate < 1.0` → mais grave
|
||||
|
||||
Como posição vira fracionária:
|
||||
|
||||
- usa-se **interpolação linear** entre dois samples vizinhos
|
||||
|
||||
---
|
||||
|
||||
## 9. Mixer
|
||||
|
||||
Para cada frame de saída (48kHz):
|
||||
|
||||
1. Para cada voice ativa:
|
||||
- ler sample na posição atual
|
||||
- aplicar pitch
|
||||
- aplicar volume
|
||||
- aplicar pan → gera L/R
|
||||
2. Somar todas as voices
|
||||
3. Aplicar clamp
|
||||
4. Escrever no buffer estéreo
|
||||
|
||||
Custo depende de:
|
||||
|
||||
- número de voices ativas
|
||||
- uso de interpolação
|
||||
|
||||
---
|
||||
|
||||
## 10. Sincronização com o Jogo
|
||||
|
||||
- Jogo roda a **60Hz**
|
||||
- Áudio gera dados a **48kHz**
|
||||
|
||||
A cada frame (60Hz):
|
||||
|
||||
- jogo envia comandos:
|
||||
- play
|
||||
- stop
|
||||
- set_volume
|
||||
- set_pan
|
||||
- set_pitch
|
||||
|
||||
O áudio aplica esses comandos e continua tocando.
|
||||
|
||||
---
|
||||
|
||||
## 11. Comandos Básicos
|
||||
|
||||
Exemplos conceituais:
|
||||
|
||||
```
|
||||
audio.play(sample, voice, volume, pan, pitch, priority)
|
||||
audio.stop(voice)
|
||||
audio.setVolume(voice, v)
|
||||
audio.setPan(voice, p)
|
||||
audio.setPitch(voice, p)
|
||||
audio.isPlaying(voice)
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 12. Áudio e CAP
|
||||
|
||||
O áudio participa do Execution CAP:
|
||||
|
||||
- custo de mixagem por frame
|
||||
- custo por voice ativa
|
||||
- custo de comandos
|
||||
|
||||
Exemplo:
|
||||
|
||||
```
|
||||
Frame 1024:
|
||||
voices_active: 9
|
||||
mix_cycles: 410
|
||||
audio_commands: 6
|
||||
```
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 13. Boas Práticas
|
||||
|
||||
Recomendado:
|
||||
|
||||
- reutilizar samples
|
||||
- limitar canais simultâneos
|
||||
- tratar áudio como evento
|
||||
- separar música de efeitos
|
||||
- limitar voices simultâneas
|
||||
- tratar som como evento
|
||||
- separar música e efeitos
|
||||
|
||||
E desencoraja:
|
||||
Evitar:
|
||||
|
||||
- tocar sons repetidamente por frame
|
||||
- usar muitos canais sem necessidade
|
||||
- samples grandes para efeitos simples
|
||||
- tocar som todo frame
|
||||
- abusar de voices
|
||||
- samples gigantes para efeitos simples
|
||||
|
||||
---
|
||||
|
||||
## 11. Relação com Consoles Clássicos
|
||||
## 14. Inspiração Histórica
|
||||
|
||||
O modelo de áudio PROMETEU é inspirado em:
|
||||
O modelo PROMETEU se inspira em:
|
||||
|
||||
- canais dedicados do NES
|
||||
- mixagem simples do SNES
|
||||
- hardware de áudio previsível
|
||||
- NES: canais fixos
|
||||
- SNES: sample playback + mixagem
|
||||
- CPS2: polifonia confortável
|
||||
- Neo Geo: sample pesado (não copiado integralmente)
|
||||
|
||||
Mas abstraído para:
|
||||
|
||||
@ -265,30 +315,17 @@ Mas abstraído para:
|
||||
- simplicidade
|
||||
- ensino
|
||||
|
||||
O objetivo é entender **como o som é produzido**, não emular chips específicos.
|
||||
|
||||
---
|
||||
|
||||
## 12. Implicações Pedagógicas
|
||||
## 15. Resumo
|
||||
|
||||
O Periférico AUDIO permite ensinar:
|
||||
|
||||
- concorrência limitada
|
||||
- eventos temporais
|
||||
- impacto de recursos em tempo real
|
||||
- separação entre lógica e apresentação sonora
|
||||
|
||||
Tudo isso com **feedback auditivo e mensurável**.
|
||||
|
||||
---
|
||||
|
||||
## 13. Resumo
|
||||
|
||||
- áudio é um periférico explícito
|
||||
- canais são limitados
|
||||
- samples ocupam memória
|
||||
- mixagem consome ciclos
|
||||
- áudio participa do CAP
|
||||
- som é consequência de decisões técnicas
|
||||
- Output: PCM16 estéreo @ 48kHz
|
||||
- 16 voices
|
||||
- Samples PCM16 mono
|
||||
- Volume, pan, pitch
|
||||
- Interpolação linear
|
||||
- Mixer explícito
|
||||
- Conceito de “CPU de áudio”
|
||||
- Implementação é papel do host
|
||||
|
||||
< [Voltar](chapter-4.md) | [Sumário](table-of-contens.md) | [Adiante](chapter-6.md) >
|
||||
Loading…
x
Reference in New Issue
Block a user