diff --git a/code/components/extra-natives-five/src/NuiAudioSink.cpp b/code/components/extra-natives-five/src/NuiAudioSink.cpp index ef0df755fc..22c7da972d 100644 --- a/code/components/extra-natives-five/src/NuiAudioSink.cpp +++ b/code/components/extra-natives-five/src/NuiAudioSink.cpp @@ -1319,7 +1319,7 @@ class MumbleAudioEntityBase virtual ~MumbleAudioEntityBase() = default; - virtual void MInit() = 0; + virtual void MInit(float overrideVolume) = 0; virtual void MShutdown() = 0; void SetPosition(float position[3], float distance, float overrideVolume) @@ -1352,11 +1352,6 @@ class MumbleAudioEntityBase m_poller = poller; } - int GetSubmixId() - { - return m_submixId; - } - void SetSubmixId(int id) { m_submixId = id; @@ -1414,7 +1409,7 @@ class MumbleAudioEntity : public rage::audEntity, public MumbleAudioEntit virtual void Shutdown() override; - virtual void MInit() override; + virtual void MInit(float overrideVolume) override; virtual void MShutdown() override; @@ -1489,7 +1484,7 @@ void MumbleAudioEntity::Init() { rage::audEntity::Init(); - MInit(); + MInit(m_overrideVolume); } template @@ -1512,10 +1507,9 @@ static constexpr int kExtraAudioBuckets = 6; static uint32_t bucketsUsed[kExtraAudioBuckets]; template -void MumbleAudioEntity::MInit() +void MumbleAudioEntity::MInit(float overrideVolume) { std::lock_guard _(m_render); - m_environmentGroup = naEnvironmentGroup::Create(); m_environmentGroup->Init(nullptr, 20.0f, 1000, 4000, 0.5f, 1000); m_environmentGroup->SetPosition(m_position); @@ -1530,9 +1524,18 @@ void MumbleAudioEntity::MInit() initValues.SetCategory(category); } +#ifdef GTA_FIVE initValues.SetPositional(true); initValues.SetEnvironmentGroup(m_environmentGroup); +#elif IS_RDR3 + if (overrideVolume < 0.0) + { + m_environmentGroup->SetPosition(m_position); + initValues.SetEnvironmentGroup(m_environmentGroup); + initValues.SetPositional(true); + } +#endif if (m_submixId >= 0) { @@ -1607,14 +1610,15 @@ template void MumbleAudioEntity::MShutdown() { std::lock_guard _(m_render); + auto sound = m_sound; - if (m_sound) + if (sound) { - std::exchange(m_sound, nullptr)->StopAndForget(false); - } + //trace("deleting sound (%s): %016llx\n", ToNarrow(m_name), (uintptr_t)sound); - // Owned by m_sound, released by rage::audSound::SetIsReferencedByGame - m_environmentGroup = nullptr; + sound->StopAndForget(false); + m_sound = nullptr; + } if (m_soundBucket != 0xFF) { @@ -1622,9 +1626,16 @@ void MumbleAudioEntity::MShutdown() m_soundBucket = -1; } - if (m_buffer) + // needs to be delayed to when the sound is removed + //delete m_environmentGroup; + m_environmentGroup = nullptr; + + auto buffer = m_buffer; + + if (buffer) { - std::exchange(m_buffer, nullptr)->Release(); + buffer->Release(); + m_buffer = nullptr; } } @@ -1788,6 +1799,10 @@ void MumbleAudioEntity::PreUpdateService(uint32_t) } } #endif + if (m_poller) + { + //m_poller(); + } } void MumbleAudioEntityBase::PushAudio(int16_t* pcm, int len) @@ -1830,6 +1845,10 @@ class MumbleAudioSink : public IMumbleAudioSink alignas(16) rage::Vec3V m_position; float m_distance; float m_overrideVolume; + float m_lastOverrideVolume = -1.0f; + + int m_lastSubmixId = -1; + int m_lastPed = -1; std::function m_poller; std::function m_resetti; @@ -1949,6 +1968,19 @@ void MumbleAudioSink::Process() #endif static auto getEntityAddress = fx::ScriptEngine::GetNativeHandler(HashString("GET_ENTITY_ADDRESS")); +#if 0 + if (m_serverId == 0) + { + if (!m_entity) + { + m_entity = std::make_shared(); + m_entity->Init(); + } + + return; + } +#endif + auto playerId = FxNativeInvoke::Invoke(getByServerId, m_serverId); bool isNoPlayer = (playerId > 256 || playerId == -1); @@ -1967,32 +1999,58 @@ void MumbleAudioSink::Process() if (isNoPlayer && m_overrideVolume <= 0.0f) { m_entity = {}; + m_lastPed = -1; } else { - if (!m_entity || (m_entity->GetSubmixId() != submixId)) + auto ped = (!isNoPlayer) ? FxNativeInvoke::Invoke(getPlayerPed, playerId) : 0; + + // pre-initialize ped + if (m_lastPed == -1) + { + m_lastPed = ped; + } + + if (!m_entity) { Reset(); - if (!m_entity) - { - m_entity = MakeMumbleAudioEntity([submixId](auto entity) { - entity->SetSubmixId(submixId); - }, m_name); - } - else + m_entity = MakeMumbleAudioEntity([this, submixId](MumbleAudioEntityBase* entity) { - m_entity->MShutdown(); - m_entity->SetSubmixId(submixId); - m_entity->MInit(); - } + entity->SetPoller(m_poller); + entity->SetSubmixId(submixId); + }, m_name); - m_entity->SetPoller(m_poller); + m_lastSubmixId = submixId; + } + + if (m_overrideVolume != m_lastOverrideVolume || + submixId != m_lastSubmixId || + ped != m_lastPed) + { + Reset(); + + m_lastOverrideVolume = m_overrideVolume; + m_lastSubmixId = submixId; + m_lastPed = ped; + + m_entity->MShutdown(); + m_entity->SetSubmixId(submixId); + m_entity->MInit(m_overrideVolume); } - auto ped = (!isNoPlayer) ? FxNativeInvoke::Invoke(getPlayerPed, playerId) : 0; - m_entity->SetBackingEntity((ped > 0) ? FxNativeInvoke::Invoke(getEntityAddress, ped) : nullptr); m_entity->SetPosition((float*)&m_position, m_distance, m_overrideVolume); + + if (ped > 0) + { + auto address = FxNativeInvoke::Invoke(getEntityAddress, ped); + + m_entity->SetBackingEntity(address); + } + else + { + m_entity->SetBackingEntity(nullptr); + } } }