Competent Audio Code
Machine graph audio engine for computer games
Status: Beta
Brought to you by:
oddwarg
Competent Audio (CA) is an audio engine suitable for video games. It is written in C, but the API is designed to allow it to be used from other languages, even if they have poor C interoperability. Windows and Linux binaries for x86 and amd64 are available, and should work without installing any dependencies on any reasonably modern system. CA uses a machine graph model with support for arbitrary numbers of machines, limited only by the available system resources: - Samplers play back audio clips. - Mixers combine audio signals and optionally perform signal processing. - Sinks send audio signals to an output device. Stereo and mono sound output is supported, but sound clips can have arbitrary channel counts, enabling certain types of dynamic music using a mixing matrix. Other types of dynamic music can be achieved by queueing audio clips on samplers for gapless playback. Queueing is also useful for streaming. CA contains a very simple embedded VM for running custom signal processors. This is a novel approach that allows you to add custom signal processing code to your project without compiling native code for your target platforms. (Only an assembly language can be used as of writing, so in practice this is difficult.) Any available system errors and many usage errors are reported using negative return codes. The error codes and their conditions are carefully documented in the API header. When used correctly, it attempts to handle expected errors such as missing, faulty or disconnected audio devices gracefully so that you don't have to. Sample code using the C API: //Using a thread safe dispatcher allows you to use CA from multiple threads. //A thread-unsafe dispatcher is available you don't need this and want to save a tiny bit of latency. CADispatcher* dispatcher; caNewThreadSafeDispatcher(&dispatcher); //CA must be initialized exactly once before any further calls can be made. caInitialize(dispatcher); //Use a stereo sound model to play stereo samples correctly and control left and right gain separately. //A mono sound model is available if you don't need this and want to reduce CPU load. CASoundModel* soundModel; caNewStereoSoundModel(&soundModel); //A sink must be created and opened to connect to an output device. There is normally just one sink. //Note the buffer size and sample rate are advisory; the library may select other values if necessary. CAMachine* sink = NULL; caNewSink(&sink, soundModel, 800); caOpenSink(sink, CA_DEVICE_INDEX_AUTO, 44100); //A sampler must be created and connected to the sink in order to play back audio. //Samplers are cheap, so you can have many (thousands, as long as they don't all play at the same time). CAMachine* testSampler; caNewSampler(&testSampler, sink); //An audio clip must be loaded into the sampler to allow it to play audio. //Multiple clips can be queued on a sampler to enable streaming or gapless playback. //Note that the C API does not have any audio file loaders, but this is easy to add yourself. float sampleData[44100]; for(int i = 0; i<44100; i++) sampleData[i] = sin(440 * 3.1415 * 2.0 * i / 44100.0); caEnqueueClip(testSampler, false, NULL, NULL, 1, 44100, CA_FLOAT32, caIsLittleEndian(), 44100, sampleData); //The sampler can now be used. caPlay(testSampler); caSleep(4000); //CA must be uninitialized exactly once after all other calls. caUninitialize(); Error checks in the above code have been omitted for clarity. Although it is not exactly a design goal, the C API has plenty of extension points, so custom machine types, signal processors, sound models, etc. can be written as add-on libraries. For audio output, CA uses a fork of libsoundio 2.0 (see appendix folder for source/changelog). The modified source code is included in the appendix directory of the CA repository. Competent Audio is released under an MIT license; see "LICENSE.txt". However, be aware that the high level Java API specifically depends on the additional files "jlayer-decoder.jar" and "jorbis.jar", which are covered by the separate licenses "JLAYER-LICENSE.txt" and "JORBIS-LICENSE.txt", respectively.