Skip to main content

forge-audio-pool

Add fire-and-forget audio playback with a source pool and volume fading for click-free start/stop transitions.

Zur Installation springen

Quellinformationen

Repository
Nebulavenus/forge-gpu
Letzte Quellaktivität
16. März 2026 um 02:28
Erkannte Sprache von SKILL.md
Englisch
Sterne
38
Forks
7

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
forge-audio-pool
description
Add fire-and-forget audio playback with a source pool and volume fading for click-free start/stop transitions.
trigger
Use when someone needs polyphonic sound effects, fire-and-forget audio, one-shot playback, or fade-in/fade-out on audio sources.
# forge-audio-pool Add fire-and-forget sound effect playback using `ForgeAudioPool` and smooth volume transitions using the fade envelope on `ForgeAudioSource`. Based on [Audio Lesson 02](../../../lessons/audio/02-sound-effects/). ## When to use - Playing the same sound multiple times with overlap (polyphony) - One-shot sound effects that should auto-clean-up when finished - Starting or stopping sounds without audible clicks (fade-in / fade-out) - Ambient loops that toggle smoothly with a volume ramp ## Source pool pattern ```c #include "audio/forge_audio.h" /* In app_state */ ForgeAudioPool pool; ForgeAudioBuffer sfx_buffer; /* In SDL_AppInit */ forge_audio_pool_init(&pool); forge_audio_load_wav("assets/audio/impact.wav", &sfx_buffer); /* Fire-and-forget: each call allocates a new slot (up to 32) */ int slot = forge_audio_pool_play(&pool, &sfx_buffer, 1.0f, false); if (slot < 0) { SDL_Log("Pool full — sound dropped"); } /* In SDL_AppIterate — mix all active sources, reclaim finished slots */ SDL_memset(scratch, 0, samples * sizeof(float)); forge_audio_pool_mix(&pool, scratch, frames_needed); /* Stop everything */ forge_audio_pool_stop_all(&pool); ``` The pool scans for the first slot with `playing == false`. Non-looping sources auto-stop at buffer end; the slot is then reusable by the next `pool_play()`. ## Fade envelope pattern ```c /* Fade fields on ForgeAudioSource (initialized by forge_audio_source_create): * fade_volume = 1.0 (current multiplier) * fade_target = 1.0 (destination) * fade_rate = 0.0 (change per second, 0 = no fade) */ /* Start a fade to any target */ forge_audio_source_fade(src, 0.5f, 2.0f); /* fade to 50% over 2 seconds */ /* Convenience: fade in from silence (sets fade_volume=0, starts playback) */ forge_audio_source_fade_in(src, 0.5f); /* Convenience: fade out to zero (auto-stops when complete) */ forge_audio_source_fade_out(src, 1.0f); /* MUST call once per frame to advance the ramp */ forge_audio_source_fade_update(src, dt); ``` The fade multiplier is applied on top of `volume * pan` during `forge_audio_source_mix()`. Default `fade_volume=1.0` means existing code from Lesson 01 behaves identically. ## Combining pool + fade For pool sources that need fade control, get the source pointer after play: ```c int slot = forge_audio_pool_play(&pool, &buffer, 1.0f, true); if (slot >= 0) { ForgeAudioSource *src = forge_audio_pool_get(&pool, slot); forge_audio_source_fade_in(src, 0.3f); } /* Update fades on all pool sources each frame */ for (int i = 0; i < FORGE_AUDIO_POOL_MAX_SOURCES; i++) { if (pool.sources[i].playing) { forge_audio_source_fade_update(&pool.sources[i], dt); } } ``` ## Ambient loop with fade toggle For a single looping source managed outside the pool (direct fade control): ```c /* In app_state */ ForgeAudioSource ambient; bool ambient_active; /* Toggle on key press */ if (ambient_active) { forge_audio_source_fade_out(&ambient, fade_duration); ambient_active = false; } else { if (!ambient.playing) forge_audio_source_reset(&ambient); forge_audio_source_fade_in(&ambient, fade_duration); ambient_active = true; } ``` ## Common mistakes - **Forgetting `fade_update`** — The fade does not advance automatically. Call `forge_audio_source_fade_update(src, dt)` once per frame for every source that might be fading. - **Calling fade_update per mix call** — Call it per frame, not per mix invocation. The rate is in units per second, scaled by `dt`. - **Not zeroing the mix buffer** — `forge_audio_pool_mix()` is additive. Always `memset(out, 0, ...)` before the first mix call each frame. - **Ignoring pool_play return value** — Returns -1 when full. Decide whether to drop the sound or steal an existing slot. ## API reference | Function | Purpose | |---|---| | `forge_audio_pool_init` | Zero all 32 slots | | `forge_audio_pool_play` | Play buffer in first idle slot → index or -1 | | `forge_audio_pool_get` | Get source pointer at index → `ForgeAudioSource*` or NULL | | `forge_audio_pool_mix` | Mix active sources, reclaim finished | | `forge_audio_pool_stop_all` | Stop everything | | `forge_audio_pool_active_count` | Count of playing sources | | `forge_audio_source_fade` | Start fade toward target over duration | | `forge_audio_source_fade_in` | 0→1 fade, starts playback | | `forge_audio_source_fade_out` | Current→0 fade, auto-stops | | `forge_audio_source_fade_update` | Advance fade by dt seconds |
Auf GitHub ansehen