rewrite audio spec to improve logical hardware

This commit is contained in:
bQUARKz 2026-01-14 11:09:46 +00:00
parent 5fce506365
commit e0fccbae6b
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8

View File

@ -6,258 +6,308 @@
O **Periférico AUDIO** é responsável pela **geração e mistura de som** no PROMETEU. 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 é automático
- **não é gratuito** - não é gratuito
- **não é mágico** - 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 consome tempo.
Som também consome memória. > Som consome memória.
>
--- ---
## 2. Filosofia do Sistema de Áudio ## 2. Filosofia
PROMETEU trata áudio como: PROMETEU trata áudio como:
- um **periférico ativo** - um **periférico ativo**
- com **canais limitados, previsíveis** - com **canais limitados**
- e **comportamento determinístico** - 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: O sistema de áudio é composto por:
- **Canais de áudio** — fontes independentes de som - **Voices (canais)** — tocadores independentes
- **Samples** — dados sonoros curtos - **Samples** — dados PCM
- **Music streams** — trilhas contínuas - **Mixer** — soma das voices
- **Mixer** — combinação final dos canais - **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 ### 6.2 Implementação é Papel do Host
- ou a chamada pode ser ignorada
(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) Campos:
- feedback imediato
- sons repetitivos
Samples: - `sample_rate`
- `frames_len`
- ocupam memória - `loop_start`, `loop_end` (opcional)
- são imutáveis durante execução
- devem ser carregados conscientemente
--- ---
### 5.2 Custo dos Samples ### 7.2 Uso
Cada sample tem custo associado a: Exemplo:
- 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:
``` ```
audio.musicPlay(trackId) audio.play(sample_id, voice_id, volume, pan, pitch, priority)
audio.musicStop()
audio.musicSetVolume(v)
``` ```
Essas operações: Ou:
- 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:
``` ```
Frame 24510: audio.playAuto(sample_id, volume, pan, pitch, priority)
audio.play():120cycles
audio.mixer():380cycles
``` ```
Excessos: (usa política de stealing)
- não bloqueiam o jogo
- aparecem na certificação
--- ---
## 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 - reutilizar samples
- limitar canais simultâneos - limitar voices simultâneas
- tratar áudio como evento - tratar som como evento
- separar música de efeitos - separar música e efeitos
E desencoraja: Evitar:
- tocar sons repetidamente por frame - tocar som todo frame
- usar muitos canais sem necessidade - abusar de voices
- samples grandes para efeitos simples - 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 - NES: canais fixos
- mixagem simples do SNES - SNES: sample playback + mixagem
- hardware de áudio previsível - CPS2: polifonia confortável
- Neo Geo: sample pesado (não copiado integralmente)
Mas abstraído para: Mas abstraído para:
@ -265,30 +315,17 @@ Mas abstraído para:
- simplicidade - simplicidade
- ensino - 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: - Output: PCM16 estéreo @ 48kHz
- 16 voices
- concorrência limitada - Samples PCM16 mono
- eventos temporais - Volume, pan, pitch
- impacto de recursos em tempo real - Interpolação linear
- separação entre lógica e apresentação sonora - Mixer explícito
- Conceito de “CPU de áudio”
Tudo isso com **feedback auditivo e mensurável**. - Implementação é papel do host
---
## 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
< [Voltar](chapter-4.md) | [Sumário](table-of-contens.md) | [Adiante](chapter-6.md) > < [Voltar](chapter-4.md) | [Sumário](table-of-contens.md) | [Adiante](chapter-6.md) >