Fork me on GitHub

SoLoud::Soloud

In order to use SoLoud, you have to create a SoLoud::Soloud object. The object must be cleaned up or destroyed before your back-end is shut down; the safest way to do this is to call soloud.deinit() manually before terminating.

The object may be global, member variable, or even a local variable, it can be allocated from the heap or the stack, as long as the above demand is met. If the back-end gets destroyed before the back-end clean-up call is made, the result is undefined. As in, bad. Most likely, a crash. Blue screens in Windows are not out of the question.


SoLoud::Soloud *soloud = new SoLoud::Soloud; // object created
soloud->init();             // back-end initialization
...
soloud->deinit();           // clean-up
delete soloud;              // this cleans up too

Seriously: remember to call the cleanup function. The SoLoud object destructor also calls the cleanup function, but if you perform your application's tear-down in an unpredictable order (such as having the SoLoud object be a global variable), the back-end may end up trying to use resources that are no longer available. So, it's best to call the cleanup function manually.

Basics

Soloud.init()

Initializes the SoLoud object. The function has several optional parameters you can use to adjust SoLoud's behavior. The default values should work for most cases.


result init(unsigned int aFlags = Soloud::CLIP_ROUNDOFF, 
            unsigned int aBackend = Soloud::AUTO, 
            unsigned int aSamplerate = Soloud::AUTO, 
            unsigned int aBufferSize = Soloud::AUTO);

By default SoLoud is initializes with the roundoff clipping enabled, and the rest of the parameters set to auto. SoLoud will then pick the backend it prefers, and its default parameters.

Currently, you can select from these flags:

Flag Description
CLIP_ROUNDOFF Use roundoff clipper. Without this flag the clipper defaults to "hard" clipping to -1/+1
ENABLE_VISUALIZATION Enable gathering of visualization data. Can be changed at runtime with setVisualizationEnable()
LEFT_HANDED_3D Use left-handed (Direct3D) 3d coordinates. Default is right-handed (OpenGL) coordinates.
NO_FPU_REGISTER_CHANGE Do not alter the FPU state in audio threads. By default, SoLoud uses "fast" fpu options.

Current set of back-ends is:

Backend Description
AUTO Select backend automatically
SDL1 SDL1 dynamic or static linking
SDL2 SDL2 dynamic or static linking
PORTAUDIO PortAudio
MINIAUDIO MiniAudio
WINMM Windows MultiMedia
XAUDIO2 XAudio2
WASAPI Windows Audio Session API
ALSA Advanced Linux Sound Architecture
JACK JACK Audio Connection Kit
OSS Open Sound System
OPENAL OpenAL (high latency)
COREAUDIO OSX CoreAudio
OPENSLES OpenSL ES
VITA_HOMEBREW Vita console homebrew SDK
NOSOUND No-sound driver
NULLDRIVER Null driver

Soloud.deinit()

Shut down the SoLoud object.


void deinit();

Should be called before shutting down. While the shutdown probably will work out fine without calling this function, it is recommended that applications call the deinit function explicitly.

If the cleanup is left for the executable teardown, it is possible that the backend gets shut down first, and then SoLoud's audio thread may try to call it afterwards, leading to undefined behavior.

Soloud.play()

The play function can be used to start playing a sound source. The function has more than one parameter, with typical default values set to most of them.


int play(AudioSource &aSound, 
         float aVolume = 1.0f, // Full volume 
         float aPan = 0.0f,    // Centered
         int aPaused = 0,      // Not paused
         int aBus = 0);        // Primary bus

Unless you know what you're doing, leave the aBus parameter to zero.

The play function returns a channel handle which can be used to adjust the parameters of the sound while it's playing. The most common parameters can be set with the play function parameters, but for more complex processing you may want to start the sound paused, adjust the parameters, and then un-pause it.


int h = soloud.play(sound, 1, 0, 1);  // start paused
soloud.setRelativePlaySpeed(h, 0.8f); // change a parameter
soloud.setPause(h, 0);                // unpause

Soloud.playClocked()

This is a variant of the play function that takes additional parameter, the time offset for the sound. While the vanilla play() tries to play sounds as soon as possible, the playClocked will delay the start of sounds so that rapidly launched sounds don't all get clumped to the start of the next outgoing sound buffer.

Let's say we have a short sample and we want to play it repeatedly.

Single blip

If our play calls are rapid enough, several calls will hit the same audio buffer, and the effect simply amplifies the sound:

blips via play()

If we use playClocked instead, SoLoud will notice that several calls are being made within one audio buffer, and will delay the later ones based on the time given as a parameter, resulting in what we wanted in the first place:

blips via playClocked

The "pew pew" example gives an interactive and intuitive way of understanding how this function is used, and what problem it solves.


t = time_from_game_engine();        // Game physics time
int h = soloud.playClocked(t, pew); // Shoot!

Apart from the delayed start, the playClocked() works exactly like the play() function, except that there's no way to start them in a paused state.

The time parameter should be your game's "physics time", in seconds. SoLoud will then use that time (as well as the time you previously used) to calculate the delay between two sound effects. If a output sound buffer threshold is passed between the two sounds, SoLoud will adjust the delay accordingly.

Note that if your "physics time" granularity is low, playClocked is not really useful. Audio buffers tend to be 40ms long at most.

Soloud.playBackground()

The playBackground() function can be used to play sounds without panning, primarily meant for background music.


    handle playBackground(AudioSource &aSound,
                          float aVolume = -1.0f, 
                          bool aPaused = 0, 
                          unsigned int aBus = 0);

It's a convenience function, and is equivalent to play() followed by setPanAbsolute() to set left and right channels to full volme.


gSoloud.playBackground(gDramaticScore);

Soloud.seek()

You can seek to a specific time in the sound with the seek function. Note that the seek operation may be rather heavy, and some audio sources will not support seeking backwards at all.


int h = soloud.play(sound, 1, 0, 1); // start paused
soloud.seek(h, 3.8f);                // seek to 3.8 seconds
soloud.setPause(h, 0);               // unpause

Soloud.stop()

The stop function can be used to stop a sound.


soloud.stop(h); // Silence!

Soloud.stopAll()

The stop function can be used to stop all sounds. Note that this will also stop the protected sounds.


soloud.stopAll(); // Total silence!

Soloud.stopAudioSource()

The stop function can be used to stop all sounds that were started through a certain sound source. Will also stop protected sounds.


soloud.stopAudioSource(duck); // silence all the ducks

Soloud.setGlobalVolume(), Soloud.getGlobalVolume()

These functions can be used to get and set the global volume. The volume is applied before clipping. Lowering the global volume is one way to combat clipping artifacts.


float v = soloud.getGlobalVolume(); // get the current global volume
soloud.setGlobalVolume(v * 0.5f);   // halve it

Note that the volume is not limited to 0..1 range. Negative values may result in strange behavior, while huge values will likely cause distortion.

Soloud.setPostClipScaler(), Soloud.getPostClipScaler()

These functions can be used to get and set the post-clip scaler. The scaler is applied after clipping. Sometimes lowering the post-clip result sound volume may be beneficial. For instance, recording video with some video capture software results in distorted sound if the volume is too high.


float v = soloud.getPostClipScaler(); // get the current post-clip scaler
soloud.setPostClipScaler(v * 0.5f);   // halve it

Note that the scale is not limited to 0..1 range. Negative values may result in strange behavior, while huge values will likely cause distortion.

Copyright©2013-2020 Jari Komppa