History: Another FMOD SoundManager
Preview of version: 4
The interface
Copy to clipboard
#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; };
The header
Copy to clipboard
#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; }; };
Copy to clipboard
#include "SoundManager.h" 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, position.y * _timeSinceLastFrame, position.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, position.y * _timeSinceLastFrame, position.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, position.y * _timeSinceLastFrame, position.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, position.y * _timeSinceLastFrame, position.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