2026-01-19 07:28:14 +00:00

331 lines
5.1 KiB
Markdown

< [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >
# 🔊 AUDIO Peripheral (Audio System)
## 1. Overview
The **AUDIO Peripheral** is responsible for **sound generation and mixing** in PROMETEU.
Just like the other subsystems:
- it is not automatic
- it is not free
- it is not magic
Each sound is the result of **explicit commands**, executed under a **time and resource budget**.
> Sound consumes time.
> Sound consumes memory.
---
## 2. Philosophy
PROMETEU treats audio as:
- an **active peripheral**
- with **limited channels**
- **deterministic** behavior
- **explicit** control
Objective: architectural and didactic clarity, not absolute realism.
---
## 3. General Architecture
The audio system is composed of:
- **Voices (channels)** — independent players
- **Samples** — PCM data
- **Mixer** — summation of voices
- **Output** — PCM stereo buffer
Conceptual separation:
- Game sends **commands at 60Hz**
- Audio is **generated continuously** at 48kHz
---
## 4. Output Format
- Sample rate: **48,000 Hz**
- Format: **PCM16 stereo (signed i16)**
- Clipping: saturation/clamp
This format is compatible with:
- common I2S DACs
- HDMI audio
- USB audio
- DIY SBCs (Raspberry Pi, Orange Pi, etc.)
---
## 5. Voices (Channels)
### 5.1 Quantity
```
MAX_VOICES = 16
```
Each voice:
- plays **1 sample at a time**
- is independent
- is mixed into the final output
---
### 5.2 Voice State
Each voice maintains:
- `sample_id`
- `pos` (fractional position in the sample)
- `rate` (pitch)
- `volume` (0..255)
- `pan` (0..255, left→right)
- `loop_mode` (off / on)
- `loop_start`, `loop_end`
- `priority` (optional)
---
### 5.3 Voice Conflict
If all voices are occupied:
- an explicit policy is applied:
- `STEAL_OLDEST`
- `STEAL_QUIETEST`
- `STEAL_LOWEST_PRIORITY`
PROMETEU does not resolve this automatically without a defined rule.
---
## 6. Conceptual Model: “Audio CPU”
The PROMETEU AUDIO is conceived as an **independent peripheral**, just as classic consoles had:
- Main game CPU
- Dedicated sound CPU
In PROMETEU:
- The **logical core** assumes this conceptual separation
- The **host decides** how to implement it:
- same thread
- separate thread
- separate core
### 6.1 Hardware Metaphor
Conceptually:
```
[Game CPU] → sends 60Hz commands → [AUDIO Peripheral]
|
v
Voices + Mixer
|
v
PCM Output
```
### 6.2 Implementation is the Host's Role
The core:
- defines the **model**
- defines the **commands**
- defines the **limits**
The host:
- chooses:
- threads
- CPU affinity
- audio backend
- guarantees continuous delivery of buffers
Thus:
> PROMETEU models the hardware.
> The host decides how to physically realize it.
---
## 7. Samples
### 7.1 Format
PROMETEU samples:
- **PCM16 mono**
- own sample_rate (e.g., 22050, 44100, 48000)
- immutable data at runtime
Fields:
- `sample_rate`
- `frames_len`
- `loop_start`, `loop_end` (optional)
---
### 7.2 Usage
Example:
```
audio.play(sample_id, voice_id, volume, pan, pitch, priority)
```
Or:
```
audio.playAuto(sample_id, volume, pan, pitch, priority)
```
(uses stealing policy)
---
## 8. Pitch and Interpolation
- `rate = 1.0` → normal speed
- `rate > 1.0` → higher pitch
- `rate < 1.0` → lower pitch
As position becomes fractional:
- **linear interpolation** is used between two neighboring samples
---
## 9. Mixer
For each output frame (48kHz):
1. For each active voice:
- read sample at current position
- apply pitch
- apply volume
- apply pan → generates L/R
2. Sum all voices
3. Apply clamp
4. Write to the stereo buffer
Cost depends on:
- number of active voices
- use of interpolation
---
## 10. Synchronization with the Game
- Game runs at **60Hz**
- Audio generates data at **48kHz**
Every frame (60Hz):
- game sends commands:
- play
- stop
- set_volume
- set_pan
- set_pitch
The audio applies these commands and continues playing.
---
## 11. Basic Commands
Conceptual examples:
```
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. Audio and CAP
Audio participates in the Execution CAP:
- mixing cost per frame
- cost per active voice
- command cost
Example:
```
Frame 1024:
voices_active: 9
mix_cycles: 410
audio_commands: 6
```
---
## 13. Best Practices
Recommended:
- reuse samples
- limit simultaneous voices
- treat sound as an event
- separate music and effects
Avoid:
- playing sound every frame
- abusing voices
- giant samples for simple effects
---
## 14. Historical Inspiration
The PROMETEU model is inspired by:
- NES: fixed channels
- SNES: sample playback + mixing
- CPS2: comfortable polyphony
- Neo Geo: heavy samples (not fully copied)
But abstracted for:
- clarity
- simplicity
- teaching
---
## 15. Summary
- Output: stereo PCM16 @ 48kHz
- 16 voices
- mono PCM16 samples
- Volume, pan, pitch
- Linear interpolation
- Explicit mixer
- "Audio CPU" concept
- Implementation is the host's role
< [Back](chapter-4.md) | [Summary](table-of-contents.md) | [Next](chapter-6.md) >