Start

Theory

Reference

Examples

Audio

Audio plays sound clips on the machine's output device, several at once, driven by components on entities.

The concept

A game needs many sounds playing concurrently, each with its own volume and looping, without allocating while the game runs. Engines open one output device, keep a bounded pool of streams bound to it, and feed decoded clip data into those streams.

Decoded sound

Audio on a computer is a long run of numbers, samples, played at a fixed rate (for example 44,100 per second). A clip is decoded once into that raw form; playing it means copying samples to the device just ahead of the speaker. If the copying is late the sound crackles, which is why audio must never wait on slow work such as loading a file.

Mixing

Speakers receive one signal, so several sounds are mixed by adding their samples together, each scaled by its own volume (gain). Too many loud sounds at once can exceed the maximum and distort, so engines cap the number of simultaneous voices; a bounded pool also keeps memory use predictable.

Sound as game state

Treating a sound as something an entity has (play, stop, loop) rather than a one-off call means it can be saved in a scene, edited in a tool and driven by the same systems as everything else. The system, not gameplay code, owns the details of starting and stopping streams.

How ASGE does it

AudioDevice and AudioStream

asge::audio::AudioDevice owns SDL's audio subsystem, one physical playback device and a fixed pool of 32 AudioStreams. Initialize() opens the default device; CreateStream(AudioClip&) returns a std::shared_ptr<AudioStream> matching the clip's format, and DetachStream() gives the slot back. SetGain() sets the device volume. An AudioStream wraps one SDL_AudioStream: PutData() queues a clip, ClearData() empties it, SetAudioGain() sets its own volume. The shared pointer stays valid even if another detach relocates its slot.

Application initializes the device alongside the video system and passes it into your game.

AudioSource and AudioSystem

Gameplay does not touch streams. An entity gets an AudioSource component (clip path, volume, loop), and you use PlayAudioSource, StopAudioSource and DetachAudioSource to change its state. AudioSystem, the last system in Game::Update's fixed order (see Game loop & timing), starts newly playing sources, restarts looping ones whose queued audio ran out, stops finished non-looping ones, and clears the data of stopped ones. A source keeps the same stream for its whole lifetime, so replaying it never creates a new one. Clips are loaded through the asset manager as media::AudioClip.

audio.cpp
using namespace asge::game::components;

auto source = registry.GetComponent<AudioSource>( entity );   // Result<reference_wrapper<AudioSource>>
if ( source )
{
    PlayAudioSource( source.Value().get(), /* inLoop */ true );   // AudioSystem picks it up this frame
    // StopAudioSource( ... ) stops it; DetachAudioSource( device, ... ) frees its pool slot
}

See also

Source: Audio/AudioDevice.hpp, Game/Components/AudioSource.hpp, Game/Systems/AudioSystem.hpp. Audio demo