Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion src/xrEngine/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,9 @@ void CRenderDevice::End(void)
#endif // #ifdef INGAME_EDITOR
if (dwPrecacheFrame)
{
::Sound->set_master_volume(0.f);
// Level precache mutes the OpenAL listener; skip while persistent PDA/music plays
if (::Sound && !::Sound->has_playing_persistent())
::Sound->set_master_volume(0.f);
dwPrecacheFrame--;

if (!dwPrecacheFrame)
Expand Down Expand Up @@ -366,6 +368,11 @@ void CRenderDevice::on_idle()
if (g_loading_events.front()())
g_loading_events.pop_front();
}
// Keep listener snapshot fresh; SoundRender_UpdateThread refills OpenAL buffers
#ifndef DEDICATED_SERVER
if (::Sound)
::Sound->update(Device.vCameraPosition, Device.vCameraDirection, Device.vCameraTop);
#endif
PROF_EVENT("LoadDraw");
pApp->LoadDraw();
return;
Expand Down
5 changes: 2 additions & 3 deletions src/xrEngine/x_ray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,8 +1395,8 @@ CApplication::CApplication()
// Register us
Device.seqFrame.Add(this, REG_PRIORITY_HIGH + 1000);

if (psDeviceFlags.test(mtSound)) Device.seqFrameMT.Add(&SoundProcessor);
else Device.seqFrame.Add(&SoundProcessor);
// OpenAL updates run on SoundRender_UpdateThread; main thread only refreshes listener snapshot
Device.seqFrame.Add(&SoundProcessor);

Console->Show();

Expand All @@ -1414,7 +1414,6 @@ CApplication::~CApplication()
// font
xr_delete(pFontSystem);

Device.seqFrameMT.Remove(&SoundProcessor);
Device.seqFrame.Remove(&SoundProcessor);
Device.seqFrame.Remove(this);

Expand Down
29 changes: 28 additions & 1 deletion src/xrEngine/xr_ioc_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "CustomHUD.h"

#include "../Include/xrRender/RenderDeviceRender.h"
#include "../xrSound/Sound.h"

#include "xr_object.h"
#include "MonitorList.h"
Expand Down Expand Up @@ -599,6 +600,18 @@ class CCC_SND_Restart : public IConsole_Command
}
};

class CCC_SndStopPersistent : public IConsole_Command
{
public:
CCC_SndStopPersistent(LPCSTR N) : IConsole_Command(N) { bEmptyArgsHandled = TRUE; };

virtual void Execute(LPCSTR args)
{
if (Sound)
Sound->stop_persistent_emitters();
}
};

//-----------------------------------------------------------------------
float ps_gamma = 1.f, ps_brightness = 1.f, ps_contrast = 1.f;

Expand Down Expand Up @@ -953,6 +966,19 @@ class CCC_SoundParamsSmoothing : public CCC_Integer
}
};

class CCC_SndMT : public CCC_Mask
{
public:
CCC_SndMT(LPCSTR N, Flags32* V, u32 M) : CCC_Mask(N, V, M) {};

virtual void Execute(LPCSTR args)
{
CCC_Mask::Execute(args);
if (Sound)
Sound->set_thread_enabled(GetValue() != FALSE);
}
};

class CCC_Editor : public IConsole_Command
{
public:
Expand Down Expand Up @@ -1022,6 +1048,7 @@ void CCC_Register()
CMD1(CCC_LoadCFG, "cfg_load");

CMD3(CCC_Mask, "mt_particles", &psDeviceFlags, mtParticles);
CMD3(CCC_SndMT, "mt_sound", &psDeviceFlags, mtSound);

#ifdef DEBUG
CMD1(CCC_MotionsStat, "stat_motions");
Expand All @@ -1038,7 +1065,6 @@ void CCC_Register()
CMD1(CCC_DbgStrCheck, "dbg_str_check");
CMD1(CCC_DbgStrDump, "dbg_str_dump");

CMD3(CCC_Mask, "mt_sound", &psDeviceFlags, mtSound);
CMD3(CCC_Mask, "mt_physics", &psDeviceFlags, mtPhysics);
CMD3(CCC_Mask, "mt_network", &psDeviceFlags, mtNetwork);

Expand Down Expand Up @@ -1118,6 +1144,7 @@ void CCC_Register()
CMD2(CCC_Float, "snd_volume_eff", &psSoundVEffects);
CMD2(CCC_Float, "snd_volume_music", &psSoundVMusic);
CMD1(CCC_SND_Restart, "snd_restart");
CMD1(CCC_SndStopPersistent, "snd_stop_persistent");
CMD3(CCC_Mask, "snd_acceleration", &psSoundFlags, ss_Hardware);
CMD3(CCC_Mask, "snd_efx", &psSoundFlags, ss_EFX);
CMD4(CCC_Float, "snd_efx_environment_change_time", &snd_efx_environment_change_time, 0.f, 3.f);
Expand Down
65 changes: 63 additions & 2 deletions src/xrGame/script_sound.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "gameobject.h"
#include "ai_space.h"
#include "script_engine.h"
#include "../xrSound/Sound.h"

CScriptSound::CScriptSound(LPCSTR caSoundName, ESoundTypes sound_type)
{
Expand Down Expand Up @@ -50,23 +51,83 @@ Fvector CScriptSound::GetPosition() const
}
}

void CScriptSound::apply_pending_persistent()
{
CSound_emitter* emitter = active_emitter(false);
if (!m_bPersistentPending || !emitter)
return;
emitter->set_persistent_in_menu(m_bPersistentInMenuPending);
emitter->set_persistent(true);
m_bPersistentPending = false;
}

CSound_emitter* CScriptSound::active_emitter(bool reconcile)
{
if (m_sound._feedback())
return m_sound._feedback();
if (reconcile)
m_sound.reconcile_feedback();
return m_sound._feedback();
}

void CScriptSound::Play(CScriptGameObject* object, float delay, int flags)
{
THROW3(m_sound._handle(), "There is no sound", *m_caSoundToPlay);
// Msg ("%6d : CScriptSound::Play (%s), delay %f, flags %d",Device.dwTimeGlobal,m_sound._handle()->file_name(),delay,flags);
m_sound.play((object) ? &object->object() : NULL, flags, delay);
apply_pending_persistent();
}

void CScriptSound::PlayAtPos(CScriptGameObject* object, const Fvector& position, float delay, int flags)
{
THROW3(m_sound._handle(), "There is no sound", *m_caSoundToPlay);
// Msg ("%6d : CScriptSound::Play (%s), delay %f, flags %d",m_sound._handle()->file_name(),delay,flags);
m_sound.play_at_pos((object) ? &object->object() : NULL, position, flags, delay);
apply_pending_persistent();
}

void CScriptSound::PlayNoFeedback(CScriptGameObject* object, u32 flags/*!< Looping */, float delay/*!< Delay */,
Fvector pos, float vol, float freq)
{
THROW3(m_sound._handle(), "There is no sound", *m_caSoundToPlay);
m_sound.play_no_feedback((object) ? &object->object() : NULL, flags, delay, &pos, &vol, &freq);
apply_pending_persistent();
}

void CScriptSound::set_persistent(bool bPersist)
{
set_persistent(bPersist, m_bPersistentInMenuPending);
}

void CScriptSound::set_persistent(bool bPersist, bool bPersistInMenu)
{
m_bPersistentInMenuPending = bPersistInMenu;
CSound_emitter* emitter = active_emitter();
if (!emitter)
{
m_bPersistentPending = bPersist;
if (!bPersist && Sound && m_sound._p)
Sound->stop_emitters_for_owner(m_sound._p._get());
return;
}
emitter->set_persistent_in_menu(bPersistInMenu);
emitter->set_persistent(bPersist);
m_bPersistentPending = false;
}

void CScriptSound::Stop()
{
m_sound.stop();
}

bool CScriptSound::is_persistent() const
{
if (CSound_emitter* emitter = m_sound._feedback())
return emitter->is_persistent();
return m_bPersistentPending;
}

bool CScriptSound::is_persistent_in_menu() const
{
if (CSound_emitter* emitter = m_sound._feedback())
return emitter->is_persistent_in_menu();
return m_bPersistentInMenuPending;
}
13 changes: 12 additions & 1 deletion src/xrGame/script_sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "ai_sounds.h"

class CScriptGameObject;
class CSound_emitter;

class CScriptSound
{
Expand All @@ -33,7 +34,7 @@ class CScriptSound
void PlayNoFeedback(CScriptGameObject* object, u32 flags/*!< Looping */, float delay/*!< Delay */, Fvector pos,
float vol, float freq);
IC void AttachTail(LPCSTR caSoundName);
IC void Stop();
void Stop();
IC void StopDeffered();
IC void SetPosition(const Fvector& position);
IC void SetFrequency(float frequency);
Expand All @@ -48,6 +49,16 @@ class CScriptSound
IC const float GetMaxDistance() const;
IC const float GetVolume() const;
IC bool IsPlaying() const;
void set_persistent(bool bPersist);
void set_persistent(bool bPersist, bool bPersistInMenu);
bool is_persistent() const;
bool is_persistent_in_menu() const;

private:
void apply_pending_persistent();
CSound_emitter* active_emitter(bool reconcile = true);
bool m_bPersistentPending = false;
bool m_bPersistentInMenuPending = true;

DECLARE_SCRIPT_REGISTER_FUNCTION
};
Expand Down
8 changes: 1 addition & 7 deletions src/xrGame/script_sound_inline.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,20 +74,14 @@ IC bool CScriptSound::IsPlaying() const
{
// commented for comfort work with -nosound command line option
// VERIFY (m_sound._handle());
return (!!m_sound._feedback());
return m_sound.has_playing_emitter();
}

IC void CScriptSound::AttachTail(LPCSTR caSoundName)
{
m_sound.attach_tail(caSoundName);
}

IC void CScriptSound::Stop()
{
VERIFY(m_sound._handle());
m_sound.stop();
}

IC void CScriptSound::StopDeffered()
{
VERIFY(m_sound._handle());
Expand Down
4 changes: 4 additions & 0 deletions src/xrGame/script_sound_script.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,5 +54,9 @@ void CScriptSound::script_register(lua_State* L)
.def("playing", &CScriptSound::IsPlaying)
.def("length", &CScriptSound::Length)
.def("attach_tail", &CScriptSound::AttachTail)
.def("set_persistent", (void (CScriptSound::*)(bool))(&CScriptSound::set_persistent))
.def("set_persistent", (void (CScriptSound::*)(bool, bool))(&CScriptSound::set_persistent))
.def("is_persistent", &CScriptSound::is_persistent)
.def("is_persistent_in_menu", &CScriptSound::is_persistent_in_menu)
];
}
39 changes: 37 additions & 2 deletions src/xrSound/Sound.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ XRSOUND_API extern float psSpeedOfSound;
XRSOUND_API extern int psSoundCacheSizeMB;
XRSOUND_API extern xr_token* snd_devices_token;
XRSOUND_API extern xr_string snd_device_name;

// reverb overwrite
extern BOOL reverb_overwrite;

Expand Down Expand Up @@ -213,6 +212,8 @@ struct ref_sound

IC void stop();
IC void stop_deffered();
IC void reconcile_feedback();
IC bool has_playing_emitter() const;
IC void set_position(const Fvector& pos);
IC void set_frequency(float freq);
IC void set_range(float min, float max);
Expand Down Expand Up @@ -333,6 +334,12 @@ class XRSOUND_API CSound_emitter
virtual void stop(BOOL bDeffered) = 0;
virtual const CSound_params* get_params() = 0;
virtual u32 play_time() = 0;

// Survive level unload (implementation forces 2D when enabled).
virtual void set_persistent(bool bPersist) = 0;
virtual bool is_persistent() const = 0;
virtual void set_persistent_in_menu(bool bPersistInMenu) = 0;
virtual bool is_persistent_in_menu() const = 0;
};

/// definition (Sound Stream Interface)
Expand Down Expand Up @@ -411,6 +418,13 @@ class XRSOUND_API CSound_manager_interface
virtual void clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) = 0;
virtual void destroy(ref_sound& S) = 0;
virtual void stop_emitters() = 0;
virtual void stop_persistent_emitters() = 0; // force-stops ALL persistent emitters
virtual void stop_emitters_for_owner(ref_sound_data* owner) = 0;
virtual bool has_playing_emitter_for_owner(ref_sound_data* owner) const = 0;
virtual bool reconcile_emitter_feedback(ref_sound_data* owner) = 0;
virtual bool has_playing_persistent() const = 0;
virtual void set_thread_enabled(bool enabled) = 0; // mt_sound: run OpenAL updates on the worker thread (1) or the main thread (0)
virtual bool thread_enabled() const = 0;
virtual int pause_emitters(bool val) = 0;

virtual void play(ref_sound& S, CObject* O, u32 flags = 0, float delay = 0.f) = 0;
Expand Down Expand Up @@ -535,10 +549,31 @@ IC void ref_sound::set_priority(float p)
if (_feedback()) _feedback()->set_priority(p);
}

IC void ref_sound::reconcile_feedback()
{
if (!_p || _p->feedback || !::Sound)
return;
VERIFY(!::Sound->i_locked());
::Sound->reconcile_emitter_feedback(_p._get());
}

IC bool ref_sound::has_playing_emitter() const
{
if (!_p)
return false;
if (_p->feedback)
return true;
return ::Sound && ::Sound->has_playing_emitter_for_owner(_p._get());
}

IC void ref_sound::stop()
{
VERIFY(!::Sound->i_locked());
if (_feedback()) _feedback()->stop(FALSE);
reconcile_feedback();
if (_feedback())
_feedback()->stop(FALSE);
else if (_p && ::Sound)
::Sound->stop_emitters_for_owner(_p._get());
}

IC void ref_sound::stop_deffered()
Expand Down
Loading