Skip to main content

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}


        

History

Information Version
Thu 13 of Jan, 2011 02:17 GMT-0000 bmp410 19
Thu 13 of Jan, 2011 02:16 GMT-0000 bmp410 18
Thu 13 of Jan, 2011 02:13 GMT-0000 bmp410 17
Thu 13 of Jan, 2011 02:11 GMT-0000 bmp410 16
Thu 13 of Jan, 2011 02:11 GMT-0000 bmp410 15
Thu 13 of Jan, 2011 02:10 GMT-0000 bmp410 14
Thu 13 of Jan, 2011 02:07 GMT-0000 bmp410 13
Thu 13 of Jan, 2011 02:02 GMT-0000 bmp410 12
Thu 13 of Jan, 2011 02:00 GMT-0000 bmp410 11
Thu 13 of Jan, 2011 01:57 GMT-0000 bmp410 10
Thu 13 of Jan, 2011 01:57 GMT-0000 bmp410 9
Thu 13 of Jan, 2011 01:55 GMT-0000 bmp410 8
Thu 13 of Jan, 2011 01:52 GMT-0000 bmp410 7
Thu 13 of Jan, 2011 01:44 GMT-0000 bmp410 6
Thu 13 of Jan, 2011 01:39 GMT-0000 bmp410 5
Thu 13 of Jan, 2011 01:31 GMT-0000 bmp410 4
Thu 13 of Jan, 2011 01:21 GMT-0000 bmp410 3
Thu 13 of Jan, 2011 01:19 GMT-0000 bmp410 2
Thu 13 of Jan, 2011 01:18 GMT-0000 bmp410 1