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.
GetAudioManager()->Play("click.wav");
Internally, the audio manager will play it and keep the sound object around for future calls.
Auto caching is good enough, but if you notice jerks in your game the first time audio is loading you should probably preload them.
GetAudioManager()->Preload("click.wav");
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 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 GetAudioManager()->Stop(npcTalk); 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.
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.
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.