#First submission of SoundGroup.h and SoundGroup.cpp ref #138
This was SVN commit r4440.
This commit is contained in:
parent
c1377256fa
commit
920cbe4dc3
230
source/sound/SoundGroup.cpp
Normal file
230
source/sound/SoundGroup.cpp
Normal file
@ -0,0 +1,230 @@
|
||||
/**
|
||||
* =========================================================================
|
||||
* File : SoundGroup.cpp
|
||||
* Project : 0 A.D.
|
||||
* Description : Loads up a group of sound files with shared properties,
|
||||
* and provides a simple interface for playing them.
|
||||
*
|
||||
* Author : Gavin Fowler
|
||||
* =========================================================================
|
||||
*/
|
||||
#include "precompiled.h"
|
||||
|
||||
#include "SoundGroup.h"
|
||||
|
||||
#include "ps/XML/Xeromyces.h"
|
||||
|
||||
#include "ps/CLogger.h"
|
||||
|
||||
#include "lib/lib.h"
|
||||
|
||||
#define LOG_CATEGORY "audio"
|
||||
|
||||
size_t CSoundGroup::m_index = 0;
|
||||
|
||||
CSoundGroup::CSoundGroup()
|
||||
{
|
||||
m_Flags = 0;
|
||||
|
||||
}
|
||||
|
||||
CSoundGroup::CSoundGroup(const char *XMLfile)
|
||||
{
|
||||
m_Flags = 0;
|
||||
LoadSoundGroup(XMLfile);
|
||||
}
|
||||
|
||||
CSoundGroup::~CSoundGroup()
|
||||
{
|
||||
// clean up all the handles from this group.
|
||||
ReleaseGroup();
|
||||
|
||||
}
|
||||
|
||||
void CSoundGroup::PlayNext()
|
||||
{
|
||||
//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);
|
||||
m_index++;
|
||||
if(m_index >= snd_group.size())
|
||||
Reload();
|
||||
}
|
||||
|
||||
void CSoundGroup::Reload()
|
||||
{
|
||||
m_index = 0; // reset our static index
|
||||
// get rid of the used handles
|
||||
snd_group.clear();
|
||||
//Reload the sounds
|
||||
for(size_t i = 0; i < filenames.size(); i++)
|
||||
{
|
||||
Handle temp = snd_open(m_filepath + filenames[i]);
|
||||
snd_set_gain(temp, m_Gain);
|
||||
snd_set_pitch(temp, m_Pitch);
|
||||
snd_group.push_back(temp);
|
||||
}
|
||||
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++)
|
||||
snd_free(snd_group[i]);
|
||||
snd_group.clear();
|
||||
|
||||
}
|
||||
|
||||
bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
|
||||
{
|
||||
|
||||
CXeromyces XeroFile;
|
||||
if (XeroFile.Load(XMLfile) != PSRETURN_OK)
|
||||
return false;
|
||||
|
||||
// adjust the path name for resources if necessary
|
||||
//m_Name = XMLfile + directorypath;
|
||||
|
||||
//Define elements used in XML file
|
||||
#define EL(x) int el_##x = XeroFile.getElementID(#x)
|
||||
#define AT(x) int at_##x = XeroFile.getAttributeID(#x)
|
||||
EL(soundgroup);
|
||||
EL(gain);
|
||||
EL(looping);
|
||||
EL(pitch);
|
||||
EL(priority);
|
||||
EL(randorder);
|
||||
EL(randgain);
|
||||
EL(randpitch);
|
||||
EL(conegain);
|
||||
EL(coneinner);
|
||||
EL(coneouter);
|
||||
EL(sound);
|
||||
EL(gainupper);
|
||||
EL(gainlower);
|
||||
EL(pitchupper);
|
||||
EL(pitchlower);
|
||||
EL(path);
|
||||
#undef AT
|
||||
#undef EL
|
||||
|
||||
XMBElement root = XeroFile.getRoot();
|
||||
|
||||
if (root.getNodeName() != el_soundgroup)
|
||||
{
|
||||
LOG(ERROR, LOG_CATEGORY, "Invalid SoundGroup format (unrecognised root element '%s')", XeroFile.getElementString(root.getNodeName()).c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
XERO_ITER_EL(root, child)
|
||||
{
|
||||
|
||||
int child_name = child.getNodeName();
|
||||
|
||||
if(child_name == el_gain)
|
||||
{
|
||||
this->m_Gain = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_looping)
|
||||
{
|
||||
if(CStr(child.getText()).ToInt() == 1)
|
||||
SetFlag(eLoop);
|
||||
}
|
||||
|
||||
if(child_name == el_pitch)
|
||||
{
|
||||
this->m_Pitch = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_priority)
|
||||
{
|
||||
this->m_Priority = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_randorder)
|
||||
{
|
||||
if(CStr(child.getText()).ToInt() == 1)
|
||||
SetFlag(eRandOrder);
|
||||
}
|
||||
|
||||
if(child_name == el_randgain)
|
||||
{
|
||||
if(CStr(child.getText()).ToInt() == 1)
|
||||
SetFlag(eRandGain);
|
||||
}
|
||||
|
||||
if(child_name == el_gainupper)
|
||||
{
|
||||
this->m_GainUpper = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_gainlower)
|
||||
{
|
||||
this->m_GainLower = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(child_name == el_randpitch)
|
||||
{
|
||||
if(CStr(child.getText()).ToInt() == 1)
|
||||
SetFlag(eRandPitch);
|
||||
}
|
||||
|
||||
|
||||
if(child_name == el_pitchupper)
|
||||
{
|
||||
this->m_PitchUpper = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_pitchlower)
|
||||
{
|
||||
this->m_PitchLower = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_conegain)
|
||||
{
|
||||
this->m_ConeOuterGain = CStr(child.getText()).ToFloat();
|
||||
}
|
||||
|
||||
if(child_name == el_coneinner)
|
||||
{
|
||||
this->m_ConeInnerAngle = CStr(child.getText()).ToInt();
|
||||
}
|
||||
|
||||
if(child_name == el_coneouter)
|
||||
{
|
||||
this->m_ConeOuterAngle = CStr(child.getText()).ToInt();
|
||||
}
|
||||
|
||||
if(child_name == el_sound)
|
||||
{
|
||||
CStr szTemp(child.getText());
|
||||
//Handle temp = snd_open(szTemp);
|
||||
//this->snd_group.push_back(temp);
|
||||
this->filenames.push_back(szTemp);
|
||||
|
||||
}
|
||||
if(child_name == el_path)
|
||||
{
|
||||
m_filepath = child.getText();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reload();
|
||||
return true;
|
||||
|
||||
}
|
106
source/sound/SoundGroup.h
Normal file
106
source/sound/SoundGroup.h
Normal file
@ -0,0 +1,106 @@
|
||||
/**
|
||||
* =========================================================================
|
||||
* File : SoundGroup.h
|
||||
* Project : 0 A.D.
|
||||
* Description : Loads up a group of sound files with shared properties,
|
||||
* and provides a simple interface for playing them.
|
||||
*
|
||||
* 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.
|
||||
|
||||
Example SoundGroup.xml
|
||||
<?xml version="1.0" encoding="utf-8" standalone="no" ?>
|
||||
<SoundGroup>
|
||||
<Gain>1.0</Gain>
|
||||
<Looping>0</Looping>
|
||||
<Pitch>1.0</Pitch>
|
||||
<Priority>100</Priority>
|
||||
<RandOrder>0</RandOrder>
|
||||
<RandGain>0</RandGain>
|
||||
<RandPitch>0</RandPitch>
|
||||
<ConeGain>1.0</ConeGain>
|
||||
<ConeInner>360</ConeInner>
|
||||
<ConeOuter>360</ConeOuter>
|
||||
<Sound>audio/voice/hellenes/soldier/Attack_Attackx.ogg</Sound>
|
||||
<Sound>audio/voice/hellenes/soldier/Attack_Chargex.ogg</Sound>
|
||||
<Sound>audio/voice/hellenes/soldier/Attack_Engagex.ogg</Sound>
|
||||
<Sound>audio/voice/hellenes/soldier/Attack_ForMyFamily.ogg</Sound>
|
||||
</SoundGroup>
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifndef SOUNDGROUP_H_
|
||||
#define SOUNDGROUP_H_
|
||||
|
||||
|
||||
#include "lib/res/handle.h"
|
||||
#include "ps/cstr.h"
|
||||
#include "lib/res/sound/snd_mgr.h"
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
enum eSndGrpFlags{ eRandOrder = 0x01, eRandGain = 0x02, eRandPitch = 0x04, eLoop = 0x08 };
|
||||
|
||||
class CSoundGroup
|
||||
{
|
||||
|
||||
static size_t m_index; // index of the next sound to play
|
||||
|
||||
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.
|
||||
CStr m_filepath;
|
||||
|
||||
unsigned char m_Flags; // up to eight individual parameters, use with eSndGrpFlags.
|
||||
|
||||
float m_Gain;
|
||||
float m_Pitch;
|
||||
float m_Priority;
|
||||
float m_ConeOuterGain;
|
||||
float m_PitchUpper;
|
||||
float m_PitchLower;
|
||||
float m_GainUpper;
|
||||
float m_GainLower;
|
||||
int m_ConeInnerAngle;
|
||||
int m_ConeOuterAngle;
|
||||
|
||||
public:
|
||||
CSoundGroup(const char *XMLfile);
|
||||
CSoundGroup(void);
|
||||
~CSoundGroup(void);
|
||||
|
||||
// Play next sound in group
|
||||
void PlayNext();
|
||||
|
||||
// Load a group
|
||||
bool LoadSoundGroup(const char *XMLfile);
|
||||
|
||||
void Reload();
|
||||
|
||||
// Release all remaining loaded handles
|
||||
void ReleaseGroup();
|
||||
|
||||
// Set a flag using a value from eSndGrpFlags
|
||||
inline void SetFlag(int flag){ m_Flags |= flag; }
|
||||
|
||||
// Test flag, returns true if flag is set.
|
||||
inline bool TestFlag(int flag) { return (m_Flags & flag) == flag;}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //#ifndef SOUNDGROUP_H_
|
Loading…
Reference in New Issue
Block a user