History: Another FMOD SoundManager
Source of version: 5
Copy to clipboard
The interface
{CODE(wrap="1", colors="c++")}
#pragma once
class ISoundManager{
public:
virtual ~ISoundManager(){}
virtual void Load2DSoundsFromFile(const Ogre::String &fileName)=0;
virtual void Load3DSoundsFromFile(const Ogre::String &fileName)=0;
virtual void UnloadSoundsFromFile(const Ogre::String &fileName)=0;
virtual void Load2DPlaylistFromFile(const Ogre::String &fileName)=0;
virtual void System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity)=0;
virtual void System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity,
const Ogre::Vector3 &forward)=0;
virtual void System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity,
const Ogre::Vector3 &forward, const Ogre::Vector3 &up)=0;
virtual void System3DSettings(const Ogre::Real &dopplerScale, const Ogre::Real &distanceFactor,
const Ogre::Real rolloffScale)=0;
virtual void SoundGroupMaxAudible(const Ogre::String &name, const int &maxAudible)=0;
virtual void SoundGroupMuteFadeSpeed(const Ogre::String &name, const Ogre::Real &speed)=0;
virtual void SoundGroupStop(const Ogre::String &name)=0;
virtual void SoundGroupStopAll()=0;
virtual void SoundGroupEmpty(const Ogre::String &name)=0;
virtual void SoundGroupEmptyAll()=0;
virtual void SoundGroupDestroy(const Ogre::String &name)=0;
virtual void SoundGroupDestroyAll()=0;
virtual void SoundGroupVolume(const Ogre::String &name, const Ogre::Real &volume)=0;
virtual Ogre::Real GetSoundGroupVolume(const Ogre::String &name)=0;
virtual void Sound2DLoopCount(const Ogre::String &name, const int &loopCount)=0;
virtual void Sound3DLoopCount(const Ogre::String &name, const int &loopCount)=0;
virtual void Sound3DConeSettings(const Ogre::String &name, const Ogre::Real &insideAngle,
const Ogre::Real &outsideAngle, const Ogre::Real &outsideVolume)=0;
virtual void Sound3DMinMaxDistance(const Ogre::String &name, const Ogre::Real &minDistance,
const Ogre::Real &maxDistance)=0;
virtual void ChannelGroupCreate(const Ogre::String &name)=0;
virtual void ChannelGroupPause(const Ogre::String &name, const bool &isPaused)=0;
virtual void ChannelGroupPauseAll(const bool &isPaused)=0;
virtual void ChannelGroupMute(const Ogre::String &name, const bool &isMuted)=0;
virtual void ChannelGroupMuteAll(const bool &isMuted)=0;
virtual void ChannelGroupVolume(const Ogre::String &name, const Ogre::Real &volume)=0;
virtual void ChannelGroupVolumeAll(const Ogre::Real &volume)=0;
virtual void ChannelGroupStop(const Ogre::String &name)=0;
virtual void ChannelGroupStopAll()=0;
virtual void ChannelGroupDestroy(const Ogre::String &name)=0;
virtual void ChannelGroupDestroyAll()=0;
virtual void ChannelPause(const int &index, const bool &isPaused)=0;
virtual void ChannelMute(const int &index, const bool &isMuted)=0;
virtual void ChannelVolume(const int &index, const Ogre::Real &volume)=0;
virtual void ChannelLoop(const int &index, const int &loopCount)=0;
virtual void ChannelStop(const int &index)=0;
virtual void Channel3DAttributes(const int &index, const Ogre::Vector3 &position,
const Ogre::Vector3 &velocity)=0;
virtual void Channel3DConeOrientation(const int &index, const Ogre::Vector3 &orientation)=0;
virtual void Channel3DConeSettings(const int &index, const Ogre::Real &insideAngle,
const Ogre::Real &outsideAngle, const Ogre::Real &outsideVolume)=0;
virtual void Channel3DDopplerLevel(const int &index, const Ogre::Real &level)=0;
virtual void Channel3DMinMaxDistance(const int &index, const Ogre::Real &minDistance,
const Ogre::Real &maxDistance)=0;
virtual void PlaylistPlay(const Ogre::String &playlistName)=0;
virtual void PlaylistPlayAll()=0;
virtual void PlaylistSkip(const Ogre::String &playlistName)=0;
virtual void PlaylistPause(const Ogre::String &playlistName)=0;
virtual void PlaylistPauseAll()=0;
virtual void PlaylistResume(const Ogre::String &playlistName)=0;
virtual void PlaylistResumeAll()=0;
virtual void PlaylistStop(const Ogre::String &playlistName)=0;
virtual void PlatlistStopAll()=0;
virtual void PlaylistDestroy(const Ogre::String &playlistName)=0;
virtual void PlaylistDestroyAll()=0;
virtual int Play2DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName)=0;
virtual int Play2DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const int &loopCount)=0;
virtual int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position)=0;
virtual int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const int &loopCount)=0;
virtual int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Vector3 &forward)=0;
virtual int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Vector3 &forward,
const int &loopCount)=0;
};
{CODE}
The header
{CODE(wrap="1", colors="c++")}
#pragma once
#include "ISoundManager.h"
#include <fmod.hpp>
#include "FMOD\fmod_errors.h"
#include <hash_map>
#include <fstream>
#define SOUND_LOG_NAME "SoundManager.log"
#define SOUND_LOG(x) Ogre::LogManager::getSingleton().getLog(SOUND_LOG_NAME)->logMessage(x)
#define MAX_CHAR_ARRAY_SIZE 255
#define MAX_SOUND_CHANNELS 200
#define SONG_PRIORITY 0
#define SOUND_PRIORITY_2D 1
#define SOUND_PATH "..\\..\\res\\Audio\\"
class SoundInstance{
public:
SoundInstance(Ogre::String soundName, FMOD::Sound* sound):
_soundName(soundName), _sound(sound)
{}
~SoundInstance(){
_sound->release();
}
Ogre::String _soundName;
FMOD::Sound* _sound;
};
class SoundManager : public ISoundManager{
public:
void Load2DSoundsFromFile(const Ogre::String &fileName);
void Load3DSoundsFromFile(const Ogre::String &fileName);
void UnloadSoundsFromFile(const Ogre::String &fileName);
void Load2DPlaylistFromFile(const Ogre::String &fileName);
void System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity);
void System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity,
const Ogre::Vector3 &forward);
void System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity,
const Ogre::Vector3 &forward, const Ogre::Vector3 &up);
void System3DSettings(const Ogre::Real &dopplerScale, const Ogre::Real &distanceFactor,
const Ogre::Real rolloffScale);
void SoundGroupCreate(const Ogre::String &name);
void SoundGroupMaxAudible(const Ogre::String &name, const int &maxAudible);
void SoundGroupMuteFadeSpeed(const Ogre::String &name, const Ogre::Real &speed);
void SoundGroupStop(const Ogre::String &name);
void SoundGroupStopAll();
void SoundGroupEmpty(const Ogre::String &name);
void SoundGroupEmptyAll();
void SoundGroupDestroy(const Ogre::String &name);
void SoundGroupDestroyAll();
void SoundGroupVolume(const Ogre::String &name, const Ogre::Real &volume);
Ogre::Real GetSoundGroupVolume(const Ogre::String &name);
void Sound2DLoopCount(const Ogre::String &name, const int &loopCount);
void Sound3DLoopCount(const Ogre::String &name, const int &loopCount);
void Sound3DConeSettings(const Ogre::String &name, const Ogre::Real &insideAngle,
const Ogre::Real &outsideAngle, const Ogre::Real &outsideVolume);
void Sound3DMinMaxDistance(const Ogre::String &name, const Ogre::Real &minDistance,
const Ogre::Real &maxDistance);
void ChannelGroupCreate(const Ogre::String &name);
void ChannelGroupPause(const Ogre::String &name, const bool &isPaused);
void ChannelGroupPauseAll(const bool &isPaused);
void ChannelGroupMute(const Ogre::String &name, const bool &isMuted);
void ChannelGroupMuteAll(const bool &isMuted);
void ChannelGroupVolume(const Ogre::String &name, const Ogre::Real &volume);
void ChannelGroupVolumeAll(const Ogre::Real &volume);
void ChannelGroupStop(const Ogre::String &name);
void ChannelGroupStopAll();
void ChannelGroupDestroy(const Ogre::String &name);
void ChannelGroupDestroyAll();
void ChannelPause(const int &index, const bool &isPaused);
void ChannelMute(const int &index, const bool &isMuted);
void ChannelVolume(const int &index, const Ogre::Real &volume);
void ChannelLoop(const int &index, const int &loopCount);
void ChannelStop(const int &index);
void Channel3DAttributes(const int &index, const Ogre::Vector3 &position, const Ogre::Vector3 &velocity);
void Channel3DConeOrientation(const int &index, const Ogre::Vector3 &orientation);
void Channel3DConeSettings(const int &index, const Ogre::Real &insideAngle, const Ogre::Real &outsideAngle,
const Ogre::Real &outsideVolume);
void Channel3DDopplerLevel(const int &index, const Ogre::Real &level);
void Channel3DMinMaxDistance(const int &index, const Ogre::Real &minDistance, const Ogre::Real &maxDistance);
void PlaylistPlay(const Ogre::String &playlistName);
void PlaylistPlayAll();
void PlaylistSkip(const Ogre::String &playlistName);
void PlaylistPause(const Ogre::String &playlistName);
void PlaylistPauseAll();
void PlaylistResume(const Ogre::String &playlistName);
void PlaylistResumeAll();
void PlaylistStop(const Ogre::String &playlistName);
void PlatlistStopAll();
void PlaylistDestroy(const Ogre::String &playlistName);
void PlaylistDestroyAll();
int Play2DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName="MASTER");
int Play2DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName="MASTER",
const int &loopCount=0);
int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position);
int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const int &loopCount);
int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Vector3 &forward);
int Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Vector3 &forward,
const int &loopCount);
static SoundManager* getSingleton(){
if(!_soundManager)
_soundManager = new SoundManager();
return _soundManager;
}
private:
static SoundManager* _soundManager;
static int SOUND_2D; //memory addresses of these these values are used to distinguish
static int SOUND_3D; //between 2d and 3d sounds. passed around as void pointers in fmod
SoundManager();
virtual ~SoundManager();
void Initialize();
void UpdateStarted(const Ogre::FrameEvent &gameTime);
void UpdateEnded(const Ogre::FrameEvent &gameTime);
void Cleanup();
void UnloadSound(const Ogre::String &name, const void *type);
static void OpenFile(const Ogre::String fileName, std::ifstream &infile);
static const FMOD_VECTOR OgreToFmodVec(const Ogre::Vector3 &vector);
static const Ogre::Vector3 FmodToOgreVec(const FMOD_VECTOR &vector);
FMOD::System* _system;
Ogre::Real _timeSinceLastFrame;
FMOD_VECTOR _listenerPosition;
FMOD_VECTOR _velocityVector;
FMOD_VECTOR _forwardVector;
FMOD_VECTOR _upVector;
stdext::hash_map<const Ogre::String, SoundInstance*>* _2DsoundMap;
stdext::hash_map<const Ogre::String, SoundInstance*>* _3DsoundMap;
stdext::hash_map<const Ogre::String, FMOD::SoundGroup*>* _soundGroupMap;
stdext::hash_map<const Ogre::String, FMOD::SoundGroup*>::iterator _SGMitr;
stdext::hash_map<const Ogre::String, FMOD::ChannelGroup*>* _channelGroupMap;
stdext::hash_map<const Ogre::String, FMOD::ChannelGroup*>::iterator _CGMitr;
class Sound2DPlaylist;
stdext::hash_map<const Ogre::String, Sound2DPlaylist*>* _playlistMap;
stdext::hash_map<const Ogre::String, Sound2DPlaylist*>::iterator _playlistItr;
class Sound2DPlaylist{
public:
Sound2DPlaylist(const Ogre::String &name) : _name(name) {}
~Sound2DPlaylist() { _soundQueue.clear();}
void Update(FMOD::System *system){
FMOD::Channel *channel;
if(system->getChannel(_channel, &channel) == FMOD_OK)
return;
Skip();
}
void AddSound(const Ogre::String soundName) { _soundQueue.push_back(soundName); }
void Play(){ Stop(); _channel = SoundManager::getSingleton()->Play2DSound(_soundQueue.front(), _name);}
void Pause() { SoundManager::getSingleton()->ChannelPause(_channel, true); }
void Resume(){ SoundManager::getSingleton()->ChannelPause(_channel, false); }
void Stop(){ SoundManager::getSingleton()->ChannelStop(_channel); _channel = -1; }
void Skip(){ _soundQueue.push_back(_soundQueue.front()); _soundQueue.pop_front(); Stop(); Play(); }
Ogre::String _name;
FMOD::ChannelGroup* _channelGroup;
std::deque<const Ogre::String> _soundQueue;
std::deque<const Ogre::String>::iterator _itr;
int _channel;
};
};
{CODE}
The implementation
{CODE(wrap="1", colors="c++")}
#include "SoundManager.h"
//static variable instances
int SoundManager::SOUND_2D;
int SoundManager::SOUND_3D;
SoundManager* SoundManager::_soundManager;
SoundManager::SoundManager() :
_system(nullptr),
_2DsoundMap(new stdext::hash_map<const Ogre::String, SoundInstance*>()),
_3DsoundMap(new stdext::hash_map<const Ogre::String, SoundInstance*>()),
_soundGroupMap(new stdext::hash_map<const Ogre::String, FMOD::SoundGroup*>()),
_channelGroupMap(new stdext::hash_map<const Ogre::String, FMOD::ChannelGroup*>()),
_playlistMap(new stdext::hash_map<const Ogre::String, Sound2DPlaylist*>())
{
Ogre::LogManager::getSingleton().createLog(SOUND_LOG_NAME);
SOUND_LOG("SoundManager created");
}
SoundManager::~SoundManager(){
_system = nullptr;
delete _2DsoundMap; _2DsoundMap = nullptr;
delete _3DsoundMap; _3DsoundMap = nullptr;
delete _soundGroupMap; _soundGroupMap = nullptr;
delete _channelGroupMap; _channelGroupMap = nullptr;
SOUND_LOG("SoundManager destroyed");
}
void SoundManager::Initialize(){
FMOD::System_Create(&_system);
_system->init(MAX_SOUND_CHANNELS, FMOD_INIT_NORMAL,0);
FMOD::SoundGroup* soundGroup;
_system->getMasterSoundGroup(&soundGroup);
_soundGroupMap->insert(std::pair<const Ogre::String, FMOD::SoundGroup*>("MASTER", soundGroup));
FMOD::ChannelGroup* channelGroup;
_system->getMasterChannelGroup(&channelGroup);
_channelGroupMap->insert(std::pair<const Ogre::String, FMOD::ChannelGroup*>("MASTER", channelGroup));
_system->set3DNumListeners(1);
SOUND_LOG("SoundManager initialized");
}
void SoundManager::UpdateStarted(const Ogre::FrameEvent &gameTime){
_timeSinceLastFrame = gameTime.timeSinceLastFrame;
_system->update();
}
void SoundManager::UpdateEnded(const Ogre::FrameEvent &gameTime){
}
void SoundManager::Cleanup(){
this->PlaylistDestroyAll();
this->ChannelGroupDestroyAll();
this->SoundGroupDestroyAll();
this->PlaylistDestroyAll();
_system->close();
_system->release();
}
void SoundManager::UnloadSound(const Ogre::String &name, const void *type){
SoundInstance* tempSound;
if(int(type) == int(&SoundManager::SOUND_2D)){
if(!_2DsoundMap->count(name))
return;
tempSound = _2DsoundMap->at(name);
_2DsoundMap->erase(name);
}else if(int(type) == int(&SoundManager::SOUND_3D)){
if(!_3DsoundMap->count(name))
return;
tempSound = _3DsoundMap->at(name);
_3DsoundMap->erase(name);
}
delete tempSound;
}
#pragma region static functions
/**open the file specified starting from the BASE_PATH directory\n
opens the file using the ifstream passed in
*/
void SoundManager::OpenFile(const Ogre::String fileName, std::ifstream &infile){
Ogre::String listPath;
listPath.append(SOUND_PATH + fileName);
infile.open(listPath);
if(infile.fail()){
SOUND_LOG("SoundManager::OpenFile() - cannot open file: " + listPath);
return;
}
}
/** returns an FMOD_VECTOR equivalent to the Ogre::Vector3 passed in
*/
const FMOD_VECTOR SoundManager::OgreToFmodVec(const Ogre::Vector3 &vector){
FMOD_VECTOR tempVec;
tempVec.x = vector.x;
tempVec.y = vector.y;
tempVec.z = vector.z;
return tempVec;
}
/** returns an Ogre::Vector3 equivalent to the FMOD_VECTOR passed in
*/
const Ogre::Vector3 SoundManager::FmodToOgreVec(const FMOD_VECTOR &vector){
return Ogre::Vector3(vector.x, vector.y, vector.z);
}
#pragma endregion
#pragma region loading/unloading sound
void SoundManager::Load2DSoundsFromFile(const Ogre::String &fileName){
std::ifstream infile;
SoundManager::OpenFile(fileName, infile);
if(infile.fail()){
infile.close();
return;
}
FMOD::Sound* soundResult; //dont delete this pointer, it just holds results
const Ogre::String soundPathString(SOUND_PATH);
Ogre::String soundFileString;
Ogre::String soundNameString;
Ogre::String soundGroupName;
Ogre::String soundPriorityString;
char* tempChar = new char[MAX_CHAR_ARRAY_SIZE];
infile>>tempChar;
soundGroupName.append(tempChar);
if(!_soundGroupMap->count(soundGroupName)){ //make the soundgroup if it doesn't exist
this->SoundGroupCreate(soundGroupName);
_soundGroupMap->at(soundGroupName)->setUserData(&SoundManager::SOUND_2D);
}
while(!infile.eof()){
soundNameString.clear();
soundFileString.clear();
infile>>tempChar;
soundFileString.append(soundPathString + tempChar);
infile>>tempChar;
soundPriorityString.append(tempChar);
infile.getline(tempChar, MAX_CHAR_ARRAY_SIZE);
soundNameString.append(tempChar);
Ogre::StringUtil::trim(soundNameString);
if(_2DsoundMap->count(soundNameString))
continue; //sound already loaded
if(_system->createSound(soundFileString.c_str(), FMOD_2D | FMOD_HARDWARE, nullptr, &soundResult)
!= FMOD_OK)
continue;
int priority;
Ogre::Real frequency, volume, pan;
soundResult->getDefaults(&frequency, &volume, &pan, &priority);
soundResult->setDefaults(frequency, volume, pan, Ogre::StringConverter::parseInt(soundPriorityString));
soundResult->setSoundGroup(_soundGroupMap->at(soundGroupName));
_2DsoundMap->insert(std::pair<const Ogre::String, SoundInstance*>(
soundNameString, new SoundInstance(soundNameString, soundResult)));
soundResult->setUserData(&(_2DsoundMap->at(soundNameString)->_soundName));
}
infile.close();
delete tempChar;
}
void SoundManager::Load3DSoundsFromFile(const Ogre::String &fileName){
std::ifstream infile;
SoundManager::OpenFile(fileName, infile);
if(infile.fail()){
infile.close();
return;
}
FMOD::Sound* soundResult; //dont delete this pointer, it just holds results
const Ogre::String soundPathString(SOUND_PATH);
Ogre::String soundFileString;
Ogre::String soundNameString;
Ogre::String soundGroupName;
Ogre::String soundPriorityString;
char* tempChar = new char[MAX_CHAR_ARRAY_SIZE];
infile>>tempChar;
soundGroupName.append(tempChar);
if(!_soundGroupMap->count(soundGroupName)){ //make the soundgroup if it doesn't exist
this->SoundGroupCreate(soundGroupName);
_soundGroupMap->at(soundGroupName)->setUserData(&SoundManager::SOUND_3D);
}
while(!infile.eof()){
soundNameString.clear();
soundFileString.clear();
infile>>tempChar;
soundFileString.append(soundPathString + tempChar);
infile>>tempChar;
soundPriorityString.append(tempChar);
infile.getline(tempChar, MAX_CHAR_ARRAY_SIZE);
soundNameString.append(tempChar);
Ogre::StringUtil::trim(soundNameString);
if(_3DsoundMap->count(soundNameString))
continue; //sound already loaded
if(_system->createSound(soundFileString.c_str(), FMOD_3D | FMOD_HARDWARE, nullptr, &soundResult)
!= FMOD_OK)
continue;
int priority;
Ogre::Real frequency, volume, pan;
soundResult->getDefaults(&frequency, &volume, &pan, &priority);
soundResult->setDefaults(frequency, volume, pan, Ogre::StringConverter::parseInt(soundPriorityString));
soundResult->setSoundGroup(_soundGroupMap->at(soundGroupName));
_3DsoundMap->insert(std::pair<const Ogre::String, SoundInstance*>(
soundNameString, new SoundInstance(soundNameString, soundResult)));
soundResult->setUserData(&(_3DsoundMap->at(soundNameString)->_soundName));
}
infile.close();
delete tempChar;
}
void SoundManager::UnloadSoundsFromFile(const Ogre::String &fileName){
std::ifstream infile;
SoundManager::OpenFile(fileName, infile);
if(infile.bad()){
infile.close();
return;
}
Ogre::String soundGroupName;
char* tempChar = new char[MAX_CHAR_ARRAY_SIZE];
infile>>tempChar;
soundGroupName.append(tempChar);
this->SoundGroupDestroy(soundGroupName);
infile.close();
delete tempChar;
}
void SoundManager::Load2DPlaylistFromFile(const Ogre::String &fileName){
this->Load2DSoundsFromFile(fileName);
std::ifstream infile;
SoundManager::OpenFile(fileName, infile);
if(infile.bad()){
infile.close();
return;
}
Ogre::String playlistNameString, nameString;
char* tempChar = new char[MAX_CHAR_ARRAY_SIZE];
infile>>tempChar>>tempChar;
infile.getline(tempChar, MAX_CHAR_ARRAY_SIZE);
playlistNameString.append(tempChar);
Sound2DPlaylist* playlist = new Sound2DPlaylist(playlistNameString);
while(!infile.eof()){
nameString.clear();
infile.getline(tempChar, MAX_CHAR_ARRAY_SIZE);
nameString.append(tempChar);
if(!_2DsoundMap->count(nameString))
continue;
playlist->AddSound(nameString);
}
_playlistMap->insert(std::pair<const Ogre::String, Sound2DPlaylist*>(playlistNameString, playlist));
infile.close();
delete tempChar;
}
#pragma endregion
#pragma region system
void SoundManager::System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity){
const FMOD_VECTOR posVec = {position.x, position.y, position.z},
velVec = {velocity.x * _timeSinceLastFrame,
velocity.y * _timeSinceLastFrame,
velocity.z * _timeSinceLastFrame};
_listenerPosition = posVec;
_velocityVector = velVec;
_system->set3DListenerAttributes(0, &posVec, &velVec, &_forwardVector, &_upVector);
}
void SoundManager::System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity,
const Ogre::Vector3 &forward){
const FMOD_VECTOR posVec = {position.x, position.y, position.z},
velVec = {velocity.x * _timeSinceLastFrame,
velocity.y * _timeSinceLastFrame,
velocity.z * _timeSinceLastFrame},
forVec = {forward.normalisedCopy().x, forward.normalisedCopy().y, forward.normalisedCopy().z};
_listenerPosition = posVec;
_velocityVector = velVec;
_forwardVector = forVec;
_system->set3DListenerAttributes(0, &posVec, &velVec, &forVec, &_upVector);
}
void SoundManager::System3DAttributes(const Ogre::Vector3 &position, const Ogre::Vector3 &velocity,
const Ogre::Vector3 &forward, const Ogre::Vector3 &up){
const FMOD_VECTOR posVec = {position.x, position.y, position.z},
velVec = {velocity.x * _timeSinceLastFrame,
velocity.y * _timeSinceLastFrame,
velocity.z * _timeSinceLastFrame},
forVec = {forward.normalisedCopy().x, forward.normalisedCopy().y, forward.normalisedCopy().z},
upVec = {up.normalisedCopy().x, up.normalisedCopy().y, up.normalisedCopy().z};
_listenerPosition = posVec;
_velocityVector = velVec;
_forwardVector = forVec;
_upVector = upVec;
_system->set3DListenerAttributes(0, &posVec, &velVec, &forVec, &upVec);
}
void SoundManager::System3DSettings(const Ogre::Real &dopplerScale, const Ogre::Real &distanceFactor,
const Ogre::Real rolloffScale){
_system->set3DSettings(dopplerScale, distanceFactor, rolloffScale);
}
#pragma endregion
#pragma region sound group
void SoundManager::SoundGroupCreate(const Ogre::String &name){
if(_soundGroupMap->count(name))
return;
FMOD::SoundGroup* soundGroup;
if(_system->createSoundGroup(name.c_str(), &soundGroup) != FMOD_OK)
return;
_soundGroupMap->insert(std::pair<const Ogre::String, FMOD::SoundGroup*>(name.c_str(), soundGroup));
}
void SoundManager::SoundGroupMuteFadeSpeed(const Ogre::String &name, const Ogre::Real &speed){
if(_soundGroupMap->count(name))
return;
_soundGroupMap->at(name)->setMuteFadeSpeed(speed);
}
void SoundManager::SoundGroupMaxAudible(const Ogre::String &name, const int &maxAudible){
if(!_soundGroupMap->count(name))
return;
_soundGroupMap->at(name)->setMaxAudible(maxAudible);
_soundGroupMap->at(name)->setMaxAudibleBehavior(FMOD_SOUNDGROUP_BEHAVIOR_MUTE);
}
void SoundManager::SoundGroupStop(const Ogre::String &name){
if(!_soundGroupMap->count(name))
return;
_soundGroupMap->at(name)->stop();
}
void SoundManager::SoundGroupStopAll(){
for(_SGMitr = _soundGroupMap->begin(); _SGMitr != _soundGroupMap->end(); ++_SGMitr)
_SGMitr->second->stop();
}
void SoundManager::SoundGroupEmpty(const Ogre::String &name){
if(!_soundGroupMap->count(name))
return;
this->SoundGroupStop(name);
FMOD::Sound* sound;
FMOD::SoundGroup* soundGroup = _soundGroupMap->at(name);
Ogre::String* soundName;
void* userData;
int soundCount;
soundGroup->getNumSounds(&soundCount);
while(soundCount-- > 0){
soundGroup->getSound(0, &sound);
sound->getUserData(&userData);
soundName = (Ogre::String*)userData;
soundGroup->getUserData(&userData);
this->UnloadSound(*soundName, userData);
}
}
void SoundManager::SoundGroupEmptyAll(){
for(_SGMitr = _soundGroupMap->begin(); _SGMitr != _soundGroupMap->end(); ++_SGMitr)
this->SoundGroupEmpty(_SGMitr->first);
}
void SoundManager::SoundGroupDestroy(const Ogre::String &name){
if(!_soundGroupMap->count(name) || !name.compare("MASTER"))
return;
this->SoundGroupEmpty(name);
_soundGroupMap->at(name)->release();
_soundGroupMap->erase(name);
}
void SoundManager::SoundGroupDestroyAll(){
this->SoundGroupEmptyAll();
for(_SGMitr = _soundGroupMap->begin(); _SGMitr != _soundGroupMap->end(); ++_SGMitr){
if(!_SGMitr->first.compare("MASTER"))
continue;
_SGMitr->second->release();
}
_soundGroupMap->clear();
FMOD::SoundGroup* soundGroup;
_system->getMasterSoundGroup(&soundGroup);
_soundGroupMap->insert(std::pair<const Ogre::String, FMOD::SoundGroup*>("MASTER", soundGroup));
}
void SoundManager::SoundGroupVolume(const Ogre::String &name, const Ogre::Real &volume){
if(!_soundGroupMap->count(name))
return;
_soundGroupMap->at(name)->setVolume(volume);
}
Ogre::Real SoundManager::GetSoundGroupVolume(const Ogre::String &name){
if(!_soundGroupMap->count(name))
return -1.0f;
Ogre::Real volume;
_soundGroupMap->at(name)->getVolume(&volume);
return volume;
}
#pragma endregion
#pragma region sound
void SoundManager::Sound2DLoopCount(const Ogre::String &name, const int &loopCount){
if(!_2DsoundMap->count(name))
return;
_2DsoundMap->at(name)->_sound->setLoopCount(loopCount);
}
void SoundManager::Sound3DLoopCount(const Ogre::String &name, const int &loopCount){
if(!_3DsoundMap->count(name))
return;
_3DsoundMap->at(name)->_sound->setLoopCount(loopCount);
}
void SoundManager::Sound3DConeSettings(const Ogre::String &name, const Ogre::Real &insideAngle, const Ogre::Real &outsideAngle, const Ogre::Real &outsideVolume){
if(!_3DsoundMap->count(name))
return;
_3DsoundMap->at(name)->_sound->set3DConeSettings(insideAngle, outsideAngle, outsideVolume);
}
void SoundManager::Sound3DMinMaxDistance(const Ogre::String &name, const Ogre::Real &minDistance, const Ogre::Real &maxDistance){
if(!_3DsoundMap->count(name))
return;
_3DsoundMap->at(name)->_sound->set3DMinMaxDistance(minDistance, maxDistance);
}
#pragma endregion
#pragma region channel group
void SoundManager::ChannelGroupCreate(const Ogre::String &name){
if(_channelGroupMap->count(name))
return;
FMOD::ChannelGroup* channelGroup;
if(_system->createChannelGroup(name.c_str(), &channelGroup) == FMOD_OK)
_channelGroupMap->insert(std::pair<const Ogre::String, FMOD::ChannelGroup*>(name.c_str(), channelGroup));
}
void SoundManager::ChannelGroupPause(const Ogre::String &name, const bool &isPaused){
if(_channelGroupMap->count(name))
return;
_channelGroupMap->at(name)->setPaused(isPaused);
}
void SoundManager::ChannelGroupPauseAll(const bool &isPaused){
for(_CGMitr = _channelGroupMap->begin(); _CGMitr != _channelGroupMap->end(); ++_CGMitr)
_CGMitr->second->setPaused(isPaused);
}
void SoundManager::ChannelGroupMute(const Ogre::String &name, const bool &isMuted){
if(_channelGroupMap->count(name))
return;
_channelGroupMap->at(name)->setMute(isMuted);
}
void SoundManager::ChannelGroupMuteAll(const bool &isMuted){
for(_CGMitr = _channelGroupMap->begin(); _CGMitr != _channelGroupMap->end(); ++_CGMitr)
_CGMitr->second->setMute(isMuted);
}
void SoundManager::ChannelGroupVolume(const Ogre::String &name, const Ogre::Real &volume){
if(_channelGroupMap->count(name))
return;
_channelGroupMap->at(name)->setVolume(volume);
}
void SoundManager::ChannelGroupVolumeAll(const Ogre::Real &volume){
for(_CGMitr = _channelGroupMap->begin(); _CGMitr != _channelGroupMap->end(); ++_CGMitr)
_CGMitr->second->setVolume(volume);
}
void SoundManager::ChannelGroupStop(const Ogre::String &name){
if(!_channelGroupMap->count(name))
return;
_channelGroupMap->at(name)->stop();
}
void SoundManager::ChannelGroupStopAll(){
for(_CGMitr = _channelGroupMap->begin(); _CGMitr != _channelGroupMap->end(); ++_CGMitr)
_CGMitr->second->stop();
}
void SoundManager::ChannelGroupDestroy(const Ogre::String &name){
if(!_channelGroupMap->count(name) || !name.compare("MASTER"))
return;
this->ChannelGroupStop(name);
_channelGroupMap->at(name)->release();
_channelGroupMap->erase(name);
}
void SoundManager::ChannelGroupDestroyAll(){
this->ChannelGroupStopAll();
for(_CGMitr = _channelGroupMap->begin(); _CGMitr != _channelGroupMap->end(); ++_CGMitr){
if(!_CGMitr->first.compare("MASTER"))
continue;
_CGMitr->second->release();
}
_channelGroupMap->clear();
FMOD::ChannelGroup* channelGroup;
_system->getMasterChannelGroup(&channelGroup);
_channelGroupMap->insert(std::pair<const Ogre::String, FMOD::ChannelGroup*>("MASTER", channelGroup));
}
#pragma endregion
#pragma region channel
void SoundManager::ChannelPause(const int &index, const bool &isPaused){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->setPaused(isPaused);
}
void SoundManager::ChannelMute(const int &index, const bool &isMuted){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->setMute(isMuted);
}
void SoundManager::ChannelVolume(const int &index, const Ogre::Real &volume){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->setVolume(volume);
}
void SoundManager::ChannelLoop(const int &index, const int &loopCount){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->setLoopCount(loopCount);
}
void SoundManager::ChannelStop(const int &index){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->stop();
}
#pragma endregion
#pragma region channel3D
void SoundManager::Channel3DAttributes(const int &index, const Ogre::Vector3 &position, const Ogre::Vector3 &velocity){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
const FMOD_VECTOR posVec = {position.x, position.y, position.z},
velVec = {velocity.x * _timeSinceLastFrame,
velocity.y * _timeSinceLastFrame,
velocity.z * _timeSinceLastFrame};
channel->set3DAttributes(&posVec, &velVec);
}
void SoundManager::Channel3DConeOrientation(const int &index, const Ogre::Vector3 &orientation){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
FMOD_VECTOR orient = {orientation.normalisedCopy().x,
orientation.normalisedCopy().y,
orientation.normalisedCopy().z};
channel->set3DConeOrientation(&orient);
}
void SoundManager::Channel3DConeSettings(const int &index, const Ogre::Real &insideAngle, const Ogre::Real &outsideAngle,
const Ogre::Real &outsideVolume){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->set3DConeSettings(insideAngle, outsideAngle, outsideVolume);
}
void SoundManager::Channel3DDopplerLevel(const int &index, const Ogre::Real &level){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->set3DDopplerLevel(level);
}
void SoundManager::Channel3DMinMaxDistance(const int &index, const Ogre::Real &minDistance, const Ogre::Real &maxDistance){
FMOD::Channel* channel;
if(_system->getChannel(index, &channel) != FMOD_OK)
return;
channel->set3DMinMaxDistance(minDistance, maxDistance);
}
#pragma endregion
#pragma region playlist
void SoundManager::PlaylistPlay(const Ogre::String &playlistName){
if(!_playlistMap->count(playlistName))
return;
_playlistMap->at(playlistName)->Play();
}
void SoundManager::PlaylistPlayAll(){
for(_playlistItr = _playlistMap->begin(); _playlistItr != _playlistMap->end(); ++_playlistItr)
_playlistItr->second->Play();
}
void SoundManager::PlaylistSkip(const Ogre::String &playlistName){
if(!_playlistMap->count(playlistName))
return;
_playlistMap->at(playlistName)->Skip();
}
void SoundManager::PlaylistPause(const Ogre::String &playlistName){
if(!_playlistMap->count(playlistName))
return;
_playlistMap->at(playlistName)->Pause();
}
void SoundManager::PlaylistPauseAll(){
for(_playlistItr = _playlistMap->begin(); _playlistItr != _playlistMap->end(); ++_playlistItr)
_playlistItr->second->Pause();
}
void SoundManager::PlaylistResume(const Ogre::String &playlistName){
if(!_playlistMap->count(playlistName))
return;
_playlistMap->at(playlistName)->Resume();
}
void SoundManager::PlaylistResumeAll(){
for(_playlistItr = _playlistMap->begin(); _playlistItr != _playlistMap->end(); ++_playlistItr)
_playlistItr->second->Resume();
}
void SoundManager::PlaylistStop(const Ogre::String &playlistName){
if(!_playlistMap->count(playlistName))
return;
_playlistMap->at(playlistName)->Stop();
}
void SoundManager::PlatlistStopAll(){
for(_playlistItr = _playlistMap->begin(); _playlistItr != _playlistMap->end(); ++_playlistItr)
_playlistItr->second->Stop();
}
void SoundManager::PlaylistDestroy(const Ogre::String &playlistName){
if(!_playlistMap->count(playlistName))
return;
Sound2DPlaylist *playlist = _playlistMap->at(playlistName);
_playlistMap->erase(playlistName);
delete playlist;
}
void SoundManager::PlaylistDestroyAll(){
Sound2DPlaylist *playlist;
while(_playlistMap->begin() != _playlistMap->end()){
playlist = _playlistMap->begin()->second;
_playlistMap->erase(_playlistMap->begin()->first);
delete playlist;
}
}
#pragma endregion
#pragma region play
int SoundManager::Play2DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName){
if(!_2DsoundMap->count(soundName))
return -1;
int channelIndex;
FMOD::Channel* channel;
if(_system->playSound(FMOD_CHANNEL_FREE, _2DsoundMap->at(soundName)->_sound, false, &channel) != FMOD_OK)
return -1;
if(!_channelGroupMap->count(channelGroupName))
this->ChannelGroupCreate(channelGroupName);
channel->setChannelGroup(_channelGroupMap->at(channelGroupName));
channel->getIndex(&channelIndex);
return channelIndex;
}
int SoundManager::Play2DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName, const int &loopCount){
if(!_2DsoundMap->count(soundName))
return -1;
int channelIndex;
FMOD::Channel* channel;
if(_system->playSound(FMOD_CHANNEL_FREE, _2DsoundMap->at(soundName)->_sound, false, &channel) != FMOD_OK)
return -1;
if(!_channelGroupMap->count(channelGroupName))
this->ChannelGroupCreate(channelGroupName);
channel->setChannelGroup(_channelGroupMap->at(channelGroupName));
channel->setLoopCount(loopCount);
channel->getIndex(&channelIndex);
return channelIndex;
}
int SoundManager::Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position){
if(!_3DsoundMap->count(soundName))
return -1;
int channelIndex;
FMOD::Channel* channel;
if(_system->playSound(FMOD_CHANNEL_FREE, _3DsoundMap->at(soundName)->_sound, false, &channel) != FMOD_OK)
return -1;
if(!_channelGroupMap->count(channelGroupName))
this->ChannelGroupCreate(channelGroupName);
channel->setChannelGroup(_channelGroupMap->at(channelGroupName));
channel->getIndex(&channelIndex);
this->Channel3DAttributes(channelIndex, position, Ogre::Vector3(0.0f));
return channelIndex;
}
int SoundManager::Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const int &loopCount){
if(!_3DsoundMap->count(soundName))
return -1;
int channelIndex;
FMOD::Channel* channel;
if(_system->playSound(FMOD_CHANNEL_FREE, _3DsoundMap->at(soundName)->_sound, false, &channel) != FMOD_OK)
return -1;
if(!_channelGroupMap->count(channelGroupName))
this->ChannelGroupCreate(channelGroupName);
channel->setChannelGroup(_channelGroupMap->at(channelGroupName));
channel->setLoopCount(loopCount);
channel->getIndex(&channelIndex);
this->Channel3DAttributes(channelIndex, position, Ogre::Vector3(0.0f));
return channelIndex;
}
int SoundManager::Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Vector3 &forward){
if(!_3DsoundMap->count(soundName))
return -1;
int channelIndex;
FMOD::Channel* channel;
if(_system->playSound(FMOD_CHANNEL_FREE, _3DsoundMap->at(soundName)->_sound, false, &channel) != FMOD_OK)
return -1;
if(!_channelGroupMap->count(channelGroupName))
this->ChannelGroupCreate(channelGroupName);
channel->setChannelGroup(_channelGroupMap->at(channelGroupName));
channel->getIndex(&channelIndex);
this->Channel3DAttributes(channelIndex, position, velocity);
this->Channel3DConeOrientation(channelIndex, forward);
return channelIndex;
}
int SoundManager::Play3DSound(const Ogre::String &soundName, const Ogre::String &channelGroupName,
const Ogre::Vector3 &position, const Ogre::Vector3 &velocity, const Ogre::Vector3 &forward, const int &loopCount){
if(!_3DsoundMap->count(soundName))
return -1;
if(!_3DsoundMap->count(soundName))
return -1;
int channelIndex;
FMOD::Channel* channel;
if(_system->playSound(FMOD_CHANNEL_FREE, _3DsoundMap->at(soundName)->_sound, false, &channel) != FMOD_OK)
return -1;
if(!_channelGroupMap->count(channelGroupName))
this->ChannelGroupCreate(channelGroupName);
channel->setChannelGroup(_channelGroupMap->at(channelGroupName));
channel->setLoopCount(loopCount);
channel->getIndex(&channelIndex);
this->Channel3DAttributes(channelIndex, position, velocity);
this->Channel3DConeOrientation(channelIndex, forward);
return channelIndex;
}
#pragma endregion
{CODE}