Here is my sound_manager class for my game:
sound_manager.h
Code: Select all
/*
This class is used for all sound management, 2D and 3D.
*/
#ifndef SOUND_MANAGER_H
#define SOUND_MANAGER_H
#include <iostream>
#include <cstdlib>
#include <irrlicht.h>
#include <bass.h>
using namespace std;
using namespace irr;
using namespace core;
using namespace video;
using namespace io;
using namespace scene;
using namespace gui;
HSTREAM createSoundHandle(IReadFile* snd, DWORD flags = 0); //This function creates an HSTREAM from the sound file in the .zip.
struct sound_instance_2d
{
sound_instance_2d(); //Constructor.
int soundID; //What sound is this?
int soundInstance; //What is the index of this sound in the sound manager?
HSTREAM handle; //The HSTREAM sound handle.
IReadFile* file_handle; //The handle to the read file.
bool loop; //Should this sound loop?
};
struct sound_instance_3d
{
sound_instance_3d(); //Constructor.
int soundID; //What sound is this?
int soundInstance; //What is the index of this sound in the sound manager?
HSTREAM handle; //The HSTREAM sound handle.
IReadFile* file_handle; //The handle to the read file.
ISceneNode* node; //The node to follow.
bool loop; //Should this sound loop?
};
class sound_manager
{
public:
//Constructor/Deconstructor
sound_manager(IrrlichtDevice* irrdv, float basevol);
~sound_manager();
//Routines
void update(); //Update the manager.
void loadSounds(); //Loads in all the sounds and music.
void unloadSounds(); //Unloads all the sounds.
int play2DSound(int id, float vol, bool loop); //Play a 2D sound.
int play3DSound(int id, ISceneNode* node, float dist, float vol, bool loop); //Play a 3D sound.
void stop2DSound(int id); //Stops a 2D sound.
void stop3DSound(int id); //Stops a 3D sound.
void stopAll2DSounds(); //Stops all 2D sounds.
void stopAll3DSounds(); //Stops all 3D sounds.
void stopAllSounds(); //Stops ALL sounds.
//Setters
void setMasterVolume(float vol); //Sets the master volume.
void setListenCamera(ICameraSceneNode* cam); //Sets the 3D listening camera.
//Getters
float getMasterVolume(); //Gets the master volume.
ICameraSceneNode* getListenCamera(); //Returns the 3D listening camera.
bool getAreSoundsLoaded(); //Returns whether or not sounds are loaded.
sound_instance_2d* get2DSoundInstance(int id); //Gets the 2D sound instance.
sound_instance_3d* get3DSoundInstance(int id); //Gets the 3D sound instance.
private:
IrrlichtDevice* irrdevice;
IFileSystem* irrio;
float master_volume; //Main volume.
ICameraSceneNode* listencam; //The camera where the 3D listener is.
bool sounds_loaded; //Are the sounds loaded in?
stringc sound_bank[100]; //The list of sounds, loaded into memory.
sound_instance_2d* sounds2d[100]; //List of currently playing 2D sounds.
sound_instance_3d* sounds3d[100]; //List of currently playing 3D sounds.
};
#endif
Code: Select all
#include "sound_manager.h"
using namespace std;
using namespace irr;
using namespace core;
using namespace video;
using namespace io;
using namespace scene;
using namespace gui;
HSTREAM createSoundHandle(IReadFile* snd, DWORD flags)
{
void* buffer = malloc(snd->getSize());
snd->read(buffer, snd->getSize());
HSTREAM tmp_snd = BASS_StreamCreateFile(true, buffer, 0, snd->getSize(), flags);
return tmp_snd;
}
sound_instance_2d::sound_instance_2d()
{
soundID = -1;
soundInstance = -1;
handle = 0;
file_handle = 0;
loop = false;
}
sound_instance_3d::sound_instance_3d()
{
soundID = -1;
soundInstance = -1;
handle = 0;
file_handle = 0;
node = 0;
loop = false;
}
sound_manager::sound_manager(IrrlichtDevice* irrdv, float basevol)
{
irrdevice = irrdv;
irrio = irrdevice->getFileSystem();
setMasterVolume(basevol);
listencam = 0;
sounds_loaded = false;
for(int i=0;i<100;i++)
{
sound_bank[i] = "";
sounds2d[i] = 0;
sounds3d[i] = 0;
}
BASS_3DVECTOR pos;
pos.x = 0;
pos.y = 0;
pos.z = 0;
BASS_Set3DPosition(&pos, &pos, &pos, &pos);
}
sound_manager::~sound_manager()
{
unloadSounds();
}
void sound_manager::update()
{
if(sounds_loaded)
{
for(int i=0;i<100;i++)
{
//2D
if(sounds2d[i])
{
HSTREAM whndle = sounds2d[i]->handle;
if(BASS_ChannelGetPosition(whndle, BASS_POS_BYTE) == BASS_ChannelGetLength(whndle, BASS_POS_BYTE))
{
if(sounds2d[i]->loop)
{
BASS_ChannelPlay(whndle, true);
}
else
{
stop2DSound(i);
}
}
}
//Handle listener.
if(listencam)
{
vector3df cpos = listencam->getAbsolutePosition();
vector3df ctargpos = listencam->getTarget();
vector3df cup = listencam->getUpVector();
BASS_3DVECTOR pos, targ, up;
pos.x = cpos.X;
pos.y = cpos.Y;
pos.z = cpos.Z;
targ.x = ctargpos.X;
targ.y = ctargpos.Y;
targ.z = ctargpos.Z;
up.x = cup.X;
up.y = cup.Y;
up.z = cup.Z;
BASS_Set3DPosition(&pos, 0, &targ, &up);
}
else
{
BASS_3DVECTOR pos;
pos.x = 0;
pos.y = 0;
pos.z = 0;
BASS_Set3DPosition(&pos, &pos, &pos, &pos);
}
//3D
if(sounds3d[i])
{
HSTREAM whndle = sounds3d[i]->handle;
BASS_3DVECTOR tmpps;
tmpps.x = sounds3d[i]->node->getAbsolutePosition().X;
tmpps.y = sounds3d[i]->node->getAbsolutePosition().Y;
tmpps.z = sounds3d[i]->node->getAbsolutePosition().Z;
BASS_ChannelSet3DPosition(whndle, &tmpps, 0, 0);
if(BASS_ChannelGetPosition(whndle, BASS_POS_BYTE) == BASS_ChannelGetLength(whndle, BASS_POS_BYTE))
{
if(sounds3d[i]->loop)
{
BASS_ChannelPlay(whndle, true);
}
else
{
stop3DSound(i);
}
}
}
}
BASS_Apply3D();
}
}
void sound_manager::loadSounds()
{
if(!sounds_loaded)
{
sound_bank[0] = "menumusic.mp3";
sound_bank[1] = "button_click.mp3";
sound_bank[2] = "button_hover.mp3";
sound_bank[3] = "forestambience.mp3";
sound_bank[4] = "monsterspot.mp3";
sound_bank[5] = "monsterchasemusic.mp3";
sound_bank[6] = "creditsmusic.mp3";
sound_bank[7] = "pony_walking.mp3";
sound_bank[8] = "pony_running.mp3";
sounds_loaded = true;
}
}
void sound_manager::unloadSounds()
{
if(sounds_loaded)
{
stopAllSounds();
for(int i=0;i<100;i++)
{
if(sound_bank[i] != "")
{
sound_bank[i] = "";
}
}
sounds_loaded = false;
}
}
int sound_manager::play2DSound(int id, float vol, bool loop)
{
int slot_num = -1;
if(sounds_loaded && sound_bank[id] != "")
{
if(vol >= 0 && vol <= 1)
{
for(int i=0;i<100;i++)
{
if(!sounds2d[i])
{
slot_num = i;
sounds2d[i] = new sound_instance_2d();
sounds2d[i]->soundID = id;
sounds2d[i]->soundInstance = i;
sounds2d[i]->loop = loop;
sounds2d[i]->file_handle = irrio->createAndOpenFile(sound_bank[id].c_str());
sounds2d[i]->handle = createSoundHandle(sounds2d[i]->file_handle);
float newvol = vol;
if(newvol > master_volume)
{
newvol = master_volume;
}
else
{
newvol = vol * master_volume;
}
BASS_ChannelSetAttribute(sounds2d[i]->handle, BASS_ATTRIB_VOL, newvol);
BASS_ChannelPlay(sounds2d[i]->handle, true);
break;
}
}
}
}
return slot_num;
}
int sound_manager::play3DSound(int id, ISceneNode* node, float dist, float vol, bool loop)
{
int slot_num = -1;
if(sounds_loaded && sound_bank[id] != "")
{
if(vol >= 0 && vol <= 1)
{
for(int i=0;i<100;i++)
{
if(!sounds3d[i])
{
slot_num = i;
sounds3d[i] = new sound_instance_3d();
sounds3d[i]->soundID = id;
sounds3d[i]->soundInstance = i;
sounds3d[i]->loop = loop;
sounds3d[i]->node = node;
sounds3d[i]->file_handle = irrio->createAndOpenFile(sound_bank[id].c_str());
sounds3d[i]->handle = createSoundHandle(sounds3d[i]->file_handle, BASS_SAMPLE_3D);
BASS_3DVECTOR tmpps;
tmpps.x = node->getAbsolutePosition().X;
tmpps.y = node->getAbsolutePosition().Y;
tmpps.z = node->getAbsolutePosition().Z;
BASS_ChannelSet3DAttributes(sounds3d[i]->handle, -1, dist, 0, 360, 360, 0);
BASS_ChannelSet3DPosition(sounds3d[i]->handle, &tmpps, 0, 0);
float newvol = vol;
if(newvol > master_volume)
{
newvol = master_volume;
}
else
{
newvol = vol * master_volume;
}
BASS_ChannelSetAttribute(sounds3d[i]->handle, BASS_ATTRIB_VOL, newvol);
BASS_ChannelPlay(sounds3d[i]->handle, true);
break;
}
}
}
}
return slot_num;
}
void sound_manager::stop2DSound(int id)
{
if(sounds_loaded)
{
if(sounds2d[id])
{
BASS_ChannelStop(sounds2d[id]->handle);
BASS_StreamFree(sounds2d[id]->handle);
sounds2d[id]->file_handle->drop();
sounds2d[id] = 0;
}
}
}
void sound_manager::stop3DSound(int id)
{
if(sounds_loaded)
{
if(sounds3d[id])
{
BASS_ChannelStop(sounds3d[id]->handle);
BASS_StreamFree(sounds3d[id]->handle);
sounds3d[id]->file_handle->drop();
sounds3d[id] = 0;
}
}
}
void sound_manager::stopAll2DSounds()
{
for(int i=0;i<100;i++)
{
stop2DSound(i);
}
}
void sound_manager::stopAll3DSounds()
{
for(int i=0;i<100;i++)
{
stop3DSound(i);
}
}
void sound_manager::stopAllSounds()
{
stopAll2DSounds();
stopAll3DSounds();
}
void sound_manager::setMasterVolume(float vol)
{
if(vol >= 0 && vol <= 1)
{
master_volume = vol;
}
}
void sound_manager::setListenCamera(ICameraSceneNode* cam)
{
listencam = cam;
}
float sound_manager::getMasterVolume()
{
return master_volume;
}
ICameraSceneNode* sound_manager::getListenCamera()
{
return listencam;
}
bool sound_manager::getAreSoundsLoaded()
{
return sounds_loaded;
}
sound_instance_2d* sound_manager::get2DSoundInstance(int id)
{
return sounds2d[id];
}
sound_instance_3d* sound_manager::get3DSoundInstance(int id)
{
return sounds3d[id];
}