Sound
Audio playback for sound effects and music, with mix buses, ducking and positional sound.
Header: #include <asw/modules/sound.h>
Namespace: asw::sound

From the sound example.
The sound module has 32 voices for sound effects and one track for music. asw::core::init() initializes the module, and asw::core::update() updates fades, ducking and positional sounds each frame.
Mixer
get_mixer
MIX_Mixer* get_mixer();Get the SDL_mixer device. Returns nullptr if the sound module is not initialized.
Types
Bus Enum
enum class Bus : uint8_t {
Sfx,
Music,
Ambient,
Ui,
Voice,
Count,
};Mix buses. Each sound plays on one bus. Each bus has its own volume and can be ducked. Count is the number of buses. Do not play sounds on it.
Rolloff Enum
enum class Rolloff : uint8_t {
Linear,
Inverse,
InverseSquare,
};How volume decreases with distance for positional sounds.
| Value | Description |
|---|---|
Linear | Straight line from full volume at min_distance to silent at max_distance |
Inverse | Sounds natural. Loud when near, with a long quiet tail |
InverseSquare | Like Inverse, but decreases faster |
SpatialMode Enum
enum class SpatialMode : uint8_t {
Stereo,
Surround,
};How positional sounds are put on the speakers.
| Value | Description |
|---|---|
Stereo | Left/right panning. Best for headphones and side-on games. This is the default |
Surround | SDL_mixer 3D positioning, which also uses rear and side speakers. The world is top-down: up the screen is in front, down the screen is behind |
Attenuation
struct Attenuation;Distance settings for positional sounds, in world units (pixels).
| Field | Type | Default | Description |
|---|---|---|---|
min_distance | float | 100.0 | Full volume at this distance or nearer |
max_distance | float | 1000.0 | Silent at this distance or farther |
rolloff | Rolloff | Inverse | Shape of the decrease between the two distances |
PlayOptions
struct PlayOptions;Options for playing a sound.
| Field | Type | Default | Description |
|---|---|---|---|
volume | float | 1.0 | Playback volume (0.0 - 1.0) |
pan | float | 0.0 | Panning (-1.0 left - 1.0 right). Positional sounds ignore it |
loop | bool | false | Loop forever |
pitch | float | 1.0 | Playback speed and pitch. 2.0 is one octave up |
pitch_variation | float | 0.0 | Random pitch change for each play, as a fraction. 0.05 picks a value from 0.95x to 1.05x. Use it to make repeated sounds (footsteps, hits) less robotic |
volume_variation | float | 0.0 | Random volume change for each play, as a fraction |
bus | Bus | Sfx | The bus to play on |
priority | int | 0 | When all voices are busy, a new sound replaces the quietest voice that has the same or lower priority. If there is no such voice, the new sound is not played |
fade_in_s | float | 0.0 | Fade-in time in seconds |
attenuation | Attenuation | {} | Distance settings for positional sounds |
SoundHandle
class SoundHandle;A handle to a playing sound. Use it to change the sound while it plays. Handles are cheap to copy. When the sound ends, or its voice is given to a different sound, the handle becomes stale. All calls on a stale handle do nothing. A default-constructed handle refers to no sound.
| Method | Description |
|---|---|
bool is_playing() const | true while the sound has not ended (playing or paused) |
void stop(float fade_out_s = 0.0F) const | Stop the sound, with an optional fade-out in seconds |
void pause() const | Pause the sound |
void resume() const | Resume a paused sound |
void set_volume(float volume) const | Set the volume (0.0 - 1.0), before bus and distance |
void set_pitch(float pitch) const | Set the playback speed and pitch. 1.0 is normal |
void set_pan(float pan) const | Set the panning (-1.0 - 1.0). A positional sound becomes non-positional |
void set_position(const Vec2<float>& position) const | Set the world position. The sound becomes positional |
void set_velocity(const Vec2<float>& velocity) const | Set the velocity in world units per second, for doppler pitch shift |
void set_occlusion(float amount) const | Muffle the sound, as if heard through a wall. 0.0 is clear, 1.0 is fully muffled |
void set_attenuation(const Attenuation& attenuation) const | Change the distance settings |
Sound Effects
play
SoundHandle play(const asw::Sample& sample,
float volume = 1.0F,
float pan = 0.0F,
bool loop = false);
SoundHandle play(const asw::Sample& sample, const PlayOptions& options);Play a sound effect sample on the Sfx bus, or with the given options. Returns a handle to the sound. The handle is stale if the sound could not be played.
| Parameter | Type | Default | Description |
|---|---|---|---|
sample | const asw::Sample& | The sample to play | |
volume | float | 1.0 | Playback volume (0.0 - 1.0) |
pan | float | 0.0 | Panning: -1.0 (full left), 0.0 (center), 1.0 (full right) |
loop | bool | false | Infinite loop when true |
options | const PlayOptions& | How to play the sample. See PlayOptions |
play_positional
SoundHandle play_positional(const asw::Sample& sample,
const Vec2<float>& position,
const PlayOptions& options = {});Play a sample at a point in the world. The sound is panned, faded and pitch-shifted relative to the listener, and continues to update while it plays. A one-shot sound that is out of hearing range (farther than options.attenuation.max_distance) is not played, and the handle is stale.
play_at
SoundHandle play_at(const asw::Sample& sample, float x, float volume = 1.0F);
SoundHandle play_at(const asw::Sample& sample, float x, const PlayOptions& options);Play a sample panned by its horizontal position on the screen. x is in logical screen coordinates. Sounds pan to the side they are on. They fade out when they are off screen and are silent one full screen width past the edge. Use this for simple games that do not have a listener.
The PlayOptions version also takes pitch, variation, bus, priority and the rest. options.volume is the volume before the fade, and options.pan is replaced by the screen position. The pan is set once when the sound starts.
asw::sound::PlayOptions shot;
shot.pitch_variation = 0.08F;
shot.priority = 2;
asw::sound::play_at(gunshot, enemy.position.x, shot);Listener and Spatial Settings
set_listener
void set_listener(const Vec2<float>& position,
const Vec2<float>& velocity = { 0.0F, 0.0F });Set the listener position in the world, usually the player or the center of the camera. velocity is in world units per second and is used for doppler.
get_listener
Vec2<float> get_listener();Get the listener position.
set_spatial_mode
void set_spatial_mode(SpatialMode mode);Set how positional sounds are put on the speakers. The default is SpatialMode::Stereo.
set_doppler
void set_doppler(float factor, float speed_of_sound = 3000.0F);Set the strength of the doppler pitch shift. A factor of 0 turns doppler off, and 1 is realistic (default). speed_of_sound is in world units per second. A lower value makes the effect stronger.
Buses and Ducking
set_bus_volume
void set_bus_volume(Bus bus, float volume);Set the volume multiplier of a bus. Range: 0.0 - 1.0.
get_bus_volume
float get_bus_volume(Bus bus);Get the volume multiplier of a bus.
duck
void duck(Bus bus, float gain, float hold_s, float fade_s = 0.2F);Decrease the volume of a bus for some time. For example, lower the music during dialogue, or lower all other sounds during a big explosion. If ducks overlap, the lowest level and the longest hold are used.
| Parameter | Type | Default | Description |
|---|---|---|---|
bus | Bus | The bus to duck | |
gain | float | The level while ducked (0.0 - 1.0) | |
hold_s | float | Seconds to stay ducked | |
fade_s | float | 0.2 | Seconds to fade down and back up |
Music
Music plays on the Music bus and always loops.
play_music
void play_music(const asw::Music& sample, float volume = 1.0F, float fade_in_s = 0.0F);Play a music track.
| Parameter | Type | Default | Description |
|---|---|---|---|
sample | const asw::Music& | The music to play | |
volume | float | 1.0 | Playback volume (0.0 - 1.0) |
fade_in_s | float | 0.0 | Fade-in duration in seconds |
stop_music
void stop_music(float fade_out_s = 0.0F);Stop the currently playing music. Set fade_out_s to fade out over that number of seconds.
pause_music
void pause_music();Pause the currently playing music.
resume_music
void resume_music();Resume paused music.
is_music_playing
bool is_music_playing();Returns true if music is currently playing.
is_music_paused
bool is_music_paused();Returns true if music is currently paused.
Volume Control
set_master_volume
void set_master_volume(float volume);Set the master volume multiplier (affects all audio). Range: 0.0 - 1.0.
set_sfx_volume
void set_sfx_volume(float volume);Set the SFX volume multiplier. This is the same as set_bus_volume(Bus::Sfx, volume). Range: 0.0 - 1.0.
set_music_volume
void set_music_volume(float volume);Set the music volume multiplier. This is the same as set_bus_volume(Bus::Music, volume). Range: 0.0 - 1.0.
get_master_volume
float get_master_volume();Get the current master volume.
get_sfx_volume
float get_sfx_volume();Get the current SFX volume.
get_music_volume
float get_music_volume();Get the current music volume.
Example
auto sfx = asw::assets::load_sample("explosion.wav");
auto step = asw::assets::load_sample("step.wav");
auto engine = asw::assets::load_sample("engine.wav");
auto bgm = asw::assets::load_music("theme.ogg");
// Play sound effect
asw::sound::play(sfx, 0.8f);
// Play with options: random pitch and volume for each footstep
asw::sound::PlayOptions options;
options.pitch_variation = 0.05f;
options.volume_variation = 0.1f;
asw::sound::play(step, options);
// Positional sound that follows an object
asw::sound::PlayOptions loop_options;
loop_options.loop = true;
auto handle = asw::sound::play_positional(engine, car_position, loop_options);
// Each update
asw::sound::set_listener(player_position, player_velocity);
handle.set_position(car_position);
handle.set_velocity(car_velocity);
// Stop it with a fade out
handle.stop(0.5f);
// Play music with fade in (2 seconds)
asw::sound::play_music(bgm, 0.5f, 2.0f);
// Lower the music for 1 second under the explosion
asw::sound::duck(asw::sound::Bus::Music, 0.3f, 1.0f);
// Fade out music (1 second)
asw::sound::stop_music(1.0f);
// Volume controls
asw::sound::set_master_volume(0.7f);
asw::sound::set_bus_volume(asw::sound::Bus::Ambient, 0.5f);
asw::sound::set_music_volume(0.5f);