From 3fbf7f4500f19f07b01d7b3bcf6ff2ee89ef58d8 Mon Sep 17 00:00:00 2001 From: Xottab-DUTY Date: Mon, 4 Dec 2023 07:58:04 +0500 Subject: [PATCH] Refactored ref_sound class --- src/xrEngine/IGame_Level.cpp | 13 +- src/xrEngine/IGame_Level.h | 4 +- src/xrGame/script_entity.h | 1 - src/xrGame/script_sound.cpp | 1 - src/xrGame/sound_player.cpp | 4 +- src/xrGame/sound_player_inline.h | 6 +- src/xrSound/Sound.h | 178 +++++++++++------- src/xrSound/SoundRender_Core.cpp | 146 ++++++-------- src/xrSound/SoundRender_Core.h | 15 +- src/xrSound/SoundRender_Core_Processor.cpp | 9 +- src/xrSound/SoundRender_Emitter.h | 4 +- src/xrSound/SoundRender_Emitter_StartStop.cpp | 4 +- 12 files changed, 193 insertions(+), 192 deletions(-) diff --git a/src/xrEngine/IGame_Level.cpp b/src/xrEngine/IGame_Level.cpp index 53a81bbaf09..d075673ec2c 100644 --- a/src/xrEngine/IGame_Level.cpp +++ b/src/xrEngine/IGame_Level.cpp @@ -71,11 +71,6 @@ void IGame_Level::net_Stop() //------------------------------------------------------------------------------------------- // extern CStatTimer tscreate; -void _sound_event(const ref_sound_data_ptr& S, float range) -{ - if (g_pGameLevel && S && S->feedback) - g_pGameLevel->SoundEvent_Register(S, range); -} static void build_callback(Fvector* V, int Vcnt, CDB::TRI* T, int Tcnt, void* params) { @@ -121,7 +116,11 @@ bool IGame_Level::Load(u32 dwNum) g_pGamePersistent->SpatialSpacePhysic.initialize(ObjectSpace.GetBoundingVolume()); GEnv.Sound->set_geometry_occ(ObjectSpace.GetStaticModel()); - GEnv.Sound->set_handler(_sound_event); + GEnv.Sound->set_handler([](const ref_sound& S, float range) + { + if (g_pGameLevel && S && S->feedback) + g_pGameLevel->SoundEvent_Register(S, range); + }); pApp->LoadSwitch(); @@ -258,7 +257,7 @@ void IGame_Level::SetViewEntity(IGameObject* O) pCurrentViewEntity = O; } -void IGame_Level::SoundEvent_Register(ref_sound_data_ptr S, float range) +void IGame_Level::SoundEvent_Register(const ref_sound& S, float range) { if (!g_bLoaded) return; diff --git a/src/xrEngine/IGame_Level.h b/src/xrEngine/IGame_Level.h index 00c565db531..66523e8d9ac 100644 --- a/src/xrEngine/IGame_Level.h +++ b/src/xrEngine/IGame_Level.h @@ -87,7 +87,7 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, struct _esound_delegate { Feel::Sound* dest; - ref_sound_data_ptr source; + ref_sound source; float power; }; xr_vector<_esound_delegate> snd_Events; @@ -129,7 +129,7 @@ class ENGINE_API IGame_Level : public FactoryObjectBase, void SetEntity(IGameObject* O); // { pCurrentEntity=pCurrentViewEntity=O; } void SetViewEntity(IGameObject* O); // { pCurrentViewEntity=O; } - void SoundEvent_Register(ref_sound_data_ptr S, float range); + void SoundEvent_Register(const ref_sound& S, float range); void SoundEvent_Dispatch(); void SoundEvent_OnDestDestroy(Feel::Sound*); diff --git a/src/xrGame/script_entity.h b/src/xrGame/script_entity.h index ec26a703404..ee5ec299b60 100644 --- a/src/xrGame/script_entity.h +++ b/src/xrGame/script_entity.h @@ -17,7 +17,6 @@ class CScriptEntityAction; class CEntity; class CScriptGameObject; class CCustomMonster; -class ref_sound; using namespace ScriptEntity; diff --git a/src/xrGame/script_sound.cpp b/src/xrGame/script_sound.cpp index 39362cd0b76..37875e8e3f3 100644 --- a/src/xrGame/script_sound.cpp +++ b/src/xrGame/script_sound.cpp @@ -19,7 +19,6 @@ CScriptSound::CScriptSound(LPCSTR caSoundName, ESoundTypes sound_type) m_bIsNoSound = !Engine.Sound.IsSoundEnabled(); m_caSoundToPlay = caSoundName; string_path l_caFileName; - VERIFY(GEnv.Sound); if (FS.exist(l_caFileName, "$game_sounds$", caSoundName, ".ogg")) m_sound.create(caSoundName, st_Effect, sound_type); else diff --git a/src/xrGame/sound_player.cpp b/src/xrGame/sound_player.cpp index 4a745d5a325..ea6a228ec31 100644 --- a/src/xrGame/sound_player.cpp +++ b/src/xrGame/sound_player.cpp @@ -199,8 +199,8 @@ void CSoundPlayer::play( **/ sound_single.m_sound->clone((*I).second.second->random(id), st_Effect, sg_SourceType); - sound_single.m_sound->_p->g_object = m_object; - sound_single.m_sound->_p->g_userdata = (*I).second.first.m_data; + sound_single.m_sound->_get()->g_object = m_object; + sound_single.m_sound->_get()->g_userdata = (*I).second.first.m_data; VERIFY(sound_single.m_sound->_handle()); VERIFY(max_start_time >= min_start_time); diff --git a/src/xrGame/sound_player_inline.h b/src/xrGame/sound_player_inline.h index e10ac9f8f91..a61ded956ab 100644 --- a/src/xrGame/sound_player_inline.h +++ b/src/xrGame/sound_player_inline.h @@ -46,12 +46,12 @@ IC ref_sound* CSoundPlayer::CSoundCollection::add(ESoundTypes type, LPCSTR name) { ref_sound* temp = xr_new(); temp->create(name, st_Effect, type); - if (!temp->_p) + if (!temp) { xr_delete(temp); - return (0); + return nullptr; } - return (temp); + return temp; } IC const CSoundPlayer::SOUND_COLLECTIONS& CSoundPlayer::objects() const { return (m_sounds); } diff --git a/src/xrSound/Sound.h b/src/xrSound/Sound.h index dd402e1f8da..d12dce13361 100644 --- a/src/xrSound/Sound.h +++ b/src/xrSound/Sound.h @@ -22,8 +22,8 @@ constexpr pcstr SNDENV_FILENAME = "sEnvironment.xr"; // refs class IGameObject; -class ref_sound; -class ref_sound_data; +class CSound; +struct resptrcode_sound; class XRSOUND_API CSound_params; class XRSOUND_API CSound_source; class XRSOUND_API CSound_emitter; @@ -190,10 +190,10 @@ class XRSOUND_API CSound_stats u32 _events; }; -typedef resptr_core> ref_sound_data_ptr; +using ref_sound = resptr_core; /// definition (Sound Callback) -typedef void sound_event(const ref_sound_data_ptr& S, float range); +typedef void sound_event(const ref_sound& S, float range); namespace CDB { @@ -204,9 +204,18 @@ namespace CDB class XRSOUND_API XR_NOVTABLE ISoundManager { protected: - friend class ref_sound_data; - virtual bool _create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; - virtual void _destroy_data(ref_sound_data& S) = 0; + friend class CSound; + friend struct resptrcode_sound; + + virtual CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; + virtual void destroy(CSound& S) = 0; + + virtual void attach_tail(CSound& S, pcstr fName) = 0; + + virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0; + virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0; + virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, + float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0; public: virtual ~ISoundManager() = default; @@ -214,21 +223,11 @@ class XRSOUND_API XR_NOVTABLE ISoundManager virtual void _restart() = 0; virtual bool i_locked() = 0; - virtual bool create(ref_sound& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) = 0; - virtual void attach_tail(ref_sound& S, pcstr fName) = 0; - 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 prefetch() = 0; virtual void stop_emitters() = 0; virtual int pause_emitters(bool val) = 0; - virtual void play(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f) = 0; - virtual void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) = 0; - virtual void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, - float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) = 0; - virtual void set_master_volume(float f = 1.f) = 0; virtual void set_geometry_env(IReader* I) = 0; virtual void set_geometry_som(IReader* I) = 0; @@ -284,36 +283,27 @@ class CSound_UserData : public xr_resource using CSound_UserDataPtr = resptr_core>; -class ref_sound_data : public xr_resource +class CSound : public xr_resource { public: //shared_str nm; - CSound_source* handle; //!< Pointer to wave-source interface - CSound_emitter* feedback; //!< Pointer to emitter, automatically clears on emitter-stop - esound_type s_type; - int g_type; //!< Sound type, usually for AI - IGameObject* g_object; //!< Game object that emits ref_sound - CSound_UserDataPtr g_userdata; - shared_str fn_attached[2]; + CSound_source* handle{}; //!< Pointer to wave-source interface + CSound_emitter* feedback{}; //!< Pointer to emitter, automatically clears on emitter-stop - u32 dwBytesTotal; - float fTimeTotal; + esound_type s_type{ st_Effect }; + int g_type{}; //!< Sound type, usually for AI - ref_sound_data() noexcept - : handle(0), feedback(0), s_type(st_Effect), g_type(0), g_object(0), dwBytesTotal(0), fTimeTotal(0) - { - } + IGameObject* g_object{}; //!< Game object that emits ref_sound + CSound_UserDataPtr g_userdata{}; + shared_str fn_attached[2]; - ref_sound_data(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) - { - GEnv.Sound->_create_data(*this, fName, sound_type, game_type, replaceWithNoSound); - } + u32 dwBytesTotal{}; + float fTimeTotal{}; - virtual ~ref_sound_data() { GEnv.Sound->_destroy_data(*this); } + ~CSound() override { GEnv.Sound->destroy(*this); } float get_length_sec() const { return fTimeTotal; } }; -inline void VerSndUnlocked() { VERIFY(!GEnv.Sound->i_locked()); } /*! \class ref_sound \brief Sound source + control @@ -321,63 +311,101 @@ The main class representing source/emitter interface This class in fact just hides internals and redirect calls to specific sub-systems */ -class ref_sound +struct resptrcode_sound : public resptr_base { -public: - ref_sound_data_ptr _p; + [[nodiscard]] + ICF CSound_source* _handle() const { return p_ ? p_->handle : nullptr; } + + [[nodiscard]] + ICF CSound_emitter* _feedback() const { return p_ ? p_->feedback : nullptr; } + + [[nodiscard]] + ICF IGameObject* _g_object() const { VERIFY(p_); return p_ ? p_->g_object : nullptr; } - ref_sound() = default; - ~ref_sound() = default; + [[nodiscard]] + ICF int _g_type() const { VERIFY(p_); return p_ ? p_->g_type : 0; } + + [[nodiscard]] + ICF esound_type _sound_type() const { VERIFY(p_); return p_ ? p_->s_type : st_Effect; } + + [[nodiscard]] + ICF CSound_UserDataPtr _g_userdata() const { VERIFY(p_); return p_ ? p_->g_userdata : nullptr; } - CSound_source* _handle() const { return _p ? _p->handle : nullptr; } - CSound_emitter* _feedback() const { return _p ? _p->feedback : nullptr; } - IGameObject* _g_object() { VERIFY(_p); return _p->g_object; } - int _g_type() { VERIFY(_p); return _p->g_type; } - esound_type _sound_type() { VERIFY(_p); return _p->s_type; } - CSound_UserDataPtr _g_userdata() { VERIFY(_p); return _p->g_userdata; } bool create(pcstr name, esound_type sound_type, int game_type, bool replaceWithNoSound = true) - { VerSndUnlocked(); return GEnv.Sound->create(*this, name, sound_type, game_type, replaceWithNoSound); } + { + VerSndUnlocked(); + _set(GEnv.Sound->create(name, sound_type, game_type, replaceWithNoSound)); + return _get(); + } - void attach_tail(pcstr name) - { VerSndUnlocked(); GEnv.Sound->attach_tail(*this, name); } + ICF void destroy() + { + VerSndUnlocked(); + _set(nullptr); + } - void clone(const ref_sound& from, esound_type sound_type, int game_type) - { VerSndUnlocked(); GEnv.Sound->clone(*this, from, sound_type, game_type); } + void attach_tail(pcstr name) const + { + VerSndUnlocked(); + if (!p_) + return; + GEnv.Sound->attach_tail(*p_, name); + } - void destroy() - { VerSndUnlocked(); GEnv.Sound->destroy(*this); } + void clone(const ref_sound& from, esound_type sound_type, int game_type) + { + if (!from._get()) + return; + _set(xr_new()); + p_->handle = from->handle; + p_->dwBytesTotal = from->dwBytesTotal; + p_->fTimeTotal = from->fTimeTotal; + p_->fn_attached[0] = from->fn_attached[0]; + p_->fn_attached[1] = from->fn_attached[1]; + p_->g_type = (game_type == sg_SourceType) ? p_->handle->game_type() : game_type; + p_->s_type = sound_type; + } void play(IGameObject* O, u32 flags = 0, float delay = 0.f) - { VerSndUnlocked(); GEnv.Sound->play(*this, O, flags, delay); } + { + VerSndUnlocked(); + GEnv.Sound->play(static_cast(*this), O, flags, delay); + } void play_at_pos(IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) - { VerSndUnlocked(); GEnv.Sound->play_at_pos(*this, O, pos, flags, delay); } + { + VerSndUnlocked(); + GEnv.Sound->play_at_pos(static_cast(*this), O, pos, flags, delay); + } void play_no_feedback(IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) - { VerSndUnlocked(); GEnv.Sound->play_no_feedback(*this, O, flags, delay, pos, vol, freq, range); } + { + VerSndUnlocked(); + GEnv.Sound->play_no_feedback(static_cast(*this), O, flags, delay, pos, vol, freq, range); + } - void stop() { VerSndUnlocked(); if (_feedback()) _feedback()->stop(false); } - void stop_deferred() { VerSndUnlocked(); if (_feedback()) _feedback()->stop(true ); } + ICF void stop() const { VerSndUnlocked(); if (_feedback()) _feedback()->stop(false); } + ICF void stop_deferred() const { VerSndUnlocked(); if (_feedback()) _feedback()->stop(true ); } - void set_position(const Fvector& pos) { VerSndUnlocked(); if (_feedback()) _feedback()->set_position(pos); } - void set_frequency(float freq) { VerSndUnlocked(); if (_feedback()) _feedback()->set_frequency(freq); } - void set_range(float min, float max) { VerSndUnlocked(); if (_feedback()) _feedback()->set_range(min, max); } - void set_volume(float vol) { VerSndUnlocked(); if (_feedback()) _feedback()->set_volume(vol); } - void set_priority(float p) { VerSndUnlocked(); if (_feedback()) _feedback()->set_priority(p); } - void set_time(float t) { VerSndUnlocked(); if (_feedback()) _feedback()->set_time(t); }; //--#SM+#-- + ICF void set_position(const Fvector& pos) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_position(pos); } + ICF void set_frequency(float freq) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_frequency(freq); } + ICF void set_range(float min, float max) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_range(min, max); } + ICF void set_volume(float vol) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_volume(vol); } + ICF void set_priority(float p) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_priority(p); } + ICF void set_time(float t) const { VerSndUnlocked(); if (_feedback()) _feedback()->set_time(t); }; //--#SM+#-- - const CSound_params* get_params() + [[nodiscard]] + ICF const CSound_params* get_params() const { VerSndUnlocked(); - return _feedback() ? _feedback()->get_params() : 0; + return _feedback() ? _feedback()->get_params() : nullptr; } - void set_params(CSound_params* p) + void set_params(CSound_params* p) const { VerSndUnlocked(); - CSound_emitter* const feedback = _feedback(); - if (feedback) + if (CSound_emitter* const feedback = _feedback()) { feedback->set_position(p->position); feedback->set_frequency(p->freq); @@ -386,7 +414,13 @@ class ref_sound } } - float get_length_sec() const { return _p ? _p->get_length_sec() : 0.0f; } + [[nodiscard]] + ICF float get_length_sec() const { return p_ ? p_->get_length_sec() : 0.0f; } + + IC static void VerSndUnlocked() + { + VERIFY(!GEnv.Sound->i_locked()); + } }; class XRSOUND_API CSound_stats_ext diff --git a/src/xrSound/SoundRender_Core.cpp b/src/xrSound/SoundRender_Core.cpp index 3226fb7e425..cf0a5771a99 100644 --- a/src/xrSound/SoundRender_Core.cpp +++ b/src/xrSound/SoundRender_Core.cpp @@ -225,20 +225,40 @@ void CSoundRender_Core::set_geometry_env(IReader* I) xr_free(_data); } -bool CSoundRender_Core::create(ref_sound& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) +CSound* CSoundRender_Core::create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) { if (!bPresent) - return S._handle() != nullptr; + return nullptr; - S._p = xr_new(fName, sound_type, game_type, replaceWithNoSound); + CSound_source* handle{}; - if (S._handle() == nullptr && !replaceWithNoSound) - S._p = nullptr; // no reason to keep it + string_path fn; + xr_strcpy(fn, fName); + if (strext(fn)) + *strext(fn) = 0; + const bool found = i_create_source(handle, fn, replaceWithNoSound); + const bool handleAvailable = found || replaceWithNoSound; + + if (!handleAvailable) + return nullptr; + + auto* snd = xr_new(); + + snd->handle = handle; + + snd->g_type = game_type; + if (game_type == sg_SourceType && handleAvailable) + snd->g_type = snd->handle->game_type(); + + snd->s_type = sound_type; + + snd->dwBytesTotal = handleAvailable ? snd->handle->bytes_total() : 0; + snd->fTimeTotal = handleAvailable ? snd->handle->length_sec() : 0.f; - return S._handle() != nullptr; + return snd; } -void CSoundRender_Core::attach_tail(ref_sound& S, pcstr fName) +void CSoundRender_Core::attach_tail(CSound& snd, pcstr fName) { if (!bPresent) return; @@ -246,50 +266,36 @@ void CSoundRender_Core::attach_tail(ref_sound& S, pcstr fName) xr_strcpy(fn, fName); if (strext(fn)) *strext(fn) = 0; - if (S._p->fn_attached[0].size() && S._p->fn_attached[1].size()) + if (!snd.fn_attached[0].empty() && !snd.fn_attached[1].empty()) { -#ifdef DEBUG - Msg("! 2 file already in queue [%s][%s]", S._p->fn_attached[0].c_str(), S._p->fn_attached[1].c_str()); -#endif // #ifdef DEBUG +#ifndef MASTER_GOLD + Msg("! 2 file already in queue [%s][%s]", snd.fn_attached[0].c_str(), snd.fn_attached[1].c_str()); +#endif return; } - u32 idx = S._p->fn_attached[0].size() ? 1 : 0; + const u32 idx = snd.fn_attached[0].empty() ? 0 : 1; - S._p->fn_attached[idx] = fn; + snd.fn_attached[idx] = fn; CSoundRender_Source* s = i_create_source(fn); - S._p->dwBytesTotal += s->bytes_total(); - S._p->fTimeTotal += s->length_sec(); - if (S._feedback()) - ((CSoundRender_Emitter*)S._feedback())->fTimeToStop += s->length_sec(); + snd.dwBytesTotal += s->bytes_total(); + snd.fTimeTotal += s->length_sec(); + if (snd.feedback) + ((CSoundRender_Emitter*)snd.feedback)->fTimeToStop += s->length_sec(); i_destroy_source(s); } -void CSoundRender_Core::clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) -{ - if (!bPresent) - return; - S._p = xr_new(); - S._p->handle = from._p->handle; - S._p->dwBytesTotal = from._p->dwBytesTotal; - S._p->fTimeTotal = from._p->fTimeTotal; - S._p->fn_attached[0] = from._p->fn_attached[0]; - S._p->fn_attached[1] = from._p->fn_attached[1]; - S._p->g_type = (game_type == sg_SourceType) ? S._p->handle->game_type() : game_type; - S._p->s_type = sound_type; -} - void CSoundRender_Core::play(ref_sound& S, IGameObject* O, u32 flags, float delay) { - if (!bPresent || nullptr == S._handle()) + if (!bPresent || !S._handle()) return; - S._p->g_object = O; + S->g_object = O; if (S._feedback()) ((CSoundRender_Emitter*)S._feedback())->rewind(); else - i_play(&S, flags, delay); + i_play(S, flags, delay); if (flags & sm_2D || S._handle()->channels_num() == 2) S._feedback()->switch_to_2D(); @@ -300,19 +306,19 @@ void CSoundRender_Core::play(ref_sound& S, IGameObject* O, u32 flags, float dela void CSoundRender_Core::play_no_feedback( ref_sound& S, IGameObject* O, u32 flags, float delay, Fvector* pos, float* vol, float* freq, Fvector2* range) { - if (!bPresent || nullptr == S._handle()) + if (!bPresent || !S._handle()) return; - ref_sound_data_ptr orig = S._p; - S._p = xr_new(); - S._p->handle = orig->handle; - S._p->g_type = orig->g_type; - S._p->g_object = O; - S._p->dwBytesTotal = orig->dwBytesTotal; - S._p->fTimeTotal = orig->fTimeTotal; - S._p->fn_attached[0] = orig->fn_attached[0]; - S._p->fn_attached[1] = orig->fn_attached[1]; - - i_play(&S, flags, delay); + const ref_sound orig = S; + S._set(xr_new()); + S->handle = orig->handle; + S->g_type = orig->g_type; + S->g_object = O; + S->dwBytesTotal = orig->dwBytesTotal; + S->fTimeTotal = orig->fTimeTotal; + S->fn_attached[0] = orig->fn_attached[0]; + S->fn_attached[1] = orig->fn_attached[1]; + + i_play(S, flags, delay); if (flags & sm_2D || S._handle()->channels_num() == 2) S._feedback()->switch_to_2D(); @@ -325,18 +331,18 @@ void CSoundRender_Core::play_no_feedback( S._feedback()->set_range((*range)[0], (*range)[1]); if (vol) S._feedback()->set_volume(*vol); - S._p = orig; + S = orig; } void CSoundRender_Core::play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags, float delay) { - if (!bPresent || nullptr == S._handle()) + if (!bPresent || !S._handle()) return; - S._p->g_object = O; + S->g_object = O; if (S._feedback()) ((CSoundRender_Emitter*)S._feedback())->rewind(); else - i_play(&S, flags, delay); + i_play(S, flags, delay); S._feedback()->set_position(pos); @@ -346,46 +352,14 @@ void CSoundRender_Core::play_at_pos(ref_sound& S, IGameObject* O, const Fvector& S._feedback()->set_ignore_time_factor(flags & sm_IgnoreTimeFactor); } -void CSoundRender_Core::destroy(ref_sound& S) +void CSoundRender_Core::destroy(CSound& S) { - if (S._feedback()) + if (auto* emitter = (CSoundRender_Emitter*)S.feedback) { - CSoundRender_Emitter* E = (CSoundRender_Emitter*)S._feedback(); - E->stop(false); + emitter->stop(false); + VERIFY(S.feedback == nullptr); } - S._p = nullptr; -} - -bool CSoundRender_Core::_create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound /*= true*/) -{ - string_path fn; - xr_strcpy(fn, fName); - if (strext(fn)) - *strext(fn) = 0; - const bool found = i_create_source(S.handle, fn, replaceWithNoSound); - const bool handleAvailable = found || replaceWithNoSound; - S.g_type = game_type; - if (game_type == sg_SourceType && handleAvailable) - S.g_type = S.handle->game_type(); - S.s_type = sound_type; - S.feedback = nullptr; - S.g_object = nullptr; - S.g_userdata = nullptr; - S.dwBytesTotal = handleAvailable ? S.handle->bytes_total() : 0; - S.fTimeTotal = handleAvailable ? S.handle->length_sec() : 0.f; - return found; -} - -void CSoundRender_Core::_destroy_data(ref_sound_data& S) -{ - if (S.feedback) - { - CSoundRender_Emitter* E = (CSoundRender_Emitter*)S.feedback; - E->stop(false); - } - R_ASSERT(nullptr == S.feedback); i_destroy_source((CSoundRender_Source*)S.handle); - S.handle = nullptr; } diff --git a/src/xrSound/SoundRender_Core.h b/src/xrSound/SoundRender_Core.h index b1a394514ce..2762b3290e6 100644 --- a/src/xrSound/SoundRender_Core.h +++ b/src/xrSound/SoundRender_Core.h @@ -22,9 +22,6 @@ class CSoundRender_Core : public ISoundManager volatile bool isLocked; protected: - bool _create_data(ref_sound_data& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; - void _destroy_data(ref_sound_data& S) override; - bool bListenerMoved; CSoundRender_Environment e_current; @@ -34,7 +31,7 @@ class CSoundRender_Core : public ISoundManager public: CSoundManager& Parent; - using event = std::pair; + using event = std::pair; xr_vector s_events; bool bPresent; @@ -89,11 +86,10 @@ class CSoundRender_Core : public ISoundManager // Sound interface void verify_refsound(ref_sound& S); - bool create(ref_sound& S, pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; - void attach_tail(ref_sound& S, pcstr fName) override; + CSound* create(pcstr fName, esound_type sound_type, int game_type, bool replaceWithNoSound = true) override; + void attach_tail(CSound& S, pcstr fName) override; - void clone(ref_sound& S, const ref_sound& from, esound_type sound_type, int game_type) override; - void destroy(ref_sound& S) override; + void destroy(CSound& S) override; void prefetch() override { @@ -109,6 +105,7 @@ class CSoundRender_Core : public ISoundManager void play_at_pos(ref_sound& S, IGameObject* O, const Fvector& pos, u32 flags = 0, float delay = 0.f) override; void play_no_feedback(ref_sound& S, IGameObject* O, u32 flags = 0, float delay = 0.f, Fvector* pos = nullptr, float* vol = nullptr, float* freq = nullptr, Fvector2* range = nullptr) override; + void set_master_volume(float f) override = 0; void set_geometry_env(IReader* I) override; void set_geometry_som(IReader* I) override; @@ -137,7 +134,7 @@ class CSoundRender_Core : public ISoundManager void i_create_all_sources(); void i_destroy_source(CSoundRender_Source* S); - CSoundRender_Emitter* i_play(ref_sound* S, u32 flags, float delay); + CSoundRender_Emitter* i_play(const ref_sound& S, u32 flags, float delay); void i_start(CSoundRender_Emitter* E); void i_stop(CSoundRender_Emitter* E); void i_rewind(CSoundRender_Emitter* E); diff --git a/src/xrSound/SoundRender_Core_Processor.cpp b/src/xrSound/SoundRender_Core_Processor.cpp index 0dd688187a1..3f6f5eedea6 100644 --- a/src/xrSound/SoundRender_Core_Processor.cpp +++ b/src/xrSound/SoundRender_Core_Processor.cpp @@ -9,13 +9,12 @@ #include "SoundRender_Target.h" #include "SoundRender_Source.h" -CSoundRender_Emitter* CSoundRender_Core::i_play(ref_sound* S, u32 flags, float delay) +CSoundRender_Emitter* CSoundRender_Core::i_play(const ref_sound& S, u32 flags, float delay) { - VERIFY(S->_p->feedback == 0); - CSoundRender_Emitter* E = xr_new(); - S->_p->feedback = E; + VERIFY(S._get()->feedback == nullptr); + CSoundRender_Emitter* E = s_emitters.emplace_back(xr_new()); + S._get()->feedback = E; E->start(S, flags, delay); - s_emitters.push_back(E); return E; } diff --git a/src/xrSound/SoundRender_Emitter.h b/src/xrSound/SoundRender_Emitter.h index 938066b9b57..001e2d19b20 100644 --- a/src/xrSound/SoundRender_Emitter.h +++ b/src/xrSound/SoundRender_Emitter.h @@ -34,7 +34,7 @@ class CSoundRender_Emitter final : public CSound_emitter static constexpr float TIME_TO_STOP_INFINITE = static_cast(0xffffffff); CSoundRender_Target* target; - ref_sound_data_ptr owner_data; + ref_sound owner_data; [[nodiscard]] CSoundRender_Source* source() const { return (CSoundRender_Source*)owner_data->handle; } @@ -108,7 +108,7 @@ class CSoundRender_Emitter final : public CSound_emitter void fill_data(u8* ptr, u32 offset, u32 size); float priority(); - void start(ref_sound* _owner, u32 flags, float delay); + void start(const ref_sound& _owner, u32 flags, float delay); void cancel(); // manager forces out of rendering void update(float time, float dt); bool update_culling(float dt); diff --git a/src/xrSound/SoundRender_Emitter_StartStop.cpp b/src/xrSound/SoundRender_Emitter_StartStop.cpp index a32f26c40ef..f61ed499831 100644 --- a/src/xrSound/SoundRender_Emitter_StartStop.cpp +++ b/src/xrSound/SoundRender_Emitter_StartStop.cpp @@ -5,14 +5,14 @@ #include "SoundRender_Emitter.h" #include "SoundRender_Source.h" -void CSoundRender_Emitter::start(ref_sound* _owner, u32 flags, float delay) +void CSoundRender_Emitter::start(const ref_sound& _owner, u32 flags, float delay) { const bool _loop = flags & sm_Looped; bIgnoringTimeFactor = flags & sm_IgnoreTimeFactor; starting_delay = delay; VERIFY(_owner); - owner_data = _owner->_p; + owner_data = _owner; VERIFY(owner_data); // source = (CSoundRender_Source*)owner_data->handle; p_source.position.set(0, 0, 0);