This page is the model every other audio page assumes. It describes how sound is put together in GS_Play — what processes audio, what merely computes numbers, the order stages run in, and the words used for each part.
Read it before the feature pages. Several parts of the audio API look arbitrary until you know the model, and one of them (spatialization) is deliberately not where most engines put it.
For usage guides and setup examples, see The Basics: GS_Audio.
Contents
- Two Planes
- What Each Library Does
- The Canonical Chain
- Vocabulary
- Spatialization
- Frame Size — the Audio Timestep
- See Also
Two Planes
Audio is two planes that meet at nodes.
| Plane | Runs on | Carries | Owned by |
|---|---|---|---|
| Audio plane | the audio thread | actual sound | miniaudio, always |
| Control plane | the game thread, per frame | numbers | the framework and your game code |
The audio plane is the ground floor and the only floor that reaches the speakers. Everything audible is a node in one miniaudio graph. Fan-in sums automatically; you route by attaching one node’s output to another’s input.
The control plane never carries audio. It writes numbers that the audio plane reads — the listener transform, a source’s position, an occlusion factor, reverb decay times, a binaural direction.
Control plane writes; audio plane reads. That decoupling is what keeps the system tractable, and it is the one sentence to leave this page with.
What Each Library Does
Three libraries are involved, and they are not peers. Confusing their roles is the most common way to misread the system.
| Library | On the audio plane | On the control plane | Tier |
|---|---|---|---|
| miniaudio | The substrate, mixer and output device. Everything is one of its nodes. | Built-in listener, per-sound position and panner. | Base |
| Steam Audio | DSP nodes — binaural, direct, reflection — that pass audio through like any other effect. Not the ground floor, and not a source. | An entire scoped simulation, analogous to a physics world. You register geometry, sources and a listener; it computes acoustic parameters; those parameters drive the DSP nodes. | Base (binaural + distance) / Pro (geometry) |
| SoLoud | The lineage of the DSP layer. The base gem’s effect and source node implementations derive from SoLoud’s, and its generators and synthesis feed the effect nodes. In Pro it also acts as a source, rendering speech to PCM and relaying it in through a custom node. | Emission position pushed to the voice node each frame. | Base (DSP layer) / Pro (voice synthesis) |
The rule: anything that makes sound becomes, or feeds, a miniaudio node. SoLoud and Steam Audio both relay into miniaudio; neither bypasses it.
SoLoud ships in the base gem. The framework’s own effect and source nodes were extracted into a header-only layer so they can be wired directly into the miniaudio graph, but they remain derivative of SoLoud and are sourced from it — the attribution belongs to the free tier, not only to Pro. Pro then uses SoLoud further as the synthesis engine behind Klatt voice.
Steam Audio is worth stating twice, because it is the one people misplace. Its simulation is a parallel world you connect into. It produces numbers. Nodes consume those numbers. miniaudio moves the audio.
The Canonical Chain
Every sound travels the same path from emission to speakers:
Emission Source + local tone shaping (EQ, filters, per-emitter mix nodes)
|
v
Environment Manual Reverb XOR Steam reflections/occlusion <-- SAME layer
|
v
Binaural / HRTF the "ears" stage — ALWAYS LAST before volume, if spatial
|
v
Volume Channel grouped, options-driven gain
|
v
Master -> speakers
Two rules hold everywhere:
Manual reverb and Steam reflections are the same conceptual layer — the environment. Manual reverb fakes the room. Steam reflections are the room, derived from real geometry. Use one or the other. Stacking them double-reverbs the sound.
Binaural/HRTF is always the last stage before the volume channel. It is the ears. Nothing spatial happens after it.
Worked cases:
| Case | Chain |
|---|---|
| Non-spatial (2D) sound | Emission -> Reverb -> Volume Channel — no binaural stage |
| Full geometric acoustics (Pro) | Emission -> Steam {distance + occlusion + reflections + binaural} -> Volume Channel — manual reverb is dropped |
| Mixed | Emission -> Reverb -> Binaural -> Volume Channel — a faked room, a real direction |
Vocabulary
The audio docs use these four words precisely. Source → Spatialization → Volume Channel → Master.
| Term | Meaning |
|---|---|
| Source | An emission — a position plus its effects channel — or a selected destination. “2D” means pure stereo, with no spatial consideration at all. |
| Spatialization | Everything that happens to a sound as it travels from its emission point to the listener: direction, distance, occlusion, environment. It is a property of the source, not a mix effect. |
| Volume Channel | Final amplification of grouped sound types — voice, environment, combat SFX — into Master. Driven by the options system. |
| Master | The single output everything sums into before the device. |
Spatialization and volume channels are orthogonal. A voice line, a footstep and a magic blast all get position-based spatialization, and all three route to different volume channels. One is about where the sound is; the other is about what kind of sound it is.
Spatialization
Most audio middleware lets you drop a spatializer into an effects chain. GS does not. Spatialization is a property of the source, and the framework applies it for you.
Where it happens. Each 3D sound instance gets its own spatializer node, placed between the source and its volume channel — the Binaural stage in the chain above. It is always the last thing before volume.
One spatializer, never two. A 3D source is spatialized by either miniaudio’s built-in spatializer or Steam Audio’s binaural path, decided by the project’s spatialization mode on the Audio Manager. The two are alternatives. They are never stacked, because a fixed HRTF layered over a positional pan cancels the spatial presence the pan was already producing.
It is applied procedurally. You do not author it per sound. The framework inserts the node, recomputes direction each frame from the source-to-listener vector on the control plane, and handles distance attenuation alongside it. Every 3D source therefore behaves the same way, whether it came from an event, a graph or a voice — consistent and reliable, with nothing to wire up and nothing to get wrong.
Channel discipline is why the position is fixed. Binaural is mono- or stereo-in and always stereo-out, so it has to sit at a defined point in the chain rather than anywhere a designer drops it.
MixEffect_Binaural is not how you spatialize a 3D sound
The binaural mix effect still exists, but it is a niche tool for placing a 2D sound at a fixed direction. Real spatialization of a 3D sound is automatic and per-source. Reaching for the mix effect instead will give you a sound stuck in your head with no falloff.Frame Size — the Audio Timestep
Steam Audio effects want exactly one block of samples per call. A mismatch is audible as crunching.
The framework therefore treats frame size as a fixed audio timestep. By default it queries the miniaudio device period and matches it, rather than adapting with a ring buffer. This is exposed on the Audio Manager as Auto (recommended) versus Fixed.
Think of it the way you think of a physics timestep: a rate the whole simulation agrees on, not a per-effect setting.
See Also
For the systems this model describes:
- Audio Manager — the listener, project settings, and the engine
- Mixing & Effects — the Emission and Volume Channel stages
- GS_Options — what drives volume channel levels
For conceptual overviews and usage guides:
Get GS_Audio
GS_Audio — Explore this gem on the product page and add it to your project.