Fork me on GitHub


SoLoud needs a back-end to play audio out. SoLoud ships with a bunch of back-ends with various levels of stability and latency. Creating new back-ends is relatively simple.

SoLoud speaks with the back-end with only a couple of functions, in addition to the optional mutex function pointers.

Studying the existing back-end implementations' source code, in addition to this page, will help creating new ones.


The back-end should call Soloud.postinit_internal() once it knows what it can do.

void postinit_internal(int aSamplerate, // Sample rate, in Hz
                       int aBufferSize, // Buffer size, in samples
                       int aFlags);     // Flags

The channels and flags most likely come directly from the application, while sample rate and buffer size may depend on how the back-end does things. The buffer size should be the maximum number of samples the back-end requests on one call. Making it bigger doesn't affect latency, but causes SoLoud to create larger than necessary internal mixing buffers.


The back-end can call the mix function to request a number of stereo samples from SoLoud. The samples will be in float format, and the back-end is responsible for converting them to the desired output format.

void mix(float *aBuffer, // Destination buffer
         int aSamples);  // Number of requested stereo samples

If the number of samples exceeds the buffer size set at init, the result is undefined (most likely a crash).


Since so many back-ends prefer 16 bit signed data instead of float data, SoLoud also provides a mix call that outputs signed 16 bit data.

void mixSigned16(short *aBuffer, // Destination buffer
                 int aSamples);  // Number of requested stereo samples


This void pointer is free for the back-end to use in any way it wants. It may be a convenient place to store any buffers and other information it needs to keep around.

Soloud.mLockMutexFunc, Soloud.mUnlockMutexFunc

These function pointers point to functions which should lock and unlock a mutex. If they are left as NULL, they will not be called.

If they're not implemented, SoLoud will not be thread safe. This means that some shared resources, such as the channel data, may be accessed by several threads at the same time. In the worst case one thread may delete an object while another is accessing it.


Pointer to mutex data. The pointer is also passed to the lock/unlock mutex functions as a parameter.


This function pointer is used by SoLoud to signal the back-end to perform cleanup; stop any threads, free any resources, etc. If NULL, not called, but may result in resource leaks and quite possibly crashes.


Descriptive, short asciiz string about the back-end. Applications may use this to print out different audio devices for user to pick from.

Different back-ends

This is a non-exhaustive list of back-ends and notes regarding them.

Backend x64 Notes
SDL/SDL2 DLL Yes Most tested, primary development platform. Cross-platform. Low latency.
SDL Static ? Mostly meant for emscripten use.
SDL2 Static Yes Can be used to statically link to SDL2.
PortAudio ? Cross-platform. Very low latency. Dynamic linking.
MiniAudio Yes Cross-platform, very low latency. Included with SoLoud.
WinMM Yes Simplest back-end for Windows-only programs.
ALSA Yes Default audio interface for Linux
JACK ? Alternative audio interface for Linux
oss (/dev/dsp) Yes Simplest back-end for Linux-only programs. Experimental.
OpenAL ? Very experimental. Very high latency; if this is your only option, you're probably better off using OpenAL directly.
WASAPI Yes Experimental
XAudio2 Yes Experimental
Nosound Yes Plays audio, throws it away.
Null driver Yes Can be used to use SoLoud without audio device.

Some of the backends have not been tested in x64 builds, but as long as everything is x64, there's no real reason why they don't work.

Copyright©2013-2020 Jari Komppa