#Added Sound Group Manager, updated Sound Groups.
refs #138. Added SoundGroupMgr.h and .cpp, revised loading and clean up in SoundGroup class. This was SVN commit r4761.
This commit is contained in:
parent
e0a6c50ce1
commit
0b150ee311
@ -8,6 +8,19 @@
|
||||
* Author : Gavin Fowler
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Gavin Fowler
|
||||
*
|
||||
* Redistribution and/or modification are also permitted under the
|
||||
* terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation (version 2 or later, at your option).
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "precompiled.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -28,6 +41,9 @@ CSoundGroup::CSoundGroup()
|
||||
{
|
||||
m_index = 0;
|
||||
m_Flags = 0;
|
||||
m_Intensity = 0;
|
||||
m_CurTime = 0.0f;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -35,6 +51,8 @@ CSoundGroup::CSoundGroup(const char *XMLfile)
|
||||
{
|
||||
m_index = 0;
|
||||
m_Flags = 0;
|
||||
m_Intensity = 0;
|
||||
m_CurTime = 0.0f;
|
||||
LoadSoundGroup(XMLfile);
|
||||
}
|
||||
|
||||
@ -47,31 +65,75 @@ CSoundGroup::~CSoundGroup()
|
||||
|
||||
void CSoundGroup::PlayNext()
|
||||
{
|
||||
if(m_Intensity >= m_IntensityThreshold)
|
||||
{
|
||||
if(!is_playing(m_hReplacement))
|
||||
{
|
||||
// load up replacement file
|
||||
m_hReplacement = snd_open(m_filepath + m_intensity_file);
|
||||
snd_set_gain(m_hReplacement, m_Gain);
|
||||
snd_set_pitch(m_hReplacement, m_Pitch);
|
||||
snd_set_cone(m_hReplacement, m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
|
||||
|
||||
//if(this->m_intensity_threshold)
|
||||
//for(size_t i = 0; i < m_index; i++)
|
||||
//{
|
||||
// //H_USER_DATA(snd_group[i], H_Sound);
|
||||
//}
|
||||
//check for randomization of pitch and gain
|
||||
if(TestFlag(eRandPitch))
|
||||
snd_set_pitch(snd_group[m_index], (float)((rand(m_PitchLower * 100.0f, m_PitchUpper * 100.0f) / 100.0f)));
|
||||
if(TestFlag(eRandGain))
|
||||
snd_set_gain(snd_group[m_index], (float)((rand(m_GainLower * 100.0f, m_GainUpper * 100.0f) / 100.0f)));
|
||||
|
||||
snd_play(snd_group[m_index], m_Priority);
|
||||
snd_play(m_hReplacement, m_Priority);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// try loading on the fly only when we need the sound to see if that fixes release problems...
|
||||
if(TestFlag(eRandOrder))
|
||||
m_index = (size_t)rand(0, filenames.size());
|
||||
Handle temp;
|
||||
temp = snd_open(m_filepath + filenames[m_index]);
|
||||
snd_set_gain(temp, m_Gain);
|
||||
snd_set_pitch(temp, m_Pitch);
|
||||
snd_set_cone(temp, m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
|
||||
|
||||
|
||||
//check for randomization of pitch and gain
|
||||
if(TestFlag(eRandPitch))
|
||||
snd_set_pitch(temp, (float)((rand(m_PitchLower * 100.0f, m_PitchUpper * 100.0f) / 100.0f)));
|
||||
//snd_set_pitch(snd_group[m_index], (float)((rand(m_PitchLower * 100.0f, m_PitchUpper * 100.0f) / 100.0f)));
|
||||
|
||||
if(TestFlag(eRandGain))
|
||||
snd_set_gain(temp, (float)((rand(m_GainLower * 100.0f, m_GainUpper * 100.0f) / 100.0f)));
|
||||
//snd_set_gain(snd_group[m_index], (float)((rand(m_GainLower * 100.0f, m_GainUpper * 100.0f) / 100.0f)));
|
||||
|
||||
snd_play(temp, m_Priority);
|
||||
//snd_play(snd_group[m_index], m_Priority);
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
playtimes[m_index] = 0.0f;
|
||||
m_index++;
|
||||
if(m_index >= snd_group.size())
|
||||
m_Intensity++;
|
||||
if(m_Intensity > m_IntensityThreshold)
|
||||
m_Intensity = m_IntensityThreshold;
|
||||
|
||||
|
||||
if(m_index >= filenames.size())
|
||||
Reload();
|
||||
}
|
||||
|
||||
void CSoundGroup::Reload()
|
||||
{
|
||||
m_index = 0; // reset our static index
|
||||
m_index = 0; // reset our index
|
||||
// get rid of the used handles
|
||||
snd_group.clear();
|
||||
// clear out the old timers
|
||||
playtimes.clear();
|
||||
//Reload the sounds
|
||||
for(size_t i = 0; i < filenames.size(); i++)
|
||||
/*for(size_t i = 0; i < filenames.size(); i++)
|
||||
{
|
||||
string szTemp = m_filepath + filenames[i];
|
||||
Handle temp = snd_open(m_filepath + filenames[i]);
|
||||
@ -79,27 +141,46 @@ void CSoundGroup::Reload()
|
||||
snd_set_pitch(temp, m_Pitch);
|
||||
snd_set_cone(temp, m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
|
||||
snd_group.push_back(temp);
|
||||
}
|
||||
if(TestFlag(eRandOrder))
|
||||
random_shuffle(snd_group.begin(), snd_group.end());
|
||||
|
||||
|
||||
|
||||
|
||||
}*/
|
||||
while(playtimes.size() < filenames.size())
|
||||
playtimes.push_back(-1.0f);
|
||||
//if(TestFlag(eRandOrder))
|
||||
//random_shuffle(snd_group.begin(), snd_group.end());
|
||||
}
|
||||
|
||||
void CSoundGroup::ReleaseGroup()
|
||||
{
|
||||
|
||||
for(size_t i = m_index; i<snd_group.size(); i++)
|
||||
{
|
||||
//if(!is_playing(snd_group[i]))
|
||||
snd_free(snd_group[i]);
|
||||
snd_group.clear();
|
||||
m_index = 0;
|
||||
|
||||
}
|
||||
snd_group.clear();
|
||||
playtimes.clear();
|
||||
//if(is_playing(m_hReplacement))
|
||||
// snd_free(m_hReplacement);
|
||||
m_index = 0;
|
||||
|
||||
}
|
||||
|
||||
void CSoundGroup::Update(float TimeSinceLastFrame)
|
||||
{
|
||||
|
||||
for(size_t i = 0; i < playtimes.size(); i++)
|
||||
{
|
||||
if(playtimes[i] >= 0.0f)
|
||||
playtimes[i] += TimeSinceLastFrame;
|
||||
|
||||
if(playtimes[i] >= m_Decay)
|
||||
{
|
||||
playtimes[i] = -1.0f;
|
||||
m_Intensity--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
|
||||
{
|
||||
@ -132,6 +213,7 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
|
||||
EL(pitchlower);
|
||||
EL(path);
|
||||
EL(threshold);
|
||||
EL(decay);
|
||||
EL(replacement);
|
||||
#undef AT
|
||||
#undef EL
|
||||
@ -239,9 +321,16 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
|
||||
}
|
||||
if(child_name == el_threshold)
|
||||
{
|
||||
m_intensity_threshold = CStr(child.getText()).ToFloat();
|
||||
|
||||
//m_intensity_threshold = CStr(child.getText()).ToFloat();
|
||||
m_IntensityThreshold = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_decay)
|
||||
{
|
||||
//m_intensity_threshold = CStr(child.getText()).ToFloat();
|
||||
m_Decay = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_replacement)
|
||||
{
|
||||
m_intensity_file = child.getText();
|
||||
|
@ -8,13 +8,22 @@
|
||||
* Author : Gavin Fowler
|
||||
* =========================================================================
|
||||
*/
|
||||
/*
|
||||
Example usage:
|
||||
|
||||
CSoundGroup s;
|
||||
s.LoadSoundGroup("SoundGroup.xml"); // only needs to be called once (or not at all if filename is passed to ctor)
|
||||
s.PlayNext(); // call each time you want to play another sound from the group.
|
||||
s.ReleaseGroup(); // If you want to free up the resources early, but this happens in dtor.
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Gavin Fowler
|
||||
*
|
||||
* Redistribution and/or modification are also permitted under the
|
||||
* terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation (version 2 or later, at your option).
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
/*
|
||||
Example usage: (SEE SOUNDGROUPMGR.H)
|
||||
|
||||
|
||||
Example SoundGroup.xml
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
|
||||
@ -55,18 +64,24 @@ enum eSndGrpFlags
|
||||
eLoop = 0x08
|
||||
};
|
||||
|
||||
|
||||
class CSoundGroup
|
||||
{
|
||||
size_t m_index; // index of the next sound to play
|
||||
|
||||
Handle m_hReplacement;
|
||||
|
||||
vector<Handle> snd_group; // we store the handles so we can load now and play later
|
||||
vector<CStr> filenames; // we need the filenames so we can reload when necessary.
|
||||
vector<float> playtimes; // it would be better to store this in with the Handles perhaps?
|
||||
CStr m_filepath; // the file path for the list of sound file resources
|
||||
CStr m_intensity_file; // this will be either the name of a new sound file or new sound group
|
||||
|
||||
size_t m_intensity_threshold;
|
||||
|
||||
CStr m_intensity_file; // the replacement aggregate 'intense' sound
|
||||
|
||||
float m_CurTime; // Time elapsed since soundgroup was created
|
||||
float m_TimeWindow; // The Intensity Threshold Window
|
||||
size_t m_IntensityThreshold; // the allowable intensity before a sound switch
|
||||
size_t m_Intensity; // our current intensity(number of sounds played since m_CurTime - m_TimeWindow)
|
||||
float m_Decay; //
|
||||
unsigned char m_Flags; // up to eight individual parameters, use with eSndGrpFlags.
|
||||
|
||||
float m_Gain;
|
||||
@ -96,6 +111,9 @@ public:
|
||||
// Release all remaining loaded handles
|
||||
void ReleaseGroup();
|
||||
|
||||
// Update SoundGroup, remove dead sounds from intensity count
|
||||
void Update(float TimeSinceLastFrame);
|
||||
|
||||
// Set a flag using a value from eSndGrpFlags
|
||||
inline void SetFlag(int flag){ m_Flags |= flag; }
|
||||
|
||||
|
156
source/sound/SoundGroupMgr.cpp
Normal file
156
source/sound/SoundGroupMgr.cpp
Normal file
@ -0,0 +1,156 @@
|
||||
/**
|
||||
* =========================================================================
|
||||
* File : SoundGroupMgr.h
|
||||
* Project : 0 A.D.
|
||||
* Description : Manages and updates SoundGroups
|
||||
*
|
||||
* Author : Gavin Fowler
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Gavin Fowler
|
||||
*
|
||||
* Redistribution and/or modification are also permitted under the
|
||||
* terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation (version 2 or later, at your option).
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
// Example usage:
|
||||
|
||||
// size_t index;
|
||||
// CSoundGroupMgr *sgm = CSoundGroupMgr::GetInstance();
|
||||
// index = sgm->AddGroup("SoundGroup.xml");
|
||||
|
||||
// sgm->UpdateSoundGroups(TimeSinceLastFrame); // call in Frame()
|
||||
|
||||
// sgm->PlayNext(index); // wash-rinse-repeat
|
||||
|
||||
|
||||
// sgm->RemoveGroup(index); // Remove the group if you like
|
||||
|
||||
// sgm->DeleteInstance(); // Delete instance in shutdown
|
||||
|
||||
|
||||
#include "precompiled.h"
|
||||
#include "SoundGroupMgr.h"
|
||||
|
||||
|
||||
CSoundGroupMgr *CSoundGroupMgr::m_pInstance = 0;
|
||||
|
||||
CSoundGroupMgr::CSoundGroupMgr()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CSoundGroupMgr *CSoundGroupMgr::GetInstance()
|
||||
{
|
||||
if(!m_pInstance)
|
||||
m_pInstance = new CSoundGroupMgr();
|
||||
|
||||
return m_pInstance;
|
||||
|
||||
}
|
||||
|
||||
void CSoundGroupMgr::DeleteInstance()
|
||||
{
|
||||
if(m_pInstance)
|
||||
{
|
||||
|
||||
vector<CSoundGroup *>::iterator vIter = m_pInstance->m_Groups.begin();
|
||||
while(vIter != m_pInstance->m_Groups.end())
|
||||
vIter = m_pInstance->RemoveGroup(vIter);
|
||||
|
||||
delete m_pInstance;
|
||||
}
|
||||
m_pInstance = 0;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// AddGroup()
|
||||
// in: const char *XMLFile - the filename of the SoundGroup.xml to open
|
||||
// out: size_t index into m_Groups
|
||||
// Loads the given XML file and returns an index for later use
|
||||
///////////////////////////////////////////
|
||||
size_t CSoundGroupMgr::AddGroup(const char *XMLFile)
|
||||
{
|
||||
CSoundGroup* newGroup = new CSoundGroup(XMLFile);
|
||||
m_Groups.push_back(newGroup);
|
||||
|
||||
return m_Groups.size() - 1;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// RemoveGroup()
|
||||
// in: size_t index into m_Groups
|
||||
// out: vector<CSoundGroup *>::iterator - one past the index removed (sometimes useful)
|
||||
// Removes and Releases a given soundgroup
|
||||
///////////////////////////////////////////
|
||||
vector<CSoundGroup *>::iterator CSoundGroupMgr::RemoveGroup(size_t index)
|
||||
{
|
||||
|
||||
vector<CSoundGroup *>::iterator vIter = m_Groups.begin();
|
||||
if(index >= m_Groups.size())
|
||||
return vIter;
|
||||
|
||||
|
||||
|
||||
CSoundGroup *temp = (*vIter);
|
||||
(*vIter)->ReleaseGroup();
|
||||
vIter = m_Groups.erase(vIter+index);
|
||||
|
||||
delete temp;
|
||||
|
||||
return vIter;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// RemoveGroup()
|
||||
// in: vector<CSoundGroup *>::iterator - item to remove
|
||||
// out: vector<CSoundGroup *>::iterator - one past the index removed (sometimes useful)
|
||||
// Removes and Releases a given soundgroup
|
||||
///////////////////////////////////////////
|
||||
vector<CSoundGroup *>::iterator CSoundGroupMgr::RemoveGroup(vector<CSoundGroup *>::iterator iter)
|
||||
{
|
||||
|
||||
(*iter)->ReleaseGroup();
|
||||
|
||||
CSoundGroup *temp = (*iter);
|
||||
|
||||
iter = m_Groups.erase(iter);
|
||||
|
||||
delete temp;
|
||||
|
||||
return iter;
|
||||
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// UpdateSoundGroups()
|
||||
// updates all soundgroups, call in Frame()
|
||||
///////////////////////////////////////////
|
||||
void CSoundGroupMgr::UpdateSoundGroups(float TimeSinceLastFrame)
|
||||
{
|
||||
vector<CSoundGroup *>::iterator vIter = m_Groups.begin();
|
||||
while(vIter != m_Groups.end())
|
||||
{
|
||||
(*vIter)->Update(TimeSinceLastFrame);
|
||||
vIter++;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////
|
||||
// PlayNext()
|
||||
// in: size_t index - index into m_Groups
|
||||
// Plays the next queued sound in an indexed group
|
||||
///////////////////////////////////////////
|
||||
void CSoundGroupMgr::PlayNext(size_t index)
|
||||
{
|
||||
m_Groups[index]->PlayNext();
|
||||
}
|
79
source/sound/SoundGroupMgr.h
Normal file
79
source/sound/SoundGroupMgr.h
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* =========================================================================
|
||||
* File : SoundGroupMgr.h
|
||||
* Project : 0 A.D.
|
||||
* Description : Manages and updates SoundGroups
|
||||
*
|
||||
* Author : Gavin Fowler
|
||||
* =========================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Copyright (c) 2005-2006 Gavin Fowler
|
||||
*
|
||||
* Redistribution and/or modification are also permitted under the
|
||||
* terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation (version 2 or later, at your option).
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "SoundGroup.h"
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
class CSoundGroupMgr
|
||||
{
|
||||
public:
|
||||
vector <CSoundGroup *> m_Groups; // a collection of sound groups
|
||||
static CSoundGroupMgr *m_pInstance; // our static instance of the manager
|
||||
static CSoundGroupMgr *GetInstance();
|
||||
static void DeleteInstance();
|
||||
|
||||
///////////////////////////////////////////
|
||||
// UpdateSoundGroups()
|
||||
// updates all soundgroups, call in Frame()
|
||||
///////////////////////////////////////////
|
||||
void UpdateSoundGroups(float TimeSinceLastFrame);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// PlayNext()
|
||||
// in: size_t index - index into m_Groups
|
||||
// Plays the next queued sound in an indexed group
|
||||
///////////////////////////////////////////
|
||||
void PlayNext(size_t index);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// AddGroup()
|
||||
// in: const char *XMLFile - the filename of the SoundGroup.xml to open
|
||||
// out: size_t index into m_Groups
|
||||
// Loads the given XML file and returns an index for later use
|
||||
///////////////////////////////////////////
|
||||
size_t AddGroup(const char *XMLFile);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// RemoveGroup()
|
||||
// in: size_t index into m_Groups
|
||||
// out: vector<CSoundGroup *>::iterator - one past the index removed (sometimes useful)
|
||||
// Removes and Releases a given soundgroup
|
||||
///////////////////////////////////////////
|
||||
vector<CSoundGroup *>::iterator RemoveGroup(size_t index);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// RemoveGroup()
|
||||
// in: vector<CSoundGroup *>::iterator - item to remove
|
||||
// out: vector<CSoundGroup *>::iterator - one past the index removed (sometimes useful)
|
||||
// Removes and Releases a given soundgroup
|
||||
///////////////////////////////////////////
|
||||
vector<CSoundGroup *>::iterator RemoveGroup(vector<CSoundGroup *>::iterator iter);
|
||||
|
||||
|
||||
private:
|
||||
CSoundGroupMgr();
|
||||
CSoundGroupMgr(const CSoundGroupMgr &ref);
|
||||
CSoundGroupMgr &operator=(const CSoundGroupMgr &ref);
|
||||
|
||||
};
|
Loading…
Reference in New Issue
Block a user