User Tools

Site Tools


AudioManager - One interface, many implementations

If you look in BaseApp.h you'll see this near the bottom:

AudioManager * GetAudioManager();  //supply this yourself

It means it expects you to implement this function somewhere in your App code. Shared-level components and code will be able to use audio through the AudioManager interface, without knowing how you implemented it. (Just standard C++ subclassing with virtuals)

The minimum you have to do is this:

AudioManager g_audioManager; //to disable sound
AudioManager * GetAudioManager()
    return &g_audioManager;

The above will let everything “think” they are using sound functions, but do nothing. To actually hear sound on windows (or iOS using FMOD), do:

#include "Audio/AudioManagerFMOD.h"
AudioManagerFMOD g_audioManager; //play with the FMOD implementation
AudioManager * GetAudioManager()
    return &g_audioManager;

RTSimpleApp uses #ifdefs to use the correct implementation for the correct platform.

BaseApp will run Init() on it, you don't.

Playing a sound


Internally, the audio manager will play it and keep the sound object around for future calls.

Caching/preloading manually

Auto caching is good enough, but if you notice jerks in your game the first time audio is loading you should probably preload them.


All of audio implementations handle playing compressed music (ogg or mp3, or both) and at a minimum, .wav sounds for effects with mixing. FMOD supports more formats like .mid and .xm as well.

Music has its own special way of being called by using the bIsMusic flag:

//defined as:  virtual AudioHandle Play(string fName, bool bLooping = false, bool bIsMusic = false, bool bAddBasePath = true, bool bForceStreaming = false);
GetAudioManager()->Play("song.ogg", false, true);

When you say, “this is music” here is what happens:

  • If the same song is already playing, the call is ignored
  • If another song is playing, it kills it first
  • The file is streamed from disk, not loaded or cached
  • On systems that can only decode one compressed audio in hardware at a time, it is reserved for music
  • If AudioManager::SetMusicEnabled was set with false, it is ignored
  • The volume it plays at is set by AudioManager::SetMusicVol

Advanced controls with AudioHandles

If you want to be able to kill a sound or perform other effects on it during playback, you need to keep track of the AudioHandle returned from the Play() command. (it's just a uint32)

//init somewhere
 AudioHandle npcTalk = 0;
//entities AI sees the player
 npcTalk = GetAudioManager()->Play(taunt.wav);
 GetAudioManager()->SetPan(npcTalk, -1.0f); //left speaker only
 GetAudioManager()->SetVol(npcTalk, 1.0f); //max volume
//but soon after he starts to taunt, he is killed and should do his deathscream
npcTalk = GetAudioManager()->Play("scream.wav");

Using old/dead handles doesn't cause problems.

Note: Some of the more advanced audio functions such as AudioManager::SetPan and AudioManager::SetFrequency are not available on all sound implementations.

Controlling memory

You know that FPS debug text that always shows up in the examples? The A:<number> is how much memory is allocated in audio. (if it says 0, it means this implementation doesn't know and is returning 0 from AudioManager::GetMemoryUsed)

If you are running low on memory you can use AudioManager::KillCachedSounds between levels, or even during levels. Its parameters allow you to further refine what is killed; including by last usage time and priority level.

Good vibrations

For some reason its the AudioManager's job to phone vibration. Called vibration on a platform that can't do it (like PC) will be ignored or write “VIBRATE!” to the debug text.

GetAudioManager()->Vibrate(); //hmm, I may need a VibrateEx() at some point with more options.

If GetAudioManager()→SetVibrateDisabled was set to true, it will be ignored.

proton/audiomanager.txt · Last modified: 2010/10/28 06:40 by seth