< [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) >