From cf3c177046a6e75c07e1c8919197de7c2cca503b Mon Sep 17 00:00:00 2001 From: "seer-by-sentry[bot]" <157164994+seer-by-sentry[bot]@users.noreply.github.com> Date: Sun, 4 Jan 2026 11:32:04 +0000 Subject: [PATCH] Prevent 3D sample allocation during Miles audio provider initialization --- .../MilesAudioDevice/MilesAudioManager.h | 1 + .../MilesAudioDevice/MilesAudioManager.cpp | 32 +++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h index 314a8b8770c..5be42512450 100644 --- a/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h +++ b/Core/GameEngineDevice/Include/MilesAudioDevice/MilesAudioManager.h @@ -282,6 +282,7 @@ class MilesAudioManager : public AudioManager UnsignedInt m_selectedProvider; UnsignedInt m_lastProvider; UnsignedInt m_selectedSpeakerType; + Bool m_providerInitializing; AsciiString m_pref3DProvider; AsciiString m_prefSpeaker; diff --git a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index 973669ed6b4..48dbf4a7ba3 100644 --- a/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Core/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -92,7 +92,8 @@ MilesAudioManager::MilesAudioManager() : m_delayFilter(NULL), m_binkHandle(NULL), m_pref3DProvider(AsciiString::TheEmptyString), - m_prefSpeaker(AsciiString::TheEmptyString) + m_prefSpeaker(AsciiString::TheEmptyString), + m_providerInitializing(FALSE) { m_audioCache = NEW AudioFileCache; } @@ -1225,6 +1226,12 @@ HSAMPLE MilesAudioManager::getFirst2DSample( AudioEventRTS *event ) //------------------------------------------------------------------------------------------------- H3DSAMPLE MilesAudioManager::getFirst3DSample( AudioEventRTS *event ) { + // Don't allocate 3D samples while provider is still initializing + // This prevents race conditions where samples are used before DirectSound buffers are fully set up + if (m_providerInitializing) { + return NULL; + } + if (m_available3DSamples.begin() != m_available3DSamples.end()) { H3DSAMPLE retSample = *m_available3DSamples.begin(); m_available3DSamples.erase(m_available3DSamples.begin()); @@ -1722,6 +1729,10 @@ void MilesAudioManager::selectProvider( UnsignedInt providerNdx ) { providerNdx = getProviderIndex( "Miles Fast 2D Positional Audio" ); } + + // Set initialization flag to prevent samples from being used before provider is ready + m_providerInitializing = TRUE; + success = AIL_open_3D_provider( m_provider3D[providerNdx].id ) == 0; //if (providerNdx < m_providerCount) @@ -1743,14 +1754,31 @@ void MilesAudioManager::selectProvider( UnsignedInt providerNdx ) { m_selectedProvider = providerNdx; + // Create listener first to ensure provider has proper context + createListener(); + + // Force the provider to complete internal initialization by updating listener position + // This ensures DirectSound buffers are fully set up before sample allocation + if (m_listener) { + AIL_update_3D_position(m_listener); + } + + // Now it's safe to initialize sample pools initSamplePools(); - createListener(); setSpeakerType(m_selectedSpeakerType); if (TheVideoPlayer) { TheVideoPlayer->notifyVideoPlayerOfNewProvider(TRUE); } + + // Clear initialization flag - provider is now fully ready + m_providerInitializing = FALSE; + } + else + { + // Failed to open provider, clear initialization flag + m_providerInitializing = FALSE; } }