331 lines
5.2 KiB
Markdown
331 lines
5.2 KiB
Markdown
< [Voltar](chapter-4.md) | [Sumário](table-of-contents.md) | [Adiante](chapter-6.md) >
|
|
|
|
# 🔊 Periférico AUDIO (Sistema de Som)
|
|
|
|
## 1. Visão Geral
|
|
|
|
O **Periférico AUDIO** é responsável pela **geração e mistura de som** no PROMETEU.
|
|
|
|
Assim como os demais subsistemas:
|
|
|
|
- não é automático
|
|
- não é gratuito
|
|
- não é mágico
|
|
|
|
Cada som é resultado de **comandos explícitos**, executados sob **orçamento de tempo e recursos**.
|
|
|
|
> Som consome tempo.
|
|
> Som consome memória.
|
|
|
|
---
|
|
|
|
## 2. Filosofia
|
|
|
|
PROMETEU trata áudio como:
|
|
|
|
- um **periférico ativo**
|
|
- com **canais limitados**
|
|
- comportamento **determinístico**
|
|
- controle **explícito**
|
|
|
|
Objetivo: clareza arquitetural e didática, não realismo absoluto.
|
|
|
|
---
|
|
|
|
## 3. Arquitetura Geral
|
|
|
|
O sistema de áudio é composto por:
|
|
|
|
- **Voices (canais)** — tocadores independentes
|
|
- **Samples** — dados PCM
|
|
- **Mixer** — soma das voices
|
|
- **Saída** — buffer estéreo PCM
|
|
|
|
Separação conceitual:
|
|
|
|
- Jogo envia **comandos a 60Hz**
|
|
- Áudio é **gerado continuamente** em 48kHz
|
|
|
|
---
|
|
|
|
## 4. Formato de Saída
|
|
|
|
- Sample rate: **48.000 Hz**
|
|
- Formato: **PCM16 estéreo (signed i16)**
|
|
- Clipping: saturação/clamp
|
|
|
|
Esse formato é compatível com:
|
|
|
|
- DACs I2S comuns
|
|
- HDMI áudio
|
|
- USB áudio
|
|
- SBCs DIY (Raspberry Pi, Orange Pi, etc.)
|
|
|
|
---
|
|
|
|
## 5. Voices (Canais)
|
|
|
|
### 5.1 Quantidade
|
|
|
|
```
|
|
MAX_VOICES = 16
|
|
```
|
|
|
|
Cada voice:
|
|
|
|
- toca **1 sample por vez**
|
|
- é independente
|
|
- é misturada no output final
|
|
|
|
---
|
|
|
|
### 5.2 Estado de uma Voice
|
|
|
|
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:
|
|
|
|
```
|
|
[CPU do Jogo] → envia comandos 60Hz → [Periférico AUDIO]
|
|
|
|
|
v
|
|
Voices + Mixer
|
|
|
|
|
v
|
|
Saída PCM
|
|
```
|
|
|
|
|
|
### 6.2 Implementação é Papel do Host
|
|
|
|
O core:
|
|
|
|
- define o **modelo**
|
|
- define os **comandos**
|
|
- define os **limites**
|
|
|
|
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.
|
|
|
|
---
|
|
|
|
## 7. Samples
|
|
|
|
### 7.1 Formato
|
|
|
|
Samples do PROMETEU:
|
|
|
|
- **PCM16 mono**
|
|
- sample_rate próprio (ex.: 22050, 44100, 48000)
|
|
- dados imutáveis em runtime
|
|
|
|
Campos:
|
|
|
|
- `sample_rate`
|
|
- `frames_len`
|
|
- `loop_start`, `loop_end` (opcional)
|
|
|
|
---
|
|
|
|
### 7.2 Uso
|
|
|
|
Exemplo:
|
|
|
|
```
|
|
audio.play(sample_id, voice_id, volume, pan, pitch, priority)
|
|
```
|
|
|
|
Ou:
|
|
|
|
```
|
|
audio.playAuto(sample_id, volume, pan, pitch, priority)
|
|
```
|
|
|
|
(usa política de stealing)
|
|
|
|
---
|
|
|
|
## 8. Pitch e Interpolação
|
|
|
|
- `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 voices simultâneas
|
|
- tratar som como evento
|
|
- separar música e efeitos
|
|
|
|
Evitar:
|
|
|
|
- tocar som todo frame
|
|
- abusar de voices
|
|
- samples gigantes para efeitos simples
|
|
|
|
---
|
|
|
|
## 14. Inspiração Histórica
|
|
|
|
O modelo PROMETEU se inspira em:
|
|
|
|
- NES: canais fixos
|
|
- SNES: sample playback + mixagem
|
|
- CPS2: polifonia confortável
|
|
- Neo Geo: sample pesado (não copiado integralmente)
|
|
|
|
Mas abstraído para:
|
|
|
|
- clareza
|
|
- simplicidade
|
|
- ensino
|
|
|
|
---
|
|
|
|
## 15. Resumo
|
|
|
|
- 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-contents.md) | [Adiante](chapter-6.md) > |