One of my responsibilities during my final project at Full Sail was to wrap an OpenAL implementation to use sound files. We used OGG Vorbis and Wave files, so I wrote a system that would give us only the power that we needed, as my responsibilities were stretched across the board. This included a SoundManager which contained instances of the Sound class and StreamingSound class through the ISound interface. The SoundManager was the entry point into the sound system and could Load, Play, Stop, and Fade sounds and was responsible for Initializing the Device.
CSoundManager.cpp
- ///////////////////////////////////////////////////////////////////////////////
- // Name : CSoundManager.cpp
- //
- // Date : 2007.02.08
- //
- // Purpose : Maintains the creation of all of the Sound objects in the game.
- ///////////////////////////////////////////////////////////////////////////////
- #include "../../../Engine/Header/sound/CSoundManager.h"
- #include "../../../Libs/OpenAL/al.h"
- #include "../../../Libs/OpenAL/alc.h"
- #include "../../../Engine/Header/Sound/CWavLoader.h"
- #include "../../../Engine/Header/Sound/COggLoader.h"
- #include "../../../Engine/Header/Sound/CSound.h"
- #include "../../../Engine/Header/Sound/CStreamingSound.h"
- #include "../../../Engine/Header/Errors.h"
- #include "../../../Engine/Header/Enums.h"
- #include "../../../Engine/Header/MessageEnums.h"
- #include "../../../Engine/Header/Core/CMessageFactory.h"
- #include "../../../Engine/Header/Core/CStaticEntity3D.h"
- #include "../../../Engine/Header/Core/tVector3d.h"
- #include "../../../Engine/Header/Core/tMatrix4.h"
- #pragma comment (lib, "Libs/OpenAL32.lib")
- #define MAX_CHANNELS 64
- IL::SOUND::CSoundManager* IL::SOUND::CSoundManager::m_pOnlyInstance = 0;
- //////////////////////////////////////////////////////////////////////////
- // Name : clear
- //
- // Date : 2007.02.08
- //
- // Author : Chad Stewart
- //
- // Purpose : Frees all allocated memory and returns the object to its
- // default state.
- //////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::clear()
- {
- ALCdevice* pDevice;
- ALCcontext* pContext;
- unsigned int Size = 0;
- // Delete all of the sounds.
- clearSounds();
- // Delete all of the unused sounds.
- Size = (unsigned int)m_UnusedSounds.size();
- for ( unsigned int i = 0; i < Size; i++ )
- delete m_UnusedSounds[i];
- m_UnusedSounds.clear();
- // Delete all of the sounds.
- Size = (unsigned int)m_UnusedStreams.size();
- for ( unsigned int i = 0; i < Size; i++ )
- delete m_UnusedStreams[i];
- m_UnusedStreams.clear();
- // Delete all of the channels.
- Size = (unsigned int)m_vSoundChannels.size();
- for ( unsigned int i = 0; i < Size; i++ )
- alDeleteSources(1, (ALuint*)&m_vSoundChannels[i].m_SourceID);
- m_vSoundChannels.clear();
- Size = (unsigned int)m_vSoundBuffers.size();
- for ( unsigned int i = 0; i < Size; i++ )
- alDeleteBuffers(1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
- m_vSoundBuffers.clear();
- // Exit
- pContext = alcGetCurrentContext();
- pDevice = alcGetContextsDevice(pContext);
- alcMakeContextCurrent(0);
- alcDestroyContext(pContext);
- alcCloseDevice(pDevice);
- // If you haven't initialized, you're going to be a jerk and call new just to delete.
- IL::SOUND::CWavLoader::getInstance()->deleteInstance();
- IL::SOUND::COggLoader::getInstance()->deleteInstance();
- }
- //////////////////////////////////////////////////////////////////////////
- // Name : getInstance
- //////////////////////////////////////////////////////////////////////////
- IL::SOUND::CSoundManager * IL::SOUND::CSoundManager::getInstance()
- {
- if (!m_pOnlyInstance)
- {
- m_pOnlyInstance = new IL::SOUND::CSoundManager;
- }
- return m_pOnlyInstance;
- }
- //////////////////////////////////////////////////////////////////////////
- // Name : deleteInstance
- //////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::deleteInstance()
- {
- if (m_pOnlyInstance)
- {
- delete m_pOnlyInstance;
- }
- m_pOnlyInstance = 0;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : initialize
- //
- // Date : 2007.02.12
- //
- // Author : Chad Stewart
- //
- // Purpose : Set up OpenAL
- ///////////////////////////////////////////////////////////////////////////////
- ILENUM IL::SOUND::CSoundManager::initialize(void)
- {
- // Device and Context required!
- ALCdevice* pDevice = 0;
- ALCcontext* pContext = 0;
- ALboolean m_EAX = AL_FALSE;
- ALfloat ListenerPosition[] = { 0.0f, 0.0f, 0.0f };
- ALfloat ListenerVelocity[] = { 0.0f, 0.0f, 0.0f };
- ALfloat ListenerOrientation[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
- IL::CORE::ILVECTOR3DF* pListenerPositionToUse = NULL;
- IL::CORE::tMatrix4<float>* pListenerOrientationToUse = NULL;
- tChannel IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector;
- ILINT i = 0;
- // We'll need to have our Loaders in order to begin.
- IL::SOUND::CWavLoader::getInstance();
- IL::SOUND::COggLoader::getInstance();
- // Acquire us an open sound device.
- pDevice = alcOpenDevice(NULL);
- // If we have the device now, let's create our context.
- if (pDevice)
- {
- pContext = alcCreateContext(pDevice, 0);
- if (NULL == pContext || !alcMakeContextCurrent(pContext))
- return IL::EEC_CANNOT_CREATE_AL_CONTEXT;
- }
- else
- return IL::EEC_CANNOT_CREATE_AL_DEVICE;
- // Check for EAX 2.0 support
- // m_EAX = alIsExtensionPresent("EAX2.0");
- alDistanceModel(AL_EXPONENT_DISTANCE);
- // Place the listener.
- alListenerfv(AL_POSITION, ListenerPosition);
- alListenerfv(AL_VELOCITY, ListenerVelocity);
- alListenerfv(AL_ORIENTATION, ListenerOrientation);
- alListenerf(AL_GAIN, 1.0f);
- // This channel is not in use... yet.
- IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector.m_InUse = false;
- // Create all the sources.
- do
- {
- // Create a source.
- alGenSources(1, (ALuint*)&IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector.m_SourceID);
- // Make sure that source worked.
- if(AL_NO_ERROR != alGetError())
- break;
- // Hell yeah, in the vector.
- m_vSoundChannels.push_back(IUseThisChannelToGenerateAllOfTheChannelsThatArePutInTheM_vSoundChannelsVector);
- } while (i++ < MAX_CHANNELS);
- return IL::EEC_OK;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : changeDevice
- ///////////////////////////////////////////////////////////////////////////////
- ILENUM IL::SOUND::CSoundManager::changeDevice(const char* vDeviceName)
- {
- ILUINT VectorSize = 0;
- ILUINT Size = 0;
- ILUINT SoundID = 0;
- ILUINT j = 0;
- ALCdevice* pDevice = 0;
- ALCcontext* pContext = 0;
- ALCchar Buffer[256] = {0};
- std::vector<ILINT> vPausedSounds;
- vPausedSounds = pauseAllSounds(true);
- pContext = alcGetCurrentContext();
- pDevice = alcGetContextsDevice( pContext );
- // Close that stuff.
- alcDestroyContext(pContext);
- alcCloseDevice(pDevice);
- pDevice = NULL;
- pContext = NULL;
- // Acquire us an open sound device.
- pDevice = alcOpenDevice((ALCchar*)vDeviceName);
- // If we have the device now, let's create our context.
- if (pDevice)
- {
- pContext = alcCreateContext(pDevice, 0);
- if (NULL == pContext || !alcMakeContextCurrent(pContext))
- return IL::EEC_CANNOT_CREATE_AL_CONTEXT;
- }
- else
- return IL::EEC_CANNOT_CREATE_AL_DEVICE;
- // We created a new device. Re-load all of the sources and buffers.
- // First we will loop through the sounds and re-load them.
- VectorSize = (ILUINT)m_Sounds.size();
- for (unsigned int i = 0; i < VectorSize; i++)
- m_Sounds[i]->reloadSound();
- // Channels.
- VectorSize = (ILUINT)m_vSoundChannels.size();
- for (unsigned int i = 0; i < VectorSize; i++)
- {
- // Did we already free the channel?
- if (!m_vSoundChannels[i].m_InUse)
- {
- alDeleteSources(1, (ALuint*)&m_vSoundChannels[i].m_SourceID);
- alGenSources(1, (ALuint*)&m_vSoundChannels[i].m_SourceID);
- }
- }
- // Buffers.
- VectorSize = (ILUINT)m_vSoundBuffers.size();
- for (unsigned int i = 0; i < VectorSize; i++)
- {
- // Would this buffer have already re-loaded?
- if (m_vSoundBuffers[i].m_References == 0)
- {
- alDeleteBuffers( 1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
- alGenBuffers( 1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
- }
- }
- // And now un-pause all of the songs.
- VectorSize = (ILUINT)vPausedSounds.size();
- Size = (ILUINT)m_Sounds.size();
- for (unsigned int i = 0; i < VectorSize; i++)
- {
- SoundID = vPausedSounds[i];
- for (j = 0; j < Size; j++)
- {
- if (m_Sounds[j]->getUniqueID() == SoundID)
- {
- m_Sounds[j]->unpauseSound();
- break;
- }
- }
- }
- return IL::EEC_OK;
- }
- //////////////////////////////////////////////////////////////////////////
- // Name : handleMessage
- //////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::handleMessage(const IL::CORE::tMessage * vMessage)
- {
- ILINT MessageData = -1;
- unsigned int Size = 0;
- // Handle ALL the messages we can.
- switch (vMessage->m_OpCode)
- {
- // Specified play channel can be used by someone else.
- case IL::EMSG_FREE_CHANNEL:
- if (-1 != (MessageData = vMessage->m_Data))
- m_vSoundChannels[MessageData].m_InUse = false;
- break;
- // A sound has run it's course and wishes to make benefit glorious sound system.
- case IL::EMSG_RECYCLE_SOUND:
- if (IL::EID_INVALID != (MessageData = vMessage->m_Data))
- {
- recycleSound(MessageData);
- }
- break;
- // A sound is done with a buffer.
- case IL::EMSG_FREE_BUFFER:
- if (-1 != (MessageData = vMessage->m_Data))
- {
- Size = (unsigned int)m_vSoundBuffers.size();
- for (unsigned int i = 0; i < Size; i++)
- if (m_vSoundBuffers[i].m_BufferID == MessageData)
- {
- m_vSoundBuffers[i].m_References--;
- if (m_vSoundBuffers[i].m_References == 0)
- {
- alDeleteBuffers(1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
- alGetError();
- alGenBuffers(1, (ALuint*)&m_vSoundBuffers[i].m_BufferID);
- }
- }
- }
- break;
- // A sound is done with a buffer.
- case IL::EMSG_ADD_BUFFER_REF:
- if (-1 != (MessageData = vMessage->m_Data))
- {
- Size = (unsigned int)m_vSoundBuffers.size();
- for (unsigned int i = 0; i < Size; i++)
- if (m_vSoundBuffers[i].m_BufferID == MessageData)
- m_vSoundBuffers[i].m_References++;
- }
- break;
- default:
- break;
- };
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : getFreeSound
- ///////////////////////////////////////////////////////////////////////////////
- IL::SOUND::CSound* IL::SOUND::CSoundManager::getFreeSound(void)
- {
- IL::SOUND::CSound* ReturnSound = NULL;
- if (m_UnusedSounds.size() != 0)
- {
- ReturnSound = m_UnusedSounds.back();
- m_UnusedSounds.pop_back();
- }
- else
- ReturnSound = new IL::SOUND::CSound;
- return ReturnSound;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : loadSoundFromFile
- ///////////////////////////////////////////////////////////////////////////////
- ILINT IL::SOUND::CSoundManager::loadSoundFromFile(const ILCHAR* vFilename, ILBOOL vStream)
- {
- ISound* NewSound;
- unsigned int Size = (unsigned int)m_Sounds.size();
- IL::CORE::CString PassThisStringIntoTheSetFileNameFunction;
- PassThisStringIntoTheSetFileNameFunction = vFilename;
- if (vFilename == NULL)
- return IL::EID_INVALID;
- // Check the names.
- for (unsigned int i = 0; i < Size; i++)
- {
- if (0 == _stricmp(vFilename, m_Sounds[i]->getFileName().asMultiByteString()))
- return m_Sounds[i]->getUniqueID();
- }
- if (vStream)
- {
- // Take a sound from the factory, or create a new one.
- if (!m_UnusedStreams.empty())
- {
- // Grab it from the vector.
- NewSound = m_UnusedStreams[m_UnusedStreams.size()-1];
- m_UnusedStreams.pop_back();
- }
- else
- NewSound = new CStreamingSound;
- }
- else
- {
- // Take a sound from the factory, or create a new one.
- if (!m_UnusedSounds.empty())
- {
- // Grab it from the vector.
- NewSound = (IL::SOUND::CSound*)m_UnusedSounds[m_UnusedSounds.size()-1];
- m_UnusedSounds.pop_back();
- }
- else
- NewSound = new CSound;
- ((IL::SOUND::CSound*)NewSound)->setBufferID(getFreeBufferi());
- }
- // Did they pass in a file name?
- if (IL::EEC_OK != NewSound->loadSoundFromFile(vFilename))
- {
- delete NewSound;
- return IL::EID_INVALID;
- }
- // Put it in the vector.
- m_Sounds.push_back(NewSound);
- NewSound->setFileName(PassThisStringIntoTheSetFileNameFunction);
- NewSound->setUniqueID(++m_UniqueIDGenerator);
- return m_UniqueIDGenerator;
- }
- ILINT IL::SOUND::CSoundManager::loadSoundFromFile(const ILWCHAR* vFilename, ILBOOL vStream)
- {
- ISound* NewSound;
- unsigned int Size = (unsigned int)m_Sounds.size();
- IL::CORE::CString PassThisStringIntoTheSetFileNameFunction(vFilename);
- // Did they pass in a file name?
- if (vFilename == NULL)
- return IL::EID_INVALID;
- // Check the names.
- for (unsigned int i = 0; i < Size; i++)
- {
- if (wcsicmp(vFilename, m_Sounds[i]->getFileName().asWideCharacterString()))
- return m_Sounds[i]->getUniqueID();
- }
- if (vStream)
- {
- // Take a sound from the factory, or create a new one.
- if (!m_UnusedStreams.empty())
- {
- // Grab it from the vector.
- NewSound = m_UnusedStreams[m_UnusedStreams.size()-1];
- m_UnusedStreams.pop_back();
- }
- else
- NewSound = new CStreamingSound;
- }
- else
- {
- // Take a sound from the factory, or create a new one.
- if (!m_UnusedSounds.empty())
- {
- // Grab it from the vector.
- NewSound = m_UnusedSounds[m_UnusedSounds.size()-1];
- m_UnusedSounds.pop_back();
- }
- else
- NewSound = new CSound;
- ((IL::SOUND::CSound*)NewSound)->setBufferID(getFreeBufferi());
- }
- if (IL::EEC_OK != NewSound->loadSoundFromFile(vFilename))
- {
- delete NewSound;
- return IL::EID_INVALID;
- }
- // Put it in the vector.
- m_Sounds.push_back(NewSound);
- NewSound->setFileName(PassThisStringIntoTheSetFileNameFunction);
- NewSound->setUniqueID(++m_UniqueIDGenerator);
- return m_UniqueIDGenerator;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : playSound
- //
- // Date : 2007.02.16
- //
- // Author : Chad Stewart
- //
- // Purpose : Plays the sound specified.
- //
- // Note : Returns the ID of the song if it is played correctly. Otherwise,
- // it is -1 for an error.
- ///////////////////////////////////////////////////////////////////////////////
- ILINT IL::SOUND::CSoundManager::playSound(ILINT vID, ILENUM vPlayMode, ILFLOAT vFadeInLength, ILFLOAT vMaxVolume,
- ILFLOAT vFadeOutLength, ILFLOAT vFadeOutStartTime, ILFLOAT vReferenceDistance)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- ISound* NewSound = NULL;
- ILINT CloneID = 0;
- ILINT ChannelID = 0;
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- if ((IL::ESPM_OVERLAP & vPlayMode) && (IL::ESPM_POSITIONAL & vPlayMode))
- {
- if (-1 != (ChannelID = getFreeChannel()))
- {
- CloneID = cloneSound(i, &NewSound);
- m_Sounds[CloneID]->setPlayChannel(ChannelID);
- m_Sounds[CloneID]->setSourceID(m_vSoundChannels[ChannelID].m_SourceID);
- if (m_Sounds[CloneID]->playSound(vPlayMode, vFadeInLength, vMaxVolume, vFadeOutLength, vFadeOutStartTime, vReferenceDistance))
- return m_Sounds[CloneID]->getUniqueID();
- else
- {
- recycleSound(m_Sounds[CloneID]);
- return -1;
- }
- }
- }
- else
- {
- if (-1 != m_Sounds[i]->getPlayChannel())
- m_Sounds[i]->playSound(vPlayMode, vFadeInLength, vMaxVolume, vFadeOutLength, vFadeOutStartTime, vReferenceDistance);
- else if (-1 != (ChannelID = getFreeChannel()))
- {
- m_Sounds[i]->setPlayChannel(ChannelID);
- m_Sounds[i]->setSourceID(m_vSoundChannels[ChannelID].m_SourceID);
- if (IL::EID_INVALID != m_Sounds[i]->playSound(vPlayMode, vFadeInLength, vMaxVolume, vFadeOutLength, vFadeOutStartTime, vReferenceDistance))
- return m_Sounds[i]->getUniqueID();
- else
- {
- m_vSoundChannels[ChannelID].m_InUse = false;
- m_Sounds[i]->setPlayChannel(-1);
- m_Sounds[i]->setSourceID(0);
- return -1;
- }
- }
- }
- }
- // Error. Invalid ID.
- return -1;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : stopSound
- //
- // Date : 2007.02.26
- //
- // Author : Chad Stewart
- //
- // Purpose : Stop a currently playing sound.
- ///////////////////////////////////////////////////////////////////////////////
- ILBOOL IL::SOUND::CSoundManager::stopSound(ILINT vID)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- if (-1 != m_Sounds[i]->getPlayChannel())
- {
- m_Sounds[i]->stopSound();
- m_vSoundChannels[m_Sounds[i]->getPlayChannel()].m_InUse = false;
- m_Sounds[i]->setPlayChannel(-1);
- m_Sounds[i]->setSourceID(0);
- return true;
- }
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : pauseSound
- //
- // Date : 2007.02.26
- //
- // Author : Chad Stewart
- //
- // Purpose : Pause a currently playing sound.
- ///////////////////////////////////////////////////////////////////////////////
- ILBOOL IL::SOUND::CSoundManager::pauseSound(ILINT vID)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- return m_Sounds[i]->pauseSound();
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : pauseSound
- //
- // Date : 2007.02.26
- //
- // Author : Chad Stewart
- //
- // Purpose : Pause a currently playing sound.
- ///////////////////////////////////////////////////////////////////////////////
- ILBOOL IL::SOUND::CSoundManager::unpauseSound(ILINT vID)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- return m_Sounds[i]->unpauseSound();
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : update
- //
- // Date : 2007.02.17
- //
- // Author : Chad Stewart
- //
- // Purpose : Update all of the sounds contained in the manager.
- ///////////////////////////////////////////////////////////////////////////////
- ILBOOL IL::SOUND::CSoundManager::update(ILFLOAT vEllapsedTime, IL::CORE::CStaticEntity3D* vListener)
- {
- IL::CORE::ILVECTOR3DF ListenerPosition(0.0f, 0.0f, 0.0f);
- IL::CORE::ILVECTOR3DF ListenerVelocity(0.0f, 0.0f, 0.0f);
- IL::CORE::tMatrix4<float> ListenerOrientation(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
- 0.0f, 0.0f, -1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
- ALfloat Orientation[] = { 0.0f, 0.0f, -1.0f, 0.0f, 1.0f, 0.0f };
- unsigned int Size = 0;
- // Listener != Origin?
- if(vListener)
- {
- // Get the listener data.
- ListenerPosition = vListener->getPosition();
- ListenerOrientation = vListener->getOrientation();
- // Put the orientation in a format we can use.
- Orientation[0] = ListenerOrientation[8];
- Orientation[1] = ListenerOrientation[9];
- Orientation[2] = ListenerOrientation[10];
- Orientation[3] = ListenerOrientation[4];
- Orientation[4] = ListenerOrientation[5];
- Orientation[5] = ListenerOrientation[6];
- }
- // Update the listener. // Now slower! Yay!
- alListener3f(AL_POSITION, ListenerPosition.x, ListenerPosition.y, ListenerPosition.z);
- alListener3f(AL_VELOCITY, ListenerVelocity.x, ListenerVelocity.y, ListenerVelocity.z);
- alListenerfv(AL_ORIENTATION, Orientation);
- // For every sound.
- Size = (unsigned int)m_Sounds.size();
- for(unsigned int i = 0; i < Size; i++)
- {
- if (IL::EID_INVALID != m_Sounds[i]->getPlayChannel())
- m_Sounds[i]->update(vEllapsedTime);
- }
- return true;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : fadeSoundOut
- //
- // Date : 2007.03.10
- //
- // Author : Chad Stewart
- //
- // Purpose : Fade a sound out.
- ///////////////////////////////////////////////////////////////////////////////
- ILBOOL IL::SOUND::CSoundManager::fadeSoundOut(ILINT vID, ILFLOAT vFadeOutLength, ILFLOAT vFadeOutStartTime)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- // Make sure that said sound is playing.
- if (-1 != m_Sounds[i]->getPlayChannel())
- return m_Sounds[i]->fadeSoundOut(vFadeOutLength, vFadeOutStartTime);
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : crossFadeSounds
- //
- // Date : 2007.03.10
- //
- // Author : Chad Stewart
- //
- // Purpose : Fades one sound out while another sound is introduced.
- ///////////////////////////////////////////////////////////////////////////////
- ILBOOL IL::SOUND::CSoundManager::crossFadeSounds(ILINT vFirstID, ILFLOAT vFadeOutLength, ILINT vSecondID,
- ILFLOAT vFadeInLength, ILENUM vPlayMode, ILFLOAT vReferenceDistance)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- ILINT ChannelID = 0;
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vFirstID)
- {
- // For every sound in the manager, check for a valid ID.
- for (unsigned int j = 0; j < Size; j++)
- if(m_Sounds[j]->getUniqueID() == vSecondID)
- {
- // Make sure that said sound is playing.
- if (-1 != m_Sounds[i]->getPlayChannel())
- m_Sounds[i]->fadeSoundOut(vFadeOutLength, 0.0f);
- if (-1 != (ChannelID = getFreeChannel()))
- {
- m_Sounds[i]->setPlayChannel(ChannelID);
- m_Sounds[i]->setSourceID(m_vSoundChannels[ChannelID].m_SourceID);
- if (!m_Sounds[i]->playSound(vPlayMode, vFadeInLength, 0.0f, 0.0f, vReferenceDistance))
- {
- m_Sounds[i]->setPlayChannel(-1);
- m_Sounds[i]->setSourceID(0);
- m_vSoundChannels[ChannelID].m_InUse = false;
- return false;
- }
- return true;
- }
- }
- }
- return false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : deleteSound
- //
- // Date : 2007.02.19
- //
- // Author : Chad Stewart
- //
- // Purpose : Completely trod all over the functionality of the factory. :(
- ///////////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::deleteSound(ILINT vID)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- // Is the song occupying a channel?
- if (-1 != m_Sounds[i]->getPlayChannel())
- {
- m_Sounds[i]->stopSound();
- m_vSoundChannels[m_Sounds[i]->getPlayChannel()].m_InUse = false;
- m_Sounds[i]->setPlayChannel(-1);
- m_Sounds[i]->setSourceID(0);
- }
- delete m_Sounds[i];
- m_Sounds.erase(m_Sounds.begin() + i);
- break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : clearSounds
- //
- // Date : 2007.02.19
- //
- // Author : Chad Stewart
- //
- // Purpose : If delete wasn't bad enough, you can clear them all.
- ///////////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::clearSounds(void)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // Delete all of the sounds.
- for ( unsigned int i = 0; i < Size; i++ )
- delete m_Sounds[i];
- m_Sounds.clear();
- // Set all of the channels to being not in use.
- Size = (unsigned int)m_vSoundChannels.size();
- for (unsigned int i = 0; i < Size; i++)
- m_vSoundChannels[i].m_InUse = false;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : stopAllSounds
- ///////////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::stopAllSounds(void)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- for (unsigned int i = 0; i < Size; i++)
- {
- if (-1 != m_Sounds[i]->getPlayChannel() && m_Sounds[i]->stopSound())
- {
- m_vSoundChannels[m_Sounds[i]->getPlayChannel()].m_InUse = false;
- m_Sounds[i]->setPlayChannel(-1);
- m_Sounds[i]->setSourceID(0);
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : pauseAllSounds
- ///////////////////////////////////////////////////////////////////////////////
- vector<ILINT>& IL::SOUND::CSoundManager::pauseAllSounds(ILBOOL vSavePlayingSoundsIDs)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- static vector<ILINT> SoundIDs;
- if (vSavePlayingSoundsIDs)
- {
- SoundIDs.clear();
- for (unsigned int i = 0; i < Size; i++)
- {
- if (m_Sounds[i]->isPlaying())
- {
- SoundIDs.push_back(m_Sounds[i]->getUniqueID());
- m_Sounds[i]->pauseSound();
- }
- }
- }
- else
- for (unsigned int i = 0; i < Size; i++)
- m_Sounds[i]->pauseSound();
- return SoundIDs;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : recycleSound
- //
- // Date : 2007.02.17
- //
- // Author : Chad Stewart
- //
- // Purpose : Clears the sound and puts it in the list for re-use.
- ///////////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::recycleSound(ILINT vID)
- {
- ISound* SoundToRecycle;
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- // Sound or stream?
- if(m_Sounds[i]->isStream())
- SoundToRecycle = (CStreamingSound*)m_Sounds[i];
- else
- SoundToRecycle = (CSound*)m_Sounds[i];
- m_Sounds.erase(m_Sounds.begin() + i);
- break;
- }
- // Is the song occupying a channel?
- if (-1 != SoundToRecycle->getPlayChannel())
- {
- m_vSoundChannels[SoundToRecycle->getPlayChannel()].m_InUse = false;
- SoundToRecycle->setPlayChannel(-1);
- SoundToRecycle->setSourceID(0);
- }
- // Clear the sound for re-use.
- SoundToRecycle->clear();
- // Add it to the list of unused sounds.
- if(SoundToRecycle->isStream())
- m_UnusedStreams.push_back((CStreamingSound*)SoundToRecycle);
- else
- m_UnusedSounds.push_back((CSound*)SoundToRecycle);
- }
- void IL::SOUND::CSoundManager::recycleSound(ISound* vSound)
- {
- ILINT UniqueID = vSound->getUniqueID();
- unsigned int Size = (unsigned int)m_Sounds.size();
- unsigned int i = 0;
- // For every sound in the manager, check for a valid ID.
- for (i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == UniqueID)
- {
- m_Sounds.erase(m_Sounds.begin() + i);
- break;
- }
- if (i == Size)
- return;
- // Is the song occupying a channel?
- if (-1 != vSound->getPlayChannel())
- {
- m_vSoundChannels[vSound->getPlayChannel()].m_InUse = false;
- vSound->setPlayChannel(-1);
- vSound->setSourceID(0);
- }
- // Clear the sound for re-use.
- vSound->clear();
- // Add it to the list of unused sounds.
- if(vSound->isStream())
- m_UnusedStreams.push_back((CStreamingSound*)vSound);
- else
- m_UnusedSounds.push_back((CSound*)vSound);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : getSound
- //
- // Date : 2007.02.22
- //
- // Author : Chad Stewart
- //
- // Purpose : Return a sound by ID.
- ///////////////////////////////////////////////////////////////////////////////
- IL::SOUND::ISound* IL::SOUND::CSoundManager::getSound(ILINT vID)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->addReference();
- return m_Sounds[i];
- }
- return NULL;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Accessors
- ///////////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::getPosition(ILINT vID, IL::CORE::ILVECTOR3DF& vPosition) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->getPosition(vPosition);
- break;
- }
- }
- void IL::SOUND::CSoundManager::getPosition(ILINT vID, ILFLOAT* vPosition) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->getPosition(vPosition);
- break;
- }
- }
- void IL::SOUND::CSoundManager::getVelocity(ILINT vID, IL::CORE::ILVECTOR3DF& vVelocity) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->getVelocity(vVelocity);
- break;
- }
- }
- void IL::SOUND::CSoundManager::getVelocity(ILINT vID, ILFLOAT* vVelocity) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->getVelocity(vVelocity);
- break;
- }
- }
- ILULONG IL::SOUND::CSoundManager::getFormat(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->getFormat();
- return NULL;
- }
- ILULONG IL::SOUND::CSoundManager::getChannels(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->getChannels();
- return NULL;
- }
- ILULONG IL::SOUND::CSoundManager::getFrequency(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->getFrequency();
- return NULL;
- }
- ILFLOAT IL::SOUND::CSoundManager::getVolume(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->getVolume();
- return NULL;
- }
- ILUINT IL::SOUND::CSoundManager::getSourceID(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->getSourceID();
- return NULL;
- }
- ILUINT IL::SOUND::CSoundManager::getUniqueID(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->getUniqueID();
- return NULL;
- }
- void IL::SOUND::CSoundManager::getDeviceUsed(char* vDeviceString) const
- {
- ALCdevice* pDevice = 0;
- ALCcontext* pContext = 0;
- pContext = alcGetCurrentContext();
- pDevice = alcGetContextsDevice( pContext );
- if (pDevice)
- strcpy(vDeviceString, (char*)alcGetString(pDevice, ALC_DEVICE_SPECIFIER));
- }
- void IL::SOUND::CSoundManager::getDevicesPossible(std::vector<IL::CORE::CString>& vDeviceStrings) const
- {
- ALCdevice* pDevice = 0;
- ALCcontext* pContext = 0;
- char* DeviceBuffer = NULL;
- ILINT CharactersRead = 0;
- char CurrentDevice[128] = {0};
- IL::CORE::CString StringBuffer = NULL;
- pContext = alcGetCurrentContext();
- pDevice = alcGetContextsDevice( pContext );
- if (pDevice)
- {
- DeviceBuffer = (char*)alcGetString(NULL, ALC_DEVICE_SPECIFIER);
- // Go team!
- strcpy(CurrentDevice, DeviceBuffer + CharactersRead);
- while ( 0 != strlen(CurrentDevice) )
- {
- StringBuffer = CurrentDevice;
- CharactersRead += StringBuffer.getLength() + 1;
- vDeviceStrings.push_back(StringBuffer);
- strcpy(CurrentDevice, DeviceBuffer + CharactersRead);
- }
- }
- }
- ILBOOL IL::SOUND::CSoundManager::isPaused(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->isPaused();
- return NULL;
- }
- ILBOOL IL::SOUND::CSoundManager::isStream(ILINT vID) const
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- return m_Sounds[i]->isStream();
- return NULL;
- }
- //////////////////////////////////////////////////////////////////////////
- // Name : Mutators
- //////////////////////////////////////////////////////////////////////////
- void IL::SOUND::CSoundManager::setPosition(ILINT vID, IL::CORE::ILVECTOR3DF& vPosition)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setPosition(vPosition);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setPosition(ILINT vID, ILFLOAT* vPosition)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setPosition(vPosition);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setPosition(ILINT vID, ILFLOAT vX, ILFLOAT vY, ILFLOAT vZ)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setPosition(vX, vY, vZ);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setPosition2D(ILINT vID, ILFLOAT vX, ILFLOAT vY)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setPosition2D(vX, vY);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setVelocity(ILINT vID, IL::CORE::ILVECTOR3DF& vVelocity)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setVelocity(vVelocity);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setVelocity(ILINT vID, ILFLOAT* vVelocity)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setVelocity(vVelocity);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setFormat(ILINT vID, ILULONG vFormat)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setFormat(vFormat);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setChannels(ILINT vID, ILULONG vChannels)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setChannels(vChannels);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setFrequency(ILINT vID, ILULONG vFrequency)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setFrequency(vFrequency);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setMaxVolume(ILINT vID, ILFLOAT vGain)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setMaxVolume(vGain);
- break;
- }
- }
- void IL::SOUND::CSoundManager::setVolume(ILINT vID, ILFLOAT vGain)
- {
- unsigned int Size = (unsigned int)m_Sounds.size();
- // For every sound in the manager, check for a valid ID.
- for (unsigned int i = 0; i < Size; i++)
- if(m_Sounds[i]->getUniqueID() == vID)
- {
- m_Sounds[i]->setVolume(vGain);
- break;
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : cloneSound
- //
- // Date : 2007.03.05
- //
- // Author : Chad Stewart
- //
- // Purpose : Create a new sound from an old one. This is how overlap works,
- // because otherwise each ISound would be a vector of sounds playing
- // instead of a single sound. Then you'd have to know the ID of the
- // sound you want as well as the ID of that specific source. Unless
- // of course you want to stop all sounds of said type everytime.
- ///////////////////////////////////////////////////////////////////////////////
- ILUINT IL::SOUND::CSoundManager::cloneSound(ILINT vVectorID, ISound** vCloneSound)
- {
- // Ok, seriously, we need to copy stuff.
- *vCloneSound = m_Sounds[vVectorID]->cloneSound();
- // Push that bad boy onto the Sound vector.
- m_Sounds.push_back(*vCloneSound);
- (*vCloneSound)->setUniqueID(++m_UniqueIDGenerator);
- (*vCloneSound)->setFileName(m_Sounds[vVectorID]->getFileName());
- // Return it's location.
- return (ILUINT)m_Sounds.size() - 1;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : getFreeChannel
- ///////////////////////////////////////////////////////////////////////////////
- ILINT IL::SOUND::CSoundManager::getFreeChannel(void)
- {
- unsigned int Size = (unsigned int)m_vSoundChannels.size();
- // In use?
- for (unsigned int i = 0; i < Size; i++)
- if (m_vSoundChannels[i].m_InUse == false)
- {
- m_vSoundChannels[i].m_InUse = true;
- return i;
- }
- // No free channels
- return -1;
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Name : getFreeBufferi
- ///////////////////////////////////////////////////////////////////////////////
- ILINT IL::SOUND::CSoundManager::getFreeBufferi(void)
- {
- unsigned int Size = (unsigned int)m_vSoundBuffers.size();
- unsigned int i = 0;
- ILINT BufferID = 0;
- for(i = 0; i < Size; i++)
- if (0 == m_vSoundBuffers[i].m_References)
- break;
- if (i != Size)
- {
- BufferID = m_vSoundBuffers[i].m_BufferID;
- m_vSoundBuffers[i].m_References++;
- }
- else
- {
- // Create a new buffer.
- tBuffer newBuffer;
- // Generate a buffer in OpenAL.
- alGetError();
- alGenBuffers(1, (ALuint*)&newBuffer.m_BufferID);
- newBuffer.m_References++;
- // Add it to our vector.
- m_vSoundBuffers.push_back(newBuffer);
- BufferID = newBuffer.m_BufferID;
- }
- return BufferID;
- }