diff --git a/source/lib/res/sound/snd_mgr.cpp b/source/lib/res/sound/snd_mgr.cpp index 6e735f0ba6..723fe2e368 100644 --- a/source/lib/res/sound/snd_mgr.cpp +++ b/source/lib/res/sound/snd_mgr.cpp @@ -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 * diff --git a/source/lib/res/sound/snd_mgr.h b/source/lib/res/sound/snd_mgr.h index 047de5289d..e48a0fe74c 100644 --- a/source/lib/res/sound/snd_mgr.h +++ b/source/lib/res/sound/snd_mgr.h @@ -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 * diff --git a/source/main.cpp b/source/main.cpp index 2bd41f9a87..559c22bc44 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -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 diff --git a/source/simulation/EntityStateProcessing.cpp b/source/simulation/EntityStateProcessing.cpp index 78307cae9b..8056dc8631 100644 --- a/source/simulation/EntityStateProcessing.cpp +++ b/source/simulation/EntityStateProcessing.cpp @@ -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 )) { diff --git a/source/sound/SoundGroup.cpp b/source/sound/SoundGroup.cpp index cd6416c887..c731570e20 100644 --- a/source/sound/SoundGroup.cpp +++ b/source/sound/SoundGroup.cpp @@ -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= 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; diff --git a/source/sound/SoundGroup.h b/source/sound/SoundGroup.h index 4c74eba70d..2f26ef35c7 100644 --- a/source/sound/SoundGroup.h +++ b/source/sound/SoundGroup.h @@ -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 @@ -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;} }; diff --git a/source/sound/SoundGroupMgr.cpp b/source/sound/SoundGroupMgr.cpp index c538b4f977..620af8af38 100644 --- a/source/sound/SoundGroupMgr.cpp +++ b/source/sound/SoundGroupMgr.cpp @@ -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); } diff --git a/source/sound/SoundGroupMgr.h b/source/sound/SoundGroupMgr.h index 669740f3b2..94f7ba78de 100644 --- a/source/sound/SoundGroupMgr.h +++ b/source/sound/SoundGroupMgr.h @@ -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()