SoLoud Audio Engine

Jari Komppa November 9, 2013

Contents

1. Introduction Tel, SHOWCASE a, a Sid. aes ay ace a Ae ay Ge a as a a gs ae Bier aa

2 Legal 2.1 SoLoud Proper... 1. 6. ee ee ee es ZZ OGG SUPPOM, 6.4 6 ooh Ge ee ee ae ee ee ee Ge a ge ee 2.3 Speech Synthesizer 2... ee ee es 2.4 Fast Fourier Transform (FFT) .... 1... 2. ee ee ee ee ee ee ee

3 Quick Start

3.1 Download SoLoud ... 2... 2...

3.2 Add filesto your project ... 1... . tt es 3) IMClUd@ PILES? oe. peace. woke ead aw oe: ae: ae we ee: a: Ge ee es we ae ae 4 «4 Nariables® = «. 40:6 & A: koa Sooo Sw HOR es Ger RO HOA RS BO A OS “5. Initialize SoLOUd 3 3. 664 ode OR a a we we .6 Setup sound sources ... 2... 2... ee ee wf Play sounds: © ¢ 64% 4% & 3 ae ee eR Ae ak ee oe OE a .8 Take controlof thesound....... 2.2.0.0. 2 eee ee ee ee oe “CLEANUP: &y sie, S:80 S Sats SAR Barak, Se ab Sie ae Gt a, A ar ae, Ba a ave Se VOVEAJOYS se ake oh og) de see oa Ga, oy ake Ge oa hase He aha we oe He gt eae HG, ate Hw) ease He ah BL ewe

Www ww Ww WwW

4 Premake

5 Concepts a > d =) 0 na Di2< Channel: s+: a. tace 4.44.4 a Poaceae a Race aw ae wee eae D3 SEAM. Be bE EE EEE OE SEE ER REE EEE EEE eS D4) CUPPING &. & 2.47% Gu aie Se Soe. Oye Gare Boe Oe Be Se he Oe Gare Sled De SANTMDUS Sse, ah, ass sr abe be ae be a, pdm: Ge ake Gh ar Ge ake Gm) WE ake Se we Bias, Gade: Beak Ge ar Weak Gace) Bre 5.6: ‘Sample Rate! ao a 2: a ea 4 a aoa ae wa Bae aa wae we A waa aw wa Ga eas E “Play Speeds. 3: fc oe sk es oe ae wk oe: Ge ee ee ee ee ae ee es 8 Relative Play Speed . 2... ee ee 9 IRESAMpliN: 4 ss eo kek eee ed eS ek eT ee SE ee ae ee eR ee 1 1 1

1 Handles: 4% 63.4% Sete eR eke ee ae He a A ee Oe aoe Ee eR HR a 2 Sound Source and Instance... 1... ee Dal GALeMCY se vn ai te aoc, Boe a Bien Ge Boer eee Oe Bere Soe Oe Bee Ss BTA FAC ak ce se as de ade he es sohbet: He ake Ee ws Bites Ge we We Ue ew eae Ge we We ee Ee ee wwe Be ee DD MIXING BUS! ce ae oe: ae ae aoa ae we Bia Bea aOR AO RY RS GORY aR ae oe GORY wa a ee ee A

5. Ds 5. 5. 5D. Ds

6 Frequently Asked Questions 6.2 What dependencies does ithave? ....... 2... . ee ee

6.3 IsthereaDLL/ C-Interface? 2... . ee 6.4 What’s the animal in the logo? ... 2... .. ee

SoLoud Audio Engine - http://soloud-audio.com

7 Examples 7.1 simplest... . 7.2 multimusic .. 7.3 piano ..... 7.4. mixbusses ... PED CONV & aoe be 4

8 Core: Basics

8.1 SoLoud::Soloud Object ... 1... . te es

8.2 Soloud.play() . 8.3 Soloud.seek() . 8.4 Soloud.stop() . 8.5 Soloud.stopAll()

8.6 Soloud.stopSound() .. 1... 2... ee es 8.7 Soloud.setGlobalVolume() / Soloud.getGlobalVolume() ..........-0065 8.8 Soloud.setPostClipScaler() / Soloud.getPostClipScaler().............4.

9 Core: Attributes

9.1 Soloud.getVolume() / Soloud.setVolume(). . 2... 2... ee 9.2 Soloud.getPan() / Soloud.setPan() ...........2. 2.220000 028s 9.3 Soloud.setPanAbsolute(). 2... 2. ee

Soloud.getSamplerate() / Soloud.setSamplerate()........

Soloud.getRelativePlaySpeed() / Soloud.setRelativePlaySpeed()

Soloud.getProtectChannel() / Soloud.setProtectChannel() .. .

9.7 Soloud.getPause() / Soloud.setPause() ... 2... 2... 2 2 ee ee 9.8 Soloud.setPauseAll(). 2... ee 9.9 Soloud.setFilterParameter().. 2... 2... ee 9.10 Soloud.getFilterParameter(). 2... 2. ee

10 Core: Faders 10.1 Overview ...

10.2 Soloud.fadeVolume() 2. 6. ee

10.3 Soloud.fadePan()

10.4 Soloud.fadeRelativePlaySpeed() . 2... ee 10.5 Soloud.fadeGlobalVolume() 2... 6. 10.6 Soloud.schedulePause() 2... 10.7 Soloud.scheduleStop() . 2... ee 10.8 Soloud.oscillateVolume() 2... es 10.9 Soloud.oscillatePan() 2... 1. ee 10.10o0loud.oscillateRelativePlaySpeed(). 2... 2... ee ee ee ee 10.11Soloud.oscillateGlobalVolume() . 2... ee 10.1250loud:fadeFilterParameter() .4.4444..¢4%4 4444 ¢4 44 4444 ¢4 4404 10.13Soloud.oscillateFilterParameter() . 2...

11 Core: Misc

11.1 Soloud.getStreamTime(). 2. 6 ee 11.2 Soloud.isValidChannelHandle() 2... 1. 11.3 Soloud.getActiveVoiceCount() . 2... ee 11.4 Soloud.setGlobalFilter() ... 2.46. 4604444046 464 wee de Eee ees

11.5 Soloud.calcFFT()

11.6 Soloud:setWave() 2.244 44444244444 4 444) $24 24240) $4 4% 4

12 SoLoud::AudioSource

12.1 AudioSource.setLooping() .. 2... 6. ee

SoLoud Audio Engine - http://soloud-audio.com

12.2 AudioSource.setFilter() 2... 6. 12.3 AudioSource.setSinglelnstance(). 2... 6.

13 SoLoud::Wav

13.1 Wav.load() 2... 2 ee 13.2 Wav.loadMem() . 1... ee ee

14 SoLoud::WavStream

14.1 WavStream.load() . 2...

15 SoLoud::Speech

15.1 Speech.setText() 2... ee

16 Creating New Audio Sources

16:1 AUGIOSOUrCE ClaSS” « «20% & aaa ele. ew ee ele eee ee eee eee 16.2 AudioSource.createlnstance() . 2... ee 16.3 AudioSourcelnstance class... 2. 16.4 AudioSourcelnstance.getAudio(). 2... 6. 16.5 AudioSourcelnstance.hasEnded() . 2... 2. eee ee ee ee 16.6 AudioSourcelnstance.seek() . 2... ee 16.7 AudioSourcelnstance.rewind(). 2... 6 ee

17 SoLoud::Bus

18 SoLoud::Filter

18.1 Filter class. 2... ee 18.2 Filterlnstance:class .. i444 44446444464 4¢444 44 04 45 18.3 Filterlnstance.filter() 2... 0... ee et 18.4 Filterlnstance.filterChannel() . 2... 2. ee ee 18.5 Filterlnstance.getFilterParameter() . 2... 2. ee ee ee ee 18.6 FilterInstance.setFilterParameter() 2... 2... ee ee ee ee 18.7 Filterlnstance.fadeFilterParameter() ...........0020004 18.8 Filterlnstance.oscillateFitlerParameter() ...........2.20804

19 SoLoud::BiquadResonantFilter 20 SoLoud::EchoFilter 21 SoLoud::FFTFilter

22 Back-ends

22.1 Soloud.init))....2.22e2.28e828 88254 2 Dee eee es 22.2 Soloud:MIX()'s #4 243 bo Re eRe EERE ERS RSE RG 22.3 Soloud.mBackendData...........0 2. cee eee ee ee ee 22.4 Soloud.mLockMutexFunc / Soloud.mUnlockMutexFunc ........ 22.5 Soloud.mMutex . 2... 2... ee 22.6 Soloud.mBackendCleanupFunc .........-..2.200+020 05 22.7 Different back-ends .... 2... 2. ee ee ee ee

SoLoud Audio Engine - http://soloud-audio.com

1.1

1.2

Introduction

SoLoud is an easy to use, free, portable c/c++ audio engine for games.

How easy?

The engine has been designed to make simple things easy, while not making harder things impossible. Here’s a code snippet that initializes the library, loads a sample and plays it:

// Declare some variables SoLoud::Soloud soloud; // Engine core SoLoud::Wav sample; // One sample

// Initialize SoLoud (with SDL) SoLoud:: sdl_init (&soloud );

sample. load (“pew pew.wav”); // Load a wave file soloud. play (sample); // Play it

The primary form of use the interface is designed for is “fire and forget” audio. In many games, most of the time you don’t need to modify a sound’s parameters on the fly - you just find an event, like an explosion, and trigger a sound effect. SoLoud handles the rest.

If you need to alter some aspect of the sound after the fact, the “play” function returns a handle you can use. For example:

int handle = soloud.play(sample); // Play the sound soloud.setVolume(handle, 0.5f); // Set volume; 1.0f is ”normal” soloud.setPan(handle, —0.2f ); // Set pan; -1 is left, 1 is right

soloud.setRelativePlaySpeed(handle, 0.9f);// Play a bit slower; 1.0f is normal

If the sound doesn’t exist anymore (either it’s ended or you’ve played so many sounds at once it’s channel has been taken over by some other sound), the handle is still safe to use - it just doesn’t do anything.

How free?

SoLoud is released under the ZLib/LibPNG license. That means you can use it in free or commer- cial applications as much as you want. You can modify it. You don’t need to give the changes back. You don’t need to release the source code. You don’t need to add a splash screen. You don’t need to mention it in your printed manual.

Basically the only things the license forbids are suing me, or claiming that you made SoLoud. If you redistribute the source code, the license needs to be there. But not with the binaries.

Parts of the SoLoud package were not made by me, and those either have a similar license, or more permissive (such as Unlicense, CCO, WTFPL or Public Domain).

SoLoud Audio Engine - http://soloud-audio.com 4

1.3 There’s a Catch, Right?

SoLoud quite probably doesn’t have all the features you’d find in a commercial library like FMOD or WWISE. There’s no artist tools or engine integration. There’s no 3d audio. Output is, currently, limited to stereo.

It quite probably isn’t as fast. As of this writing, it has no specialized assembler optimizations, for any platform.

It certainly doesn’t come with the support you get from a commercial library.

If you’re planning to make a multi-million budgeted console game, this library is (probably) not for you. Feel free to try it though =)

SoLoud Audio Engine - http://soloud-audio.com 5

2.1

Zz

2.3

Legal

SoLoud, like everything else, stands on the shoulders of giants; however, care has been taken to only incorporate source code that is under liberal licenses, namely ZLib/LibPNG, CCO or public domain, or similar, like WTFPL or Unlicense, where you don’t need to include mention of the code in your documentation or splash screens or any such nonsense.

SoLoud Proper

SoLoud proper is licensed under the ZLib/LibPNG license. The code is a clean-room implemen- tation with no outside sources used.

SoLoud audio engine Copyright (c) 2013 Jari Komppa

This software is provided ’as-is’ , without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.

Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely , subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software

in a product, an acknowledgment in the product documentation would be appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.

3. This notice may not be removed or altered from any source distribution.

OGG Support

The OGG support in the Wav and WavStream sound sources is based on stb_vorbis by Sean Barrett, and it’s in the public domain. You can find more information (and latest version) at http://nothings.org/stb vorbis/

Speech Synthesizer

The speech synth is based on rsynth by the late Nick Ing-Simmons (et al). He described the legal status as:

This is a text to speech system produced by integrating various pieces of code and tables of data, which are all (| believe) in the public domain.

SoLoud Audio Engine - http://soloud-audio.com 6

2.4

Since then, the rsynth source code has passed legal checks by several open source organizations, so it “should” be pretty safe.

The primary copyright claims seem to have to do with text-to-speech dictionary use, which I’ve removed completely.

I’ve done some serious refactoring, clean-up and feature removal on the source, as all | need is “a” free, simple speech synth, not a “good” speech synth. Since I’ve removed a bunch of stuff, this is probably safer public domain release than the original.

I’m placing my changes in public domain as well, or if that’s not acceptable for you, then CCO: http://creativecommons.org/publicdomain/zero/1.0/.

The SoLoud interface files (soloud_speech.*) are under the same ZLib/LibPNG license as the other SoLoud bits.

Fast Fourier Transform (FFT)

FFT calculation is provided by a fairly simpple implementation by Stephan M. Bernsee, under the Wide Open License:

COPYRIGHT 1996 Stephan M. Bernsee <smb [AT] dspdimension [DOT] com> The Wide Open License (WOL)

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice and this license appear in all source copies. THIS SOFTWARE IS PROVIDED “AS,,IS” WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. See http://www. dspguru.com/wol.htm for more information.

SoLoud Audio Engine - http://soloud-audio.com 7

3.1

Baz

3.3

3.4

3.5

3.6

Quick Start

Note: SoLoud supports several different “back ends”, but this quickstart guide assumes you’re using SDL; the primary difference is that to use a different back-end, you call the desired back- end’s init function (instead of SDL’s).

Download SoLoud

First, you need to download SoLoud sources. You can find the downloads on the http: //

soloud-audio.com/download.html1 page.

Add files to your project

You can go the lazy way and just add all of the sources to your project, or you can copy the things you need to a single directory and include those. You’ll need the core files, and quite likely the wav files. If you need the speech synth, include those, too.

Include files

In order to use a certain feature of SoLoud, you need to include its include file. You might have, for instance:

#include “soloud.h” #include “soloud wav.h”

Variables

You need at least the SoLoud engine core, and one or more of the sound source variables. If you’re using five different sound effect wav files, you need five SoLoud::Wav objects. You can play one object any number of times, even on top of each other.

Where to place these is up to you. Globals work, as do allocation from heap, including in a class as members, etc.

SoLoud::Soloud gSoloud; SoLoud::Wav gWave;

Initialize SoLoud

After your SDL_Init call, include a call to initialize SoLoud. The call takes a pointer to the SoLoud core object.

SoLoud:: sdl_init (&gSoloud );

Set up sound sources

This step varies from one sound source to another, but basically you’ll load your wave files here.

SoLoud Audio Engine - http://soloud-audio.com 8

3.7

3.8

3.9

gWave. load (“pew_pew.wav” );

Play sounds

Now you’re ready to play the sounds. Place playing commands wherever you need sound to be played.

gSoloud. play (gWave);

Note that you can play the same sound several times, and it doesn’t cut itself off.

Take control of the sound

You can adjust various things about the sound you’ re playing if you take the handle.

int x = gSoloud. play (gWave ); gSoloud.setPan(x, —0.2f);

Read the soloud.h header file (or this documentation) for further things you can do.

Cleanup

After you’ve done, remember to clean up. If you don’t, the audio thread may do stupid things while the application is shutting down.

gSoloud. deinit ();

3.10 Enjoy

And you’re done!

SoLoud Audio Engine - http://soloud-audio.com 9

Premake

SoLoud comes with a premake4 script. If you want to build SoLoud as static library, instead of including the source files in your project, this can be handy.

Premake can be downloaded from http: //industriousone.com/premake.

Unfortunately, premake4 cannot magically figure out where your libraries may be installed, so you may have to edit the premake4.lua file. The lines to edit can be found at the very beginning of the file, with the following defaults:

local sdl_root =e /dnijrarailes/ sailed local portmidi_root = ”/libraries/portmidi” local dxsdk_root "C: /Program Files, (x86) /Microsofty...”

"/libraries/portaudio” “/libraries/openal”

local portaudio_root local openal_root

You will most likely want to edit at least the sdl_root variable. After your edits, you can run premake4 to generate makefiles or the IDE project files of your preference, such as:

premake4 vs2010

The current version (4.3) supports codeblocks, codelite, vs2002, vs2003, vs2005, vs2008, vs2010, xcode3 and gnu makefiles (gmake). New version with at least vs2012 support is coming soon (as of this writing).

If you wish to use portmidi with the piano example, run premake with an additional parameter:

premake4 ——with—portmidi vs2010

SoLoud Audio Engine - http://soloud-audio.com 10

5.1

py.

5.3

5.4

Concepts

Back end

SoLoud itself “only” performs audio mixing and some resource handling. For it to be useful, it needs one or more sound source and a back end. Some other systems call back-ends ’sink’s. Examples of back-ends would be winmm, portaudio, wasapi and SDL audio. SoLoud comes with several back-ends, and is designed to make back-ends relatively easy to implement.

Channel

One audio stream can contain one or more channels. Typical audio sources are either mono (containing one channel) or stereo (containing two channels), but surround sound audio sources may practically have any number of channels.

Stream

SoLoud can play audio from several sound sources at once (or, in fact, several times from the same sound source at the same time). Each of these sound instances is a “stream”. The number of concurrent streams is limited, as having unlimited streams would cause performance issues, as well as lead to unnecessary clipping.

The default number of concurrent streams - maximum number of “voices” - is 64, but this can be adjusted via a defined constant in the soloud.h file. The hard maximum number is 4096, but if more are required, SoLoud can be modified to support more. But seriously, if you need more than 4096 sounds at once, you’re probably going to make some serious changes in any case.

If all channels are already playing and the application requests another sound to play, SoLoud finds the oldest sound and kills it. Since this may be your background music, you can protect channels from being killed by using the soloud.setProtect call.

Clipping

Audio hardware always has a limited dynamic range. If you think of a signed 16-bit variable, for instance, you can only store values from -32k to +32k in it; if you try to put values outside this range in, things tend to break. Same goes for audio.

SoLoud handles all audio as floats, but performs clipping before passing the samples out, so all values are in the -1..1 range. There’s two ways SoLoud can perform the clipping; the most straghtforward is simply to set all values outside this range to the border value, or alternatively a roundoff calculation can be performed, which “compresses” the loud sounds. The more quiet sounds are largely unchanged, while the loud end gets less precision. The roundoff clipper is used by default.

The roundoff clipper does, however, alter the signal and thus “damages” the sound. A more proper way of doing things would be to use the basic clipper and adjust the global volume to avoid clipping. The roundoff clipper, however, is easier to use.

SoLoud Audio Engine - http://soloud-audio.com 11

5.5

5.6

5.7

16

4 05 —Raw data —Clipping 0 —Roundoff -0.5 -1 -1,5

Figure 5.1: Results of different clippers

Sample

The real world has continious signals, whuch would require infinite amount of storage to store (unless you can figure out some kind of complicated mathematical formula that represents the signal). So, we store discrete samples of signals instead. These samples have traditionally been 8, 16 or 24 bit, but high-end audio is tending towards floating point samples.

SoLoud also uses floating point samples internally. First and foremost, it makes everything much simpler, and second, modern computing devices have become fast enough that this is not really an issue anymore.

Floating point samples also take more space than, for instance, 16 bit samples, but memory and storage sizes have also grown enough to make this a feasible approach. Nothing stops the audio sources from keeping data in a more “compressed” format and performing on-the-fly conversion to float, if memory requirements are a concern.

Sample Rate

The sample rate represents the number of samples used, per second. Typical sample rates are 8000hz, 22050hz, 44100hz and 48000hz. Higher the sample rates mean clearer sound, but also bigger files, more memory and higher processing power requirements.

Play Speed

In addition to a base sample rate, which represents the “normal” playing speed, SoLoud includes a “relative play speed” option. This simply changes the sample rate. However, if you replace your sounds with something that has a different “base” sample rate, using the relative play speed will retain the effect of playing the sound slower (and lower) or faster (and higher).

SoLoud Audio Engine - http://soloud-audio.com 12

5.8 Relative Play Speed SoLoud lets you change the relative play speed of samples. Please note that asking for a higher relative play speed is more expensive than a lower one.

5.9 Resampling SoLoud has to perform resampling when mixing. In an ideal case, all of the sources and the destination sample rate are the same, and no resampling is needed, but this is often not true. Currently, SoLoud supports “point sample” resampling, which means it simply skips or repeats samples as needed, as well as “linear interpolation”, which calculates linear interpolation of samples. Higher quality resamplers are planned.

5.10 Pan Where the sound is coming from in the stereo sound, ranging from left speaker only to right speaker only. SoLoud uses an algorithm to calculate the left/right channel volume so that the overall volume is retained across the field. You can also set the left/right volumes directly, if needed.

5.11 Handle

SoLoud uses throwaway handles to control sounds. The handle is an integer, and internally tracks the channel and sound id, as well as an “uniqueness” value.

If you try to use a handle after the sound it represents has stopped, the operation is quietly discarded (or if you’re requesting information, some kind of generic value is returned). You can also query the validity of a handle.

5.12 Sound Source and Instance

SoLoud uses two kinds of classes for the sounds. Sound sources contain all the information related to the sound in question, such as wave sample data, while sound instances contain information about an “instance” of the sound.

As an analogue, if you think of an old vinyl record, the sound source is the record, and you can put as many playheads - the instances - on the record. All of the playheads can also move at different speeds, output to a different pan position and volume.

5.13 Latency

Audio latency generally means the time it takes from triggering a sound to the sound actually coming out of the speakers. The smaller the latency, the better.

Unfortunately, there’s always some latency. The primary source of latency (that a programmer can have any control over) is the size of audio buffer. Generally speaking, the smaller the buffer, the lower the latency, but at the same time, the smaller the buffer, the more likely the system hits buffer underruns (ie, the play head marches on but there’s no data ready to be played) and the sound breaks down horribly.

Assuming there’s no other sources of latency (and there quite likely is), with 2048 sample buffer and 44100Hz playback, the latency is around 46 milliseconds, which is tolerable in most cases. A 100ms latency is already easily noticeable.

SoLoud Audio Engine - http://soloud-audio.com 13

5.14 Filter

Audio streams can also be modified on the fly for various effects. Typical uses are different environmental effects such as echoes or reverb, or low pass (bassy sound) / high pass (tinny sound) filters, but basically any kind of modification can be done; the primary limitation is the processor power.

SoLoud lets you hook several filters to a single audio stream, as well as to the global audio output.

5.15 Mixing Bus

In addition to mixing audio streams together at the “global” level, SoLoud includes mixing busses which let you mix together groups of audio streams. These serve several purposes.

The most typical use would be to let the user change the volume of different kinds of audio sources - music, sound effects, speech. In this case, you would have one mixing bus for each of these audio source groups, and simply change the volume on the mixing bus, instead of hunting down every sound separately.

When using environmental effects filters, you most likely won’t want the background music to get filtered; the easiest way to handle this is to apply the filters to the mixing bus that plays the sound effects. This will also save on processing power, as you don’t need to apply the environmental audio filters on every sound effect separately.

It’s also possible that you have some very complex audio sources, such as racing cars. In this case it makes sense to place all the audio streams that play from one car into a mixing bus, and then adjust the panning (or, eventually, 3d position) of the mixing bus.

SoLoud Audio Engine - http://soloud-audio.com 14

6.1

6.2

6.3

6.4

6.5

6.6

Frequently Asked Questions

What does it play?

Currently, SoLoud includes support for uncompressed 8 and 16 bit RIFF Wav files, as well as Ogg Vorbis files. Both of these only support a limited feature set of said formats, so you may experience some issues with strange files.

Additionally, SoLoud comes with a speech synthesizer.

The interface for audio sources is relatively simple, so new formats and noise generators, as well as audio filters, can be made.

An example sin/saw/triangle/square generator is also available, as part of the “piano” example.

Since there are several liberally-licensed audio sources available, the number of formats SoLoud will support is likely to grow in the future.

What dependencies does it have? There’s no external library dependencies (apart from stdlib). However, to get audio out of your speakers, a back-end is needed. Back-ends that currently exist include SDL, windows

multimedia and portaudio, and SoLoud has been designed so that making new back-ends would be as painless as possible.

Is there a DLL / C-Interface?

Not yet. This has been requested though, so one may appear at some point.

What’s the animal in the logo?

A fennec fox. Google it. They’re cute!

Is there a mailing list?

There’s a google group, athttp://groups.google.com/d/forum/soloud

Main development occurs on GitHub, athttps://github.com/jarikomppa/soloud

and the issue tracker is in use.

Finally, there’s #soloud on ircnet, if you want to pop by.

Are these real questions?

Surprisingly, yes.

SoLoud Audio Engine - http://soloud-audio.com 15

7.1

7.2

7.3

7.4

Examples

SoLoud package comes with a few simple examples. These can be found under the ‘demos’ directory. Pre-built binaries for Windows can also be found in the ‘bin’ directory.

simplest

The simplest example initializes SoLoud with winmm (for windows) or portaudio (otherwise), and uses the speech synthesizer to play some sound. Once the sound has finished, the application cleans up and quits.

This example also uses SoLoud’s cross-platform thread library to sleep while waiting for the sound to end.

multimusic

The multimusic example loads two OGG music loops as well as one sound effect. You can use the keyboard keys 1 through 5 for various effects:

Key Effect

1 Play sound effect at random play speed and pan 2 Fade music 1 in and music 2 out

3 Fade music 2 in and music 1 out

4 Fade music relative play speed way down

5 Fade music relative play speed to normal

piano

This example is a simple implementation of a playable instrument. The example also includes a simple waveform generator (soloud_basicwave.cpp/h), which can produce square, saw, sine and triangle waves. If compiled to use portmidi, you can also use a midi keyboard to drive the example.

The 1234.. and qwer.. rows of your keyboard can be used to play notes. asdf.. row selects waveform, and zxcv.. row selects filters. Speech synthesizer and on-screen text describes what different keys do. Have fun experimenting!

mixbusses

The mixbusses example demonstrates the use of mixing busses. You can use “qw”, “as” and “7x” keys to adjust volume of different busses.

SoLoud Audio Engine - http://soloud-audio.com 16

7.5 env

The env demo is a non-interactive demo of how SoLoud could be used to play environmental audio.

SoLoud Audio Engine - http://soloud-audio.com 17

8.1

8.2

8.3

Core: Basics

SoLoud::Soloud Object

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. Bluescreens in Windows are not out of the question.

SoLoud::Soloud *soloud = new SoLoud::Soloud; // object created

SoLoud:: sdl_init (soloud ); // 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 teardown 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.

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

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.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 Audio Engine - http://soloud-audio.com 18

8.4

8.5

8.6

8.7

8.8

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.stopSound()

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

soloud.stopSound(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.

SoLoud Audio Engine - http://soloud-audio.com 19

9.1

9.2

9.3

9.4

Core: Attributes

Soloud.getVolume() / Soloud.setVolume()

These functions can be used to get and set a sound’s current volume setting.

float v = soloud.getVolume(h); // Get current volume soloud.setVolume(h, v * 2); // Double it

Note that the volume is the “volume setting”, and the actual volume will depend on the sound source. Namely, a whisper will most likely be more quiet than a scream, even if both are played at the same volume setting.

If an invalid handle is given to getVolume, it will return 0.

Soloud.getPan() / Soloud.setPan()

These functions can be used to get and set a sound’s current pan setting.

float v = soloud.getPan(h); // Get current pan soloud.setPan(h, v 0.1); // Little bit to the left

The range of the pan values is -1 to 1, where -1 is left, 0 is middle and and 1 is right. Setting value outside this range may cause undefined behavior.

SoLoud calculates the left/right volumes from the pan to keep a constant volume; to set the volumes directly, use setPanAbsolute.

If an invalid handle is given to getPan, it will return 0.

Soloud.setPanAbsolute()

These function can be used to set the left/right volumes directly.

soloud.setPanAbsolute(h, 1, 1); // full blast

Note that this does not affect the value returned by getPan.

If an invalid handle is given to getPan, it will return 0.

Soloud.getSamplerate() / Soloud.setSamplerate()

These functions can be used to get and set a sound’s base sample rate.

float v = soloud.getSamplerate(h); // Get the base sample rate soloud.setSamplerate(h, v * 2); // Double it

Setting the value to 0 will cause undefined behavior, likely a crash.

SoLoud Audio Engine - http://soloud-audio.com 20

9.5

9.6

9.7

9.8

To adjust the play speed, while leaving the base sample rate alone, use setRelativePlaySpeed instead.

If an invalid handle is given to getSamplerate, it will return 0.

Soloud.getRelativePlaySpeed() / Soloud.setRelativePlaySpeed()

These functions can be used to get and set a sound’s relative play speed.

float v = soloud. getRelativePlaySpeed (h) soloud.setRelativePlaySpeed(h, v * 0.5f)

// Get relative play speed // Halve it

Setting the value to 0 will cause undefined behavior, likely a crash.

Change the relative play speed of asample. This changes the effective sample rate while leaving the base sample rate alone.

Note that playing a sound at a higher sample rate will require SoLoud to request more samples from the sound source, which will require more memory and more processing power. Playing at a slower sample rate is cheaper.

If an invalid handle is given to getRelativePlaySpeed, it will return 1.

Soloud.getProtectChannel() / Soloud.setProtectChannel()

These functions can be used to get and set a sound’s protection state.

int v = soloud.getProtectChannel(h); // Get the protection state if (v) soloud.setProtectChannel(h, 0); // Disable if protected

Normally, if you try to play more sounds than there are channels, SoLoud will kill off the oldest playing sound to make room. This will most likely be your background music. This can be worked around by protecting the sound.

If all sounds are protected, the result will be undefined.

If an invalid handle is given to getProtectChannel, it will return 0.

Soloud.getPause() / Soloud.setPause()

The setPause function can be used to pause, or unpause, a sound.

if (soloud.getPause(h)) hum_silently (); soloud.setPause(h, 0); // resumes playback

Note that even if a sound is paused, its channel may be taken over. Trying to resume a sound that’s no longer in a channel doesn’t do anything.

If the handle is invalid, the getPause will return 0. Soloud.setPauseAll() The setPauseAll function can be used to pause, or unpause, all sounds.

SoLoud Audio Engine - http://soloud-audio.com 21

9.9

soloud.setPauseAll(h, 0); // resumes playback of all channels

Note that this function will overwrite the pause state of all channels at once. If your game uses this to pause/unpause the sound while the game is paused, do note that it will also pause/un- pause any sounds that you may have paused/unpaused separately.

Soloud.setFilterParameter()

Sets a parameter for a live instance of a filter. The filter must support changing of live param- eters; otherwise this call does nothing.

soloud.setFilterParameter (bar , lp, cutoff ,1000); // set bar’s low pass to cut at 1000hz

9.10 Soloud.getFilterParameter()

Gets a parameter from a live instance of a filter. The filter must support changing of live parameters; otherwise this call returns zero.

float v = soloud. getFilterParameter (bar, lp, cutoff ); // get bar’s low pass cutoff

SoLoud Audio Engine - http://soloud-audio.com 22

10

10.1

Core: Faders

Overview

Faders are a convenient way of performing some common audio tasks without having to add complex code into your application.

The most common use for the faders is to fade audio in or out, adding nice touches and polish.

Let’s say you’re exiting a bar and entering the street.

soloud.fadeVolume(bar_ambience, 0, 2); // fade bar out in 2 seconds soloud.scheduleStop(bar_ambience, 2); // stop the bar ambience after fadeout street_ambience = soloud.play(cars, 0);// start steet ambience at O volume soloud.setProtectChannel(street_ambience, 1); // protect it soloud.fadeVolume(street_ambience, 1, 1.5f); // fade street in in 1.5

Or let’s say you’re quiting your game.

soloud.fadeGlobalVolume(0, 1); // Fade out global volume in 1 second

The faders are only evaluated once per mix function call - in other words, whenever the back end requests samples from SoLoud, which is likely to be in chunks of 20-100ms, which is smoothly enough for most uses.

The exception is volume (which includes panning), which gets interpolated on per-sample basis to avoid artifacts.

The starting value for most faders is the current value.

10.2 Soloud.fadeVolume()

Smoothly change a channel’s volume over specified time.

soloud.fadeVolume(orchestra, 1, 60); // The orchestra creeps in for a minute

The fader is disabled if you change the channel’s volume with setVolume()

10.3 Soloud.fadePan()

Smoothly change a channel’s pan setting over specified time.

soloud.setPan(racecar, -—1); // set start value soloud.fadePan(racecar, 1, 0.5); // Swoosh!

The fader is disabled if you change the channel’s panning with setPan() or setPanAbsolute()

10.4 Soloud.fadeRelativePlaySpeed()

Smoothly change a channel’s relative play speed over specified time.

SoLoud Audio Engine - http://soloud-audio.com 23

soloud. fadeRelativePlaySpeed(hal, 0.1, 6); // Hal’s message slows down

The fader is disabled if you change the channel’s play speed with setRelativePlaySpeed() 10.5 Soloud.fadeGlobalVolume() Smoothly change the global volume over specified time.

soloud.fadeGlobalVolume(0, 2); // Fade everything out in 2 seconds

The fader is disabled if you change the global volume with setGlobalVolume()

10.6 Soloud.schedulePause()

After specified time, pause the channel

soloud.fadeVolume(jukebox, 0, 2)

; // Fade out the music in 2 seconds soloud.schedulePause (jukebox, 2);

// Pause the music after 2 seconds

The scheduler is disabled if you set the pause state with setPause() or setPauseAll().

10.7 Soloud.scheduleStop()

After specified time, stop the channel

soloud.fadeVolume(applause, 0, 10);

// Fade out the cheers for 10 seconds soloud.scheduleStop(applause, 10);

// Stop the sound after 10 seconds There’s no way (currently) to disable this scheduler.

10.8 Soloud.oscillateVolume()

Set fader to oscillate the volume at specified frequency.

soloud.oscillateVolume (murmur, 0, 0.2, 5); // murmur comes and goes

The fader is disabled if you change the channel’s volume with setVolume()

10.9 Soloud.oscillatePan() Set fader to oscillate the panning at specified frequency.

soloud.oscillatePan(ambulance, -1, 1, 10); // Round and round it goes

The fader is disabled if you change the channel’s panning with setPan() or setPanAbsolute()

SoLoud Audio Engine - http://soloud-audio.com 24

10.10 Soloud.oscillateRelativePlaySpeed()

Set fader to oscillate the relative play speed at specified frequency.

soloud. oscillateRelativePlaySpeed(vinyl, 0.9, 1.1, 3); // Wobbly record

The fader is disabled if you change the channel’s play speed with setRelativePlaySpeed()

10.11 Soloud.oscillateGlobalVolume()

Set fader to oscillate the global volume at specified frequency.

soloud.oscillateGlobalVolume(0.5, 1.0, 0.2); // Go crazy

The fader is disabled if you change the global volume with setGlobalVolume()

10.12 Soloud.fadeFilterParameter()

Fades a parameter on a live instance of a filter. The filter must support changing of live param- eters; otherwise this call does nothing.

soloud. fadeFilterParameter (bar ,lp, cutoff ,1000,1); // Fades bar’s low pass to cut at 1000hz

10.13 Soloud.oscillateFilterParameter()

Oscillates a parameter on a live instance of a filter. The filter must support changing of live parameters; otherwise this call does nothing.

soloud.setFilterParameter (bar ,lp, cutoff ,500,1000,2); // Oscillates the bar’s lp filter’s cutoff between 500 and 1kHz

SoLoud Audio Engine - http://soloud-audio.com 25

11 Core: Misc

11.1 Soloud.getStreamTime()

The getStreamTime function can be used to get the current play position, in seconds.

float t = soloud.getStreamTime(h); // get time if (t == hammertime) hammer ();

Note that due to being a floating point value, playing a long stream may cause precision prob- lems, and eventually cause the “time” to stop. This will happen in about 6 days. The precision problems will start somewhat earlier.

Also note that the granularity is likely to be rather high (possibly around 45ms), so using this as the sole clock source for animation will lead to rather low framerate (possibly around 20hz). To fix this, either use some other clock source and only sync