Plugin audio
A plugin produces sound by queueing 16-bit samples with audio_queue. The system mixes them into the console's audio output.
Contents
How it works
| Property | Value |
|---|---|
| Format | Signed 16-bit, one mono stream |
| Sample rate | 22050 Hz on both platforms; there is no resampling, so generate 22050 Hz |
| Capacity | 16 383 frames (about 743 ms) |
| Units | audio_queue and audio_get_free count frames, never int16_t elements |
- Stereo input is mixed down: each
(L, R)frame is stored as(L + R) / 2, and the mono result plays on both speakers. - Overflow:
audio_queuestores only the frames that fit and drops the rest. It never blocks. Checkaudio_get_free()first. - Underflow: when the queue runs empty, the output is silent until new frames arrive.
- Volume: Lua sets the plugin volume with
c8b.sound.setPluginGain(gain)(0.0 to 2.0). The console default is about 0.82; the emulator plays plugin audio at 1.0. - Mixing: plugin audio goes through the music bus together with tracker, MIDI and MP3 music.
- Lifecycle: the queue is emptied at
plugin.init()andplugin.cleanup(), so sound never carries over from one plugin to the next. - Threads: call
audio_queueonly from your plugin's entry points, never from an interrupt.
Keeping the queue filled
Keep a target amount of audio queued (around 300 ms) and top it up once per plugin_update:
enum { RATE = 22050, TARGET = RATE * 300 / 1000 }; /* 6615 frames */
size_t free_frames = api->audio_get_free();
size_t queued = 16383 - free_frames;
if (queued < TARGET) {
size_t n = TARGET - queued;
render_mix(buf, n); /* your mixer */
api->audio_queue(buf, n, /*stereo=*/false);
}
A plugin can also leave music to Lua (for example the MIDI player) and use the plugin audio queue only for its own sound.