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.
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.
This is a non-exhaustive list of back-ends and notes regarding them.
|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.|
|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