1
0
forked from 0ad/0ad

add support for positional sound and "omnipresent" interface sounds

snd_mgr: remove support for sound cones (will not be used); only set
VSrc rolloff factor if relative flag is set
main: hack: flip listener up vector to 'fix' L/R flip (cause is unknown,
coord systems appear to be correct)

This was SVN commit r6092.
This commit is contained in:
janwas 2008-06-21 20:06:30 +00:00
parent cc1ab0294c
commit b478fde5a1
8 changed files with 57 additions and 139 deletions

View File

@ -1157,11 +1157,6 @@ struct VSrc
ALboolean loop;
ALboolean relative;
// AL cone properties
ALfloat cone_inner;
ALfloat cone_outer;
ALfloat cone_gain;
/// controls vsrc_update behavior (VSrcFlags)
int flags;
@ -1426,30 +1421,6 @@ static LibError list_free_all()
//-----------------------------------------------------------------------------
/**
* one-time init of parameters we will not later change. this separate from
* vsrc_latch as a tiny optimization.
*
* @param VSrc*
**/
static void vsrc_set_initial(VSrc* vs)
{
if(!vs->al_src)
return;
AL_CHECK;
// AL_VELOCITY and AL_DIRECTION correctly default to (0,0,0)
if(1) // TODO: music tracks and voiceovers, not sound effects
{
alSourcef (vs->al_src, AL_ROLLOFF_FACTOR, 0.0f);
alSourcei (vs->al_src, AL_SOURCE_RELATIVE, AL_TRUE);
}
AL_CHECK;
}
/**
* Send the VSrc properties to OpenAL (when we actually have a source).
* called by snd_set * and vsrc_grant.
@ -1471,19 +1442,15 @@ static void vsrc_latch(VSrc* vs)
debug_assert(!isnan(vs->gain) && vs->gain >= 0.0f);
debug_assert(!isnan(vs->pitch) && vs->pitch > 0.0f);
debug_assert(vs->loop == AL_TRUE || vs->loop == AL_FALSE);
debug_assert(!isnan(vs->cone_inner) && 0.0f <= vs->cone_inner && vs->cone_inner <= 360.0f);
debug_assert(!isnan(vs->cone_outer) && 0.0f <= vs->cone_outer && vs->cone_outer <= 360.0f);
debug_assert(!isnan(vs->cone_gain) && 0.0f <= vs->cone_gain && vs->cone_gain <= 1.0f);
#endif
alSourcefv(vs->al_src, AL_POSITION, vs->pos);
alSourcei (vs->al_src, AL_SOURCE_RELATIVE, vs->relative);
if(vs->relative)
alSourcef (vs->al_src, AL_ROLLOFF_FACTOR, 0.0f);
alSourcef (vs->al_src, AL_GAIN, vs->gain);
alSourcef (vs->al_src, AL_PITCH, vs->pitch);
alSourcei (vs->al_src, AL_LOOPING, vs->loop);
alSourcef (vs->al_src, AL_CONE_INNER_ANGLE, vs->cone_inner);
alSourcef (vs->al_src, AL_CONE_OUTER_ANGLE, vs->cone_outer);
alSourcef (vs->al_src, AL_CONE_OUTER_GAIN, vs->cone_gain);
AL_CHECK;
}
@ -1597,10 +1564,7 @@ static LibError vsrc_grant(VSrc* vs)
if(!vs->al_src)
return ERR::FAIL; // NOWARN
// (once only) set some properties with unspecified initial values
vsrc_set_initial(vs);
// set remaining (user-specifiable) properties.
// pass (user-specifiable) properties on to OpenAL.
vsrc_latch(vs);
// queue up some buffers (enough to start playing, at least).
@ -1843,40 +1807,6 @@ LibError snd_fade(Handle hvs, float initial_gain, float final_gain,
return INFO::OK;
}
/**
* set sound cone information
*
* cone_inner and cone_outer should be in the range 0.0 - 360.0,
* cone_gain (which is the outer cone gain) should range from 0.0 - 1.0
* @param cone_inner inner angle of sound cone
* @param cone_outer outer angle of sound cone
* @param cone_gain outer cone gain
* @return LibError
**/
LibError snd_set_cone(Handle hvs, const float cone_inner, const float cone_outer, const float cone_gain)
{
H_DEREF(hvs, VSrc, vs);
if(!(0.0f <= cone_inner && cone_inner <= 360.0f))
WARN_RETURN(ERR::INVALID_PARAM);
if(!(0.0f <= cone_outer && cone_outer <= 360.0f))
WARN_RETURN(ERR::INVALID_PARAM);
if(!(0.0f <= cone_gain && cone_gain <= 1.0f))
WARN_RETURN(ERR::INVALID_PARAM);
// set parameters in vsrc
vs->cone_inner = cone_inner;
vs->cone_outer = cone_outer;
vs->cone_gain = cone_gain;
vsrc_latch(vs);
return INFO::OK;
}
/** --TODO: Test to ensure this works (not currently necessary for intensity)
* find out if a sound is still playing
*

View File

@ -330,20 +330,6 @@ extern LibError snd_disable(bool disabled);
**/
extern LibError snd_update(const float* pos, const float* dir, const float* up);
/** added by GF
* set sound cone information
*
* cone_inner and cone_outer should be in the range 0.0 - 360.0,
* cone_gain (which is the outer cone gain) should range from 0.0 - 1.0
* @param cone_inner inner angle of sound cone
* @param cone_outer outer angle of sound cone
* @param cone_gain outer cone gain
* @return LibError
**/
extern LibError snd_set_cone(Handle hvs, const float cone_inner, const float cone_outer, const float cone_gain);
/** added by GF
* find out if a sound is still playing
*

View File

@ -206,10 +206,6 @@ static void Frame()
music_player.Update();
PROFILE_END( "update music" );
PROFILE_START( "update sound groups" );
g_soundGroupMgr->UpdateSoundGroups(TimeSinceLastFrame);
PROFILE_END( "update sound groups" );
bool is_building_archive; // must come before PROFILE_START's {
PROFILE_START("build archive");
MICROLOG(L"build archive");
@ -276,12 +272,16 @@ static void Frame()
PROFILE_START( "sound update" );
CCamera* camera = g_Game->GetView()->GetCamera();
CMatrix3D& orientation = camera->m_Orientation;
float* pos = &orientation._data[12];
float* dir = &orientation._data[8];
float* up = &orientation._data[4];
if(snd_update(pos, dir, up) < 0)
// HACK: otherwise sound effects are L/R flipped. No idea what else
// is going wrong, because the listener and camera are supposed to
// coincide in position and orientation.
float down[3] = { -up[0], -up[1], -up[2] };
if(snd_update(pos, dir, down) < 0)
debug_printf("snd_update failed\n");
g_soundGroupMgr->UpdateSoundGroups(TimeSinceLastFrame);
PROFILE_END( "sound update" );
}
else

View File

@ -439,7 +439,7 @@ bool CEntity::ProcessContactActionNoPathing( CEntityOrder* current, int timestep
if( ( m_fsm_cyclepos <= action->m_Speed ) && ( nextpos > action->m_Speed ) )
{
const size_t soundGroupIndex = m_base->m_SoundGroupTable[animation];
g_soundGroupMgr->PlayNext(soundGroupIndex);
g_soundGroupMgr->PlayNext(soundGroupIndex, m_position);
if(!DispatchEvent( contactEvent ))
{

View File

@ -27,8 +27,6 @@ CSoundGroup::CSoundGroup()
m_Flags = 0;
m_Intensity = 0;
m_CurTime = 0.0f;
}
CSoundGroup::CSoundGroup(const char *XMLfile)
@ -44,11 +42,23 @@ CSoundGroup::~CSoundGroup()
{
// clean up all the handles from this group.
ReleaseGroup();
}
void CSoundGroup::PlayNext()
void CSoundGroup::PlayNext(const CVector3D& position)
{
// interface/UI sounds should always be played at the listener's
// position, which is achieved by setting position to 0 and
// having that treated as relative to the listener.
float x = 0.0f, y = 0.0f, z = 0.0f;
bool relative = true;
if(!TestFlag(eOmnipresent))
{
x = position.X;
y = position.Y;
z = position.Z;
relative = false;
}
if(m_Intensity >= m_IntensityThreshold)
{
if(!is_playing(m_hReplacement))
@ -59,7 +69,7 @@ void CSoundGroup::PlayNext()
return;
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);
snd_set_pos(m_hReplacement, x, y, z, relative);
//check for randomization of pitch and gain
if(TestFlag(eRandPitch))
@ -68,7 +78,6 @@ void CSoundGroup::PlayNext()
snd_set_gain(m_hReplacement, (float)((rand(m_GainLower * 100.0f, m_GainUpper * 100.0f) / 100.0f)));
snd_play(m_hReplacement, m_Priority);
}
}
else
@ -80,30 +89,21 @@ void CSoundGroup::PlayNext()
// 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, (size_t)filenames.size());
Handle temp;
temp = snd_open(m_filepath + filenames[m_index]);
if(temp == ERR::AGAIN) // sound is disabled
// (note: previously snd_group[m_index] was used in place of hs)
Handle hs = snd_open(m_filepath + filenames[m_index]);
if(hs == ERR::AGAIN) // sound is disabled
return;
snd_set_gain(temp, m_Gain);
snd_set_pitch(temp, m_Pitch);
snd_set_cone(temp, m_ConeInnerAngle, m_ConeOuterAngle, m_ConeOuterGain);
snd_set_gain(hs, m_Gain);
snd_set_pitch(hs, m_Pitch);
snd_set_pos(hs, x, y, z, relative);
//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)));
snd_set_pitch(hs, (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);
snd_set_gain(hs, (float)((rand(m_GainLower * 100.0f, m_GainUpper * 100.0f) / 100.0f)));
snd_play(hs, m_Priority);
}
playtimes[m_index] = 0.0f;
@ -111,7 +111,6 @@ void CSoundGroup::PlayNext()
m_Intensity++;
if(m_Intensity > m_IntensityThreshold)
m_Intensity = m_IntensityThreshold;
if(m_index >= filenames.size())
Reload();
@ -119,7 +118,7 @@ void CSoundGroup::PlayNext()
void CSoundGroup::Reload()
{
m_index = 0; // reset our index
m_index = 0; // reset our index
// get rid of the used handles
snd_group.clear();
// clear out the old timers
@ -143,12 +142,10 @@ void CSoundGroup::Reload()
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();
playtimes.clear();
@ -160,7 +157,6 @@ void CSoundGroup::ReleaseGroup()
void CSoundGroup::Update(float TimeSinceLastFrame)
{
for(size_t i = 0; i < playtimes.size(); i++)
{
if(playtimes[i] >= 0.0f)
@ -176,7 +172,6 @@ void CSoundGroup::Update(float TimeSinceLastFrame)
bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
{
CXeromyces XeroFile;
if (XeroFile.Load(XMLfile) != PSRETURN_OK)
return false;
@ -190,6 +185,7 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
EL(soundgroup);
EL(gain);
EL(looping);
EL(omnipresent);
EL(pitch);
EL(priority);
EL(randorder);
@ -229,11 +225,17 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
}
if(child_name == el_looping)
{
{
if(CStr(child.GetText()).ToInt() == 1)
SetFlag(eLoop);
}
if(child_name == el_omnipresent)
{
if(CStr(child.GetText()).ToInt() == 1)
SetFlag(eOmnipresent);
}
if(child_name == el_pitch)
{
this->m_Pitch = CStr(child.GetText()).ToFloat();
@ -266,15 +268,12 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
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();
@ -330,7 +329,6 @@ bool CSoundGroup::LoadSoundGroup(const char *XMLfile)
}
}
Reload();
return true;

View File

@ -39,6 +39,7 @@ Example SoundGroup.xml
#include "lib/res/handle.h"
#include "ps/CStr.h"
#include "maths/Vector3D.h"
#include "lib/res/sound/snd_mgr.h"
#include <vector>
@ -46,10 +47,11 @@ using namespace std;
enum eSndGrpFlags
{
eRandOrder = 0x01,
eRandGain = 0x02,
eRandPitch = 0x04,
eLoop = 0x08
eRandOrder = 0x01,
eRandGain = 0x02,
eRandPitch = 0x04,
eLoop = 0x08,
eOmnipresent = 0x10
};
@ -89,7 +91,9 @@ public:
~CSoundGroup(void);
// Play next sound in group
void PlayNext();
// @param position world position of the entity generating the sound
// (ignored if the eOmnipresent flag is set)
void PlayNext(const CVector3D& position);
// Load a group
bool LoadSoundGroup(const char *XMLfile);
@ -106,7 +110,7 @@ public:
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;}
inline bool TestFlag(int flag) { return (m_Flags & flag) != 0;}
};

View File

@ -138,7 +138,7 @@ void CSoundGroupMgr::UpdateSoundGroups(float TimeSinceLastFrame)
// in: size_t index - index into m_Groups
// Plays the next queued sound in an indexed group
///////////////////////////////////////////
void CSoundGroupMgr::PlayNext(size_t index)
void CSoundGroupMgr::PlayNext(size_t index, const CVector3D& position)
{
m_Groups[index]->PlayNext();
m_Groups[index]->PlayNext(position);
}

View File

@ -31,7 +31,7 @@ public:
// in: size_t index - index into m_Groups
// Plays the next queued sound in an indexed group
///////////////////////////////////////////
void PlayNext(size_t index);
void PlayNext(size_t index, const CVector3D& position);
///////////////////////////////////////////
// AddGroup()