diff --git a/docs/topics/chapter-5.md b/docs/topics/chapter-5.md index ade86335..660ff43c 100644 --- a/docs/topics/chapter-5.md +++ b/docs/topics/chapter-5.md @@ -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) > \ No newline at end of file