From 038037e52445db79563ec4f182ac5f44fd7eb64f Mon Sep 17 00:00:00 2001 From: Robert Beckebans Date: Thu, 3 Jan 2013 16:56:25 +0100 Subject: [PATCH] Replaced most XAudio2 calls with OpenAL --- neo/CMakeLists.txt | 4 + neo/sound/OpenAL/AL_SoundHardware.cpp | 226 ++++++-------------------- neo/sound/OpenAL/AL_SoundHardware.h | 28 +++- neo/sound/OpenAL/AL_SoundSample.cpp | 3 +- neo/sound/OpenAL/AL_SoundSample.h | 1 + neo/sound/OpenAL/AL_SoundVoice.cpp | 136 +++++++++++----- neo/sound/OpenAL/AL_SoundVoice.h | 10 +- neo/sound/snd_local.h | 15 +- neo/sound/snd_system.cpp | 7 + 9 files changed, 200 insertions(+), 230 deletions(-) diff --git a/neo/CMakeLists.txt b/neo/CMakeLists.txt index b702c4ed..ec09fdcc 100644 --- a/neo/CMakeLists.txt +++ b/neo/CMakeLists.txt @@ -1048,6 +1048,9 @@ if(MSVC) list(APPEND RBDOOM3_INCLUDES ${OPENAL_INCLUDES}) list(APPEND RBDOOM3_SOURCES ${OPENAL_SOURCES}) + + set(OpenAL_LIBRARIES + OpenAL32) else() add_definitions(-DUSE_DOOMCLASSIC) @@ -1152,6 +1155,7 @@ if(MSVC) iphlpapi winmm wsock32.lib + ${OpenAL_LIBRARIES} ) #CMAKE_BINARY_DIR diff --git a/neo/sound/OpenAL/AL_SoundHardware.cpp b/neo/sound/OpenAL/AL_SoundHardware.cpp index 45632fd3..110b7ac5 100644 --- a/neo/sound/OpenAL/AL_SoundHardware.cpp +++ b/neo/sound/OpenAL/AL_SoundHardware.cpp @@ -3,7 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. -Copyright (C) 2012 Robert Beckebans +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -45,15 +45,14 @@ idSoundHardware_OpenAL::idSoundHardware_OpenAL */ idSoundHardware_OpenAL::idSoundHardware_OpenAL() { - pXAudio2 = NULL; - pMasterVoice = NULL; - pSubmixVoice = NULL; + openalDevice = NULL; + openalContext = NULL; - vuMeterRMS = NULL; - vuMeterPeak = NULL; + //vuMeterRMS = NULL; + //vuMeterPeak = NULL; - outputChannels = 0; - channelMask = 0; + //outputChannels = 0; + //channelMask = 0; voices.SetNum( 0 ); zombieVoices.SetNum( 0 ); @@ -64,19 +63,8 @@ idSoundHardware_OpenAL::idSoundHardware_OpenAL() void listDevices_f( const idCmdArgs& args ) { - - IXAudio2* pXAudio2 = soundSystemLocal.hardware.GetIXAudio2(); - - if( pXAudio2 == NULL ) - { - idLib::Warning( "No xaudio object" ); - return; - } - -// RB: not available on Windows 8 SDK -#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) - - // FIXME +#if 1 + // TODO idLib::Warning( "No audio devices found" ); return; @@ -211,139 +199,46 @@ idSoundHardware_OpenAL::Init */ void idSoundHardware_OpenAL::Init() { - cmdSystem->AddCommand( "listDevices", listDevices_f, 0, "Lists the connected sound devices", NULL ); - DWORD xAudioCreateFlags = 0; + common->Printf( "Setup OpenAL device and context... " ); -// RB: not available on Windows 8 SDK -#if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG) - xAudioCreateFlags |= XAUDIO2_DEBUG_ENGINE; -#endif -// RB end - - XAUDIO2_PROCESSOR xAudioProcessor = XAUDIO2_DEFAULT_PROCESSOR; - -// RB: not available on Windows 8 SDK - if( FAILED( XAudio2Create( &pXAudio2, xAudioCreateFlags, xAudioProcessor ) ) ) + openalDevice = alcOpenDevice( NULL ); + if( openalDevice == NULL ) { -#if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) && defined(_DEBUG) - if( xAudioCreateFlags & XAUDIO2_DEBUG_ENGINE ) - { - // in case the debug engine isn't installed - xAudioCreateFlags &= ~XAUDIO2_DEBUG_ENGINE; - if( FAILED( XAudio2Create( &pXAudio2, xAudioCreateFlags, xAudioProcessor ) ) ) - { - idLib::FatalError( "Failed to create XAudio2 engine. Try installing the latest DirectX." ); - return; - } - } - else -#endif -// RB end - { - idLib::FatalError( "Failed to create XAudio2 engine. Try installing the latest DirectX." ); - return; - } - } -#ifdef _DEBUG - XAUDIO2_DEBUG_CONFIGURATION debugConfiguration = { 0 }; - debugConfiguration.TraceMask = XAUDIO2_LOG_WARNINGS; - debugConfiguration.BreakMask = XAUDIO2_LOG_ERRORS; - pXAudio2->SetDebugConfiguration( &debugConfiguration ); -#endif - - // Register the sound engine callback - pXAudio2->RegisterForCallbacks( &soundEngineCallback ); - soundEngineCallback.hardware = this; - -// RB: not available on Windows 8 SDK -#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/) - - // FIXME - - idLib::Warning( "No audio devices found" ); - pXAudio2->Release(); - pXAudio2 = NULL; - return; -#else - UINT32 deviceCount = 0; - if( pXAudio2->GetDeviceCount( &deviceCount ) != S_OK || deviceCount == 0 ) - { - idLib::Warning( "No audio devices found" ); - pXAudio2->Release(); - pXAudio2 = NULL; + common->FatalError( "idSoundHardware_OpenAL::Init: alcOpenDevice() failed\n" ); return; } - idCmdArgs args; - listDevices_f( args ); - - int preferredDevice = s_device.GetInteger(); - if( preferredDevice < 0 || preferredDevice >= ( int )deviceCount ) + openalContext = alcCreateContext( openalDevice, NULL ); + if( alcMakeContextCurrent( openalContext ) == 0 ) { - int preferredChannels = 0; - for( unsigned int i = 0; i < deviceCount; i++ ) - { - XAUDIO2_DEVICE_DETAILS deviceDetails; - if( pXAudio2->GetDeviceDetails( i, &deviceDetails ) != S_OK ) - { - continue; - } - - if( deviceDetails.Role & DefaultGameDevice ) - { - // if we find a device the user marked as their preferred 'game' device, then always use that - preferredDevice = i; - preferredChannels = deviceDetails.OutputFormat.Format.nChannels; - break; - } - - if( deviceDetails.OutputFormat.Format.nChannels > preferredChannels ) - { - preferredDevice = i; - preferredChannels = deviceDetails.OutputFormat.Format.nChannels; - } - } - } - - idLib::Printf( "Using device %d\n", preferredDevice ); - - XAUDIO2_DEVICE_DETAILS deviceDetails; - if( pXAudio2->GetDeviceDetails( preferredDevice, &deviceDetails ) != S_OK ) - { - // One way this could happen is if a device is removed between the loop and this line of code - // Highly unlikely but possible - idLib::Warning( "Failed to get device details" ); - pXAudio2->Release(); - pXAudio2 = NULL; + common->FatalError( "idSoundHardware_OpenAL::Init: alcMakeContextCurrent( %p) failed\n", openalContext ); return; } - DWORD outputSampleRate = 44100; // Max( (DWORD)XAUDIO2FX_REVERB_MIN_FRAMERATE, Min( (DWORD)XAUDIO2FX_REVERB_MAX_FRAMERATE, deviceDetails.OutputFormat.Format.nSamplesPerSec ) ); + common->Printf( "Done.\n" ); - if( FAILED( pXAudio2->CreateMasteringVoice( &pMasterVoice, XAUDIO2_DEFAULT_CHANNELS, outputSampleRate, 0, preferredDevice, NULL ) ) ) - { - idLib::Warning( "Failed to create master voice" ); - pXAudio2->Release(); - pXAudio2 = NULL; - return; - } - pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) ); + common->Printf( "OpenAL vendor: %s\n", alGetString( AL_VENDOR ) ); + common->Printf( "OpenAL renderer: %s\n", alGetString( AL_RENDERER ) ); + common->Printf( "OpenAL version: %s\n", alGetString( AL_VERSION ) ); - outputChannels = deviceDetails.OutputFormat.Format.nChannels; - channelMask = deviceDetails.OutputFormat.dwChannelMask; + //pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) ); - idSoundVoice::InitSurround( outputChannels, channelMask ); + //outputChannels = deviceDetails.OutputFormat.Format.nChannels; + //channelMask = deviceDetails.OutputFormat.dwChannelMask; + + //idSoundVoice::InitSurround( outputChannels, channelMask ); // --------------------- // Initialize the Doom classic sound system. // --------------------- - I_InitSoundHardware( outputChannels, channelMask ); + //I_InitSoundHardware( outputChannels, channelMask ); // --------------------- // Create VU Meter Effect // --------------------- + /* IUnknown* vuMeter = NULL; XAudio2CreateVolumeMeter( &vuMeter, 0 ); @@ -359,11 +254,13 @@ void idSoundHardware_OpenAL::Init() pMasterVoice->SetEffectChain( &chain ); vuMeter->Release(); + */ // --------------------- // Create VU Meter Graph // --------------------- + /* vuMeterRMS = console->CreateGraph( outputChannels ); vuMeterPeak = console->CreateGraph( outputChannels ); vuMeterRMS->Enable( false ); @@ -388,16 +285,9 @@ void idSoundHardware_OpenAL::Init() vuMeterRMS->SetLabel( i, channelNames[ ci ] ); i++; } + */ - // --------------------- - // Create submix buffer - // --------------------- - if( FAILED( pXAudio2->CreateSubmixVoice( &pSubmixVoice, 1, outputSampleRate, 0, 0, NULL, NULL ) ) ) - { - idLib::FatalError( "Failed to create submix voice" ); - } - - // XAudio doesn't really impose a maximum number of voices + // OpenAL doesn't really impose a maximum number of sources voices.SetNum( voices.Max() ); freeVoices.SetNum( voices.Max() ); zombieVoices.SetNum( 0 ); @@ -405,8 +295,6 @@ void idSoundHardware_OpenAL::Init() { freeVoices[i] = &voices[i]; } -#endif // #if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) -// RB end } /* @@ -424,37 +312,21 @@ void idSoundHardware_OpenAL::Shutdown() freeVoices.Clear(); zombieVoices.Clear(); + alcMakeContextCurrent( NULL ); + + alcDestroyContext( openalContext ); + openalContext = NULL; + + alcCloseDevice( openalDevice ); + openalDevice = NULL; + + // --------------------- // Shutdown the Doom classic sound system. // --------------------- //I_ShutdownSoundHardware(); - if( pXAudio2 != NULL ) - { - // Unregister the sound engine callback - pXAudio2->UnregisterForCallbacks( &soundEngineCallback ); - } - - if( pSubmixVoice != NULL ) - { - pSubmixVoice->DestroyVoice(); - pSubmixVoice = NULL; - } - if( pMasterVoice != NULL ) - { - // release the vu meter effect - pMasterVoice->SetEffectChain( NULL ); - pMasterVoice->DestroyVoice(); - pMasterVoice = NULL; - } - if( pXAudio2 != NULL ) - { - XAUDIO2_PERFORMANCE_DATA perfData; - pXAudio2->GetPerformanceData( &perfData ); - idLib::Printf( "Final pXAudio2 performanceData: Voices: %d/%d CPU: %.2f%% Mem: %dkb\n", perfData.ActiveSourceVoiceCount, perfData.TotalSourceVoiceCount, perfData.AudioCyclesSinceLastQuery / ( float )perfData.TotalCyclesSinceLastQuery, perfData.MemoryUsageInBytes / 1024 ); - pXAudio2->Release(); - pXAudio2 = NULL; - } + /* if( vuMeterRMS != NULL ) { console->DestroyGraph( vuMeterRMS ); @@ -465,6 +337,7 @@ void idSoundHardware_OpenAL::Shutdown() console->DestroyGraph( vuMeterPeak ); vuMeterPeak = NULL; } + */ } /* @@ -533,7 +406,7 @@ idSoundHardware_OpenAL::Update */ void idSoundHardware_OpenAL::Update() { - if( pXAudio2 == NULL ) + if( openalDevice == NULL ) { int nowTime = Sys_Milliseconds(); if( lastResetTime + 1000 < nowTime ) @@ -543,17 +416,16 @@ void idSoundHardware_OpenAL::Update() } return; } + if( soundSystem->IsMuted() ) { - pMasterVoice->SetVolume( 0.0f, OPERATION_SET ); + alListenerf( AL_GAIN, 0.0f ); } else { - pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ), OPERATION_SET ); + alListenerf( AL_GAIN, DBtoLinear( s_volume_dB.GetFloat() ) ); } - pXAudio2->CommitChanges( XAUDIO2_COMMIT_ALL ); - // IXAudio2SourceVoice::Stop() has been called for every sound on the // zombie list, but it is documented as asyncronous, so we have to wait // until it actually reports that it is no longer playing. @@ -573,13 +445,16 @@ void idSoundHardware_OpenAL::Update() } } + /* if( s_showPerfData.GetBool() ) { XAUDIO2_PERFORMANCE_DATA perfData; pXAudio2->GetPerformanceData( &perfData ); idLib::Printf( "Voices: %d/%d CPU: %.2f%% Mem: %dkb\n", perfData.ActiveSourceVoiceCount, perfData.TotalSourceVoiceCount, perfData.AudioCyclesSinceLastQuery / ( float )perfData.TotalCyclesSinceLastQuery, perfData.MemoryUsageInBytes / 1024 ); } + */ + /* if( vuMeterRMS == NULL ) { // Init probably hasn't been called yet @@ -642,6 +517,7 @@ void idSoundHardware_OpenAL::Update() vuMeterPeakTimes[i] = currentTime + s_meterTopTime.GetInteger(); } } + */ } @@ -656,7 +532,9 @@ idSoundEngineCallback idSoundEngineCallback::OnCriticalError ======================== */ +/* void idSoundEngineCallback::OnCriticalError( HRESULT Error ) { soundSystemLocal.SetNeedsRestart(); } +*/ diff --git a/neo/sound/OpenAL/AL_SoundHardware.h b/neo/sound/OpenAL/AL_SoundHardware.h index d3d8d717..e828e43f 100644 --- a/neo/sound/OpenAL/AL_SoundHardware.h +++ b/neo/sound/OpenAL/AL_SoundHardware.h @@ -3,7 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. -Copyright (C) 2012 Robert Beckebans +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -39,22 +39,24 @@ class idSoundHardware_OpenAL; idSoundEngineCallback ================================================ */ +/* class idSoundEngineCallback : public IXAudio2EngineCallback { public: idSoundHardware_OpenAL* hardware; - + private: // Called by XAudio2 just before an audio processing pass begins. STDMETHOD_( void, OnProcessingPassStart )( THIS ) {} - + // Called just after an audio processing pass ends. STDMETHOD_( void, OnProcessingPassEnd )( THIS ) {} - + // Called in the event of a critical system error which requires XAudio2 // to be closed down and restarted. The error code is given in Error. STDMETHOD_( void, OnCriticalError )( THIS_ HRESULT Error ); }; +*/ /* ================================================ @@ -76,10 +78,12 @@ public: void FreeVoice( idSoundVoice* voice ); // video playback needs this + /* IXAudio2* GetIXAudio2() const { return pXAudio2; }; + */ int GetNumZombieVoices() const { @@ -95,19 +99,25 @@ protected: friend class idSoundVoice_OpenAL; private: + /* IXAudio2* pXAudio2; IXAudio2MasteringVoice* pMasterVoice; IXAudio2SubmixVoice* pSubmixVoice; idSoundEngineCallback soundEngineCallback; + */ + + ALCdevice* openalDevice; + ALCcontext* openalContext; + int lastResetTime; - int outputChannels; - int channelMask; + //int outputChannels; + //int channelMask; - idDebugGraph* vuMeterRMS; - idDebugGraph* vuMeterPeak; - int vuMeterPeakTimes[ 8 ]; + //idDebugGraph* vuMeterRMS; + //idDebugGraph* vuMeterPeak; + //int vuMeterPeakTimes[ 8 ]; // Can't stop and start a voice on the same frame, so we have to double this to handle the worst case scenario of stopping all voices and starting a full new set idStaticList voices; diff --git a/neo/sound/OpenAL/AL_SoundSample.cpp b/neo/sound/OpenAL/AL_SoundSample.cpp index d51371ef..446db948 100644 --- a/neo/sound/OpenAL/AL_SoundSample.cpp +++ b/neo/sound/OpenAL/AL_SoundSample.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -455,7 +456,7 @@ void idSoundSample_OpenAL::MakeDefault() format.basic.formatTag = idWaveFile::FORMAT_PCM; format.basic.numChannels = 1; format.basic.bitsPerSample = 16; - format.basic.samplesPerSec = XAUDIO2_MIN_SAMPLE_RATE; + format.basic.samplesPerSec = 1000; //XAUDIO2_MIN_SAMPLE_RATE; format.basic.blockSize = format.basic.numChannels * format.basic.bitsPerSample / 8; format.basic.avgBytesPerSec = format.basic.samplesPerSec * format.basic.blockSize; diff --git a/neo/sound/OpenAL/AL_SoundSample.h b/neo/sound/OpenAL/AL_SoundSample.h index 8f1a8487..9ce9faac 100644 --- a/neo/sound/OpenAL/AL_SoundSample.h +++ b/neo/sound/OpenAL/AL_SoundSample.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). diff --git a/neo/sound/OpenAL/AL_SoundVoice.cpp b/neo/sound/OpenAL/AL_SoundVoice.cpp index 073c6d1a..68d80f9b 100644 --- a/neo/sound/OpenAL/AL_SoundVoice.cpp +++ b/neo/sound/OpenAL/AL_SoundVoice.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -30,7 +31,7 @@ If you have questions concerning this license or the applicable additional terms #include "../snd_local.h" idCVar s_skipHardwareSets( "s_skipHardwareSets", "0", CVAR_BOOL, "Do all calculation, but skip XA2 calls" ); -idCVar s_debugHardware( "s_debugHardware", "0", CVAR_BOOL, "Print a message any time a hardware voice changes" ); +idCVar s_debugHardware( "s_debugHardware", "1", CVAR_BOOL, "Print a message any time a hardware voice changes" ); // The whole system runs at this sample rate static int SYSTEM_SAMPLE_RATE = 44100; @@ -41,6 +42,7 @@ static float ONE_OVER_SYSTEM_SAMPLE_RATE = 1.0f / SYSTEM_SAMPLE_RATE; idStreamingVoiceContext ======================== */ +/* class idStreamingVoiceContext : public IXAudio2VoiceCallback { public: @@ -63,6 +65,7 @@ public: soundSystemLocal.ReleaseStreamBufferContext( bufferContext ); } } streamContext; +*/ /* ======================== @@ -70,7 +73,7 @@ idSoundVoice_OpenAL::idSoundVoice_OpenAL ======================== */ idSoundVoice_OpenAL::idSoundVoice_OpenAL() - : pSourceVoice( NULL ), + : openalSource( 0 ), leadinSample( NULL ), loopingSample( NULL ), formatTag( 0 ), @@ -99,11 +102,12 @@ idSoundVoice_OpenAL::CompatibleFormat */ bool idSoundVoice_OpenAL::CompatibleFormat( idSoundSample_OpenAL* s ) { - if( pSourceVoice == NULL ) + if( alIsSource( openalSource ) ) { // If this voice has never been allocated, then it's compatible with everything return true; } + return false; } @@ -120,10 +124,11 @@ void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSo Stop(); return; } + leadinSample = ( idSoundSample_OpenAL* )leadinSample_; loopingSample = ( idSoundSample_OpenAL* )loopingSample_; - if( pSourceVoice != NULL && CompatibleFormat( leadinSample ) ) + if( alIsSource( openalSource ) && CompatibleFormat( leadinSample ) ) { sampleRate = leadinSample->format.basic.samplesPerSec; } @@ -134,27 +139,41 @@ void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSo numChannels = leadinSample->format.basic.numChannels; sampleRate = leadinSample->format.basic.samplesPerSec; - soundSystemLocal.hardware.pXAudio2->CreateSourceVoice( &pSourceVoice, ( const WAVEFORMATEX* )&leadinSample->format, XAUDIO2_VOICE_USEFILTER, 4.0f, &streamContext ); - if( pSourceVoice == NULL ) + //soundSystemLocal.hardware.pXAudio2->CreateSourceVoice( &pSourceVoice, ( const WAVEFORMATEX* )&leadinSample->format, XAUDIO2_VOICE_USEFILTER, 4.0f, &streamContext ); + + alGetError(); + alGenSources( 1, &openalSource ); + if( alGetError() != AL_NO_ERROR ) + //if( pSourceVoice == NULL ) { // If this hits, then we are most likely passing an invalid sample format, which should have been caught by the loader (and the sample defaulted) return; } + + alSourcef( openalSource, AL_ROLLOFF_FACTOR, 0.0f ); + if( s_debugHardware.GetBool() ) { if( loopingSample == NULL || loopingSample == leadinSample ) { - idLib::Printf( "%dms: %p created for %s\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "" ); + idLib::Printf( "%dms: %i created for %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "" ); } else { - idLib::Printf( "%dms: %p created for %s and %s\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "", loopingSample ? loopingSample->GetName() : "" ); + idLib::Printf( "%dms: %i created for %s and %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "", loopingSample ? loopingSample->GetName() : "" ); } } } + sourceVoiceRate = sampleRate; - pSourceVoice->SetSourceSampleRate( sampleRate ); - pSourceVoice->SetVolume( 0.0f ); + //pSourceVoice->SetSourceSampleRate( sampleRate ); + //pSourceVoice->SetVolume( 0.0f ); + + alSourcei( openalSource, AL_SOURCE_RELATIVE, AL_TRUE ); + alSource3f( openalSource, AL_POSITION, 0.0f, 0.0f, 0.0f ); + + // RB: FIXME 0.0f ? + alSourcef( openalSource, AL_GAIN, 1.0f ); } /* @@ -164,14 +183,16 @@ idSoundVoice_OpenAL::DestroyInternal */ void idSoundVoice_OpenAL::DestroyInternal() { - if( pSourceVoice != NULL ) + if( alIsSource( openalSource ) ) { if( s_debugHardware.GetBool() ) { - idLib::Printf( "%dms: %p destroyed\n", Sys_Milliseconds(), pSourceVoice ); + idLib::Printf( "%dms: %i destroyed\n", Sys_Milliseconds(), openalSource ); } - pSourceVoice->DestroyVoice(); - pSourceVoice = NULL; + + alDeleteSources( 1, &openalSource ); + openalSource = 0; + hasVUMeter = false; } } @@ -183,17 +204,17 @@ idSoundVoice_OpenAL::Start */ void idSoundVoice_OpenAL::Start( int offsetMS, int ssFlags ) { - if( s_debugHardware.GetBool() ) { - idLib::Printf( "%dms: %p starting %s @ %dms\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "", offsetMS ); + idLib::Printf( "%dms: %i starting %s @ %dms\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "", offsetMS ); } if( !leadinSample ) { return; } - if( !pSourceVoice ) + + if( !alIsSource( openalSource ) ) { return; } @@ -209,23 +230,25 @@ void idSoundVoice_OpenAL::Start( int offsetMS, int ssFlags ) { hasVUMeter = flicker; + /* if( flicker ) { IUnknown* vuMeter = NULL; + if( XAudio2CreateVolumeMeter( &vuMeter, 0 ) == S_OK ) { - + XAUDIO2_EFFECT_DESCRIPTOR descriptor; descriptor.InitialState = true; descriptor.OutputChannels = leadinSample->NumChannels(); descriptor.pEffect = vuMeter; - + XAUDIO2_EFFECT_CHAIN chain; chain.EffectCount = 1; chain.pEffectDescriptors = &descriptor; - + pSourceVoice->SetEffectChain( &chain ); - + vuMeter->Release(); } } @@ -233,6 +256,7 @@ void idSoundVoice_OpenAL::Start( int offsetMS, int ssFlags ) { pSourceVoice->SetEffectChain( NULL ); } + */ } assert( offsetMS >= 0 ); @@ -290,11 +314,11 @@ idSoundVoice_OpenAL::SubmitBuffer */ int idSoundVoice_OpenAL::SubmitBuffer( idSoundSample_OpenAL* sample, int bufferNumber, int offset ) { - if( sample == NULL || ( bufferNumber < 0 ) || ( bufferNumber >= sample->buffers.Num() ) ) { return 0; } + idSoundSystemLocal::bufferContext_t* bufferContext = soundSystemLocal.ObtainStreamBufferContext(); if( bufferContext == NULL ) { @@ -306,6 +330,11 @@ int idSoundVoice_OpenAL::SubmitBuffer( idSoundSample_OpenAL* sample, int bufferN bufferContext->sample = sample; bufferContext->bufferNumber = bufferNumber; + // TODO openal stream + return 0; + + /* + XAUDIO2_BUFFER buffer = { 0 }; if( offset > 0 ) { @@ -327,6 +356,8 @@ int idSoundVoice_OpenAL::SubmitBuffer( idSoundSample_OpenAL* sample, int bufferN pSourceVoice->SubmitSourceBuffer( &buffer ); return buffer.AudioBytes; + + */ } /* @@ -336,6 +367,7 @@ idSoundVoice_OpenAL::Update */ bool idSoundVoice_OpenAL::Update() { + /* if( pSourceVoice == NULL || leadinSample == NULL ) { return false; @@ -363,6 +395,7 @@ bool idSoundVoice_OpenAL::Update() // we don't do this any longer because we pause and unpause explicitly when the soundworld is paused or unpaused // UnPause(); + */ return true; } @@ -373,13 +406,21 @@ idSoundVoice_OpenAL::IsPlaying */ bool idSoundVoice_OpenAL::IsPlaying() { - if( pSourceVoice == NULL ) + if( !alIsSource( openalSource ) ) { return false; } - XAUDIO2_VOICE_STATE state; - pSourceVoice->GetState( &state ); - return ( state.BuffersQueued != 0 ); + + ALint state = AL_INITIAL; + + alGetSourcei( openalSource, AL_SOURCE_STATE, &state ); + + return ( state == AL_PLAYING ); + + //XAUDIO2_VOICE_STATE state; + //pSourceVoice->GetState( &state ); + + //return ( state.BuffersQueued != 0 ); } /* @@ -389,9 +430,9 @@ idSoundVoice_OpenAL::FlushSourceBuffers */ void idSoundVoice_OpenAL::FlushSourceBuffers() { - if( pSourceVoice != NULL ) + if( alIsSource( openalSource ) ) { - pSourceVoice->FlushSourceBuffers(); + //pSourceVoice->FlushSourceBuffers(); } } @@ -402,15 +443,18 @@ idSoundVoice_OpenAL::Pause */ void idSoundVoice_OpenAL::Pause() { - if( !pSourceVoice || paused ) + if( !alIsSource( openalSource ) || paused ) { return; } + if( s_debugHardware.GetBool() ) { - idLib::Printf( "%dms: %p pausing %s\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "" ); + idLib::Printf( "%dms: %i pausing %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "" ); } - pSourceVoice->Stop( 0, OPERATION_SET ); + + alSourcePause( openalSource ); + //pSourceVoice->Stop( 0, OPERATION_SET ); paused = true; } @@ -421,15 +465,18 @@ idSoundVoice_OpenAL::UnPause */ void idSoundVoice_OpenAL::UnPause() { - if( !pSourceVoice || !paused ) + if( !alIsSource( openalSource ) || !paused ) { return; } + if( s_debugHardware.GetBool() ) { - idLib::Printf( "%dms: %p unpausing %s\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "" ); + idLib::Printf( "%dms: %i unpausing %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "" ); } - pSourceVoice->Start( 0, OPERATION_SET ); + + alSourcePlay( openalSource ); + //pSourceVoice->Start( 0, OPERATION_SET ); paused = false; } @@ -440,17 +487,22 @@ idSoundVoice_OpenAL::Stop */ void idSoundVoice_OpenAL::Stop() { - if( !pSourceVoice ) + if( !alIsSource( openalSource ) ) { return; } + if( !paused ) { if( s_debugHardware.GetBool() ) { - idLib::Printf( "%dms: %p stopping %s\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "" ); + idLib::Printf( "%dms: %i stopping %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "" ); } - pSourceVoice->Stop( 0, OPERATION_SET ); + + alSourceStop( openalSource ); + alSourcei( openalSource, AL_BUFFER, 0 ); + + //pSourceVoice->Stop( 0, OPERATION_SET ); paused = true; } } @@ -462,6 +514,10 @@ idSoundVoice_OpenAL::GetAmplitude */ float idSoundVoice_OpenAL::GetAmplitude() { + // TODO + return 1.0f; + + /* if( !hasVUMeter ) { return 1.0f; @@ -497,6 +553,7 @@ float idSoundVoice_OpenAL::GetAmplitude() } return rms / ( float )levels.ChannelCount; + */ } /* @@ -506,6 +563,7 @@ idSoundVoice_OpenAL::ResetSampleRate */ void idSoundVoice_OpenAL::SetSampleRate( uint32 newSampleRate, uint32 operationSet ) { + /* if( pSourceVoice == NULL || leadinSample == NULL ) { return; @@ -543,7 +601,9 @@ void idSoundVoice_OpenAL::SetSampleRate( uint32 newSampleRate, uint32 operationS { assert( freqRatio * ( float )SYSTEM_SAMPLE_RATE <= XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MULTICHANNEL ); } + pSourceVoice->SetFrequencyRatio( freqRatio, operationSet ); + */ } /* @@ -553,7 +613,7 @@ idSoundVoice_OpenAL::OnBufferStart */ void idSoundVoice_OpenAL::OnBufferStart( idSoundSample_OpenAL* sample, int bufferNumber ) { - SetSampleRate( sample->SampleRate(), XAUDIO2_COMMIT_NOW ); + //SetSampleRate( sample->SampleRate(), XAUDIO2_COMMIT_NOW ); idSoundSample_OpenAL* nextSample = sample; int nextBuffer = bufferNumber + 1; diff --git a/neo/sound/OpenAL/AL_SoundVoice.h b/neo/sound/OpenAL/AL_SoundVoice.h index 3519565c..9afa5ad9 100644 --- a/neo/sound/OpenAL/AL_SoundVoice.h +++ b/neo/sound/OpenAL/AL_SoundVoice.h @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -51,6 +52,7 @@ public: // Stop consuming buffers void Pause(); + // Start consuming buffers again void UnPause(); @@ -92,9 +94,11 @@ private: // Adjust the voice frequency based on the new sample rate for the buffer void SetSampleRate( uint32 newSampleRate, uint32 operationSet ); - IXAudio2SourceVoice* pSourceVoice; - idSoundSample_OpenAL* leadinSample; - idSoundSample_OpenAL* loopingSample; + //IXAudio2SourceVoice* pSourceVoice; + ALuint openalSource; + + idSoundSample_OpenAL* leadinSample; + idSoundSample_OpenAL* loopingSample; // These are the fields from the sample format that matter to us for voice reuse uint16 formatTag; diff --git a/neo/sound/snd_local.h b/neo/sound/snd_local.h index 5a84f11a..b4eabca6 100644 --- a/neo/sound/snd_local.h +++ b/neo/sound/snd_local.h @@ -97,6 +97,16 @@ typedef enum #define OPERATION_SET 1 +#if defined(USE_OPENAL) + +#include +#include + +#include "OpenAL/AL_SoundSample.h" +#include "OpenAL/AL_SoundVoice.h" +#include "OpenAL/AL_SoundHardware.h" +#else + // RB: not available on Windows 8 SDK #if (_WIN32_WINNT < 0x0602 /*_WIN32_WINNT_WIN8*/) #include @@ -112,11 +122,6 @@ typedef enum #include #endif -#if defined(USE_OPENAL) -#include "OpenAL/AL_SoundSample.h" -#include "OpenAL/AL_SoundVoice.h" -#include "OpenAL/AL_SoundHardware.h" -#else #include "XAudio2/XA2_SoundSample.h" #include "XAudio2/XA2_SoundVoice.h" #include "XAudio2/XA2_SoundHardware.h" diff --git a/neo/sound/snd_system.cpp b/neo/sound/snd_system.cpp index 21b8b211..68460e13 100644 --- a/neo/sound/snd_system.cpp +++ b/neo/sound/snd_system.cpp @@ -3,6 +3,7 @@ Doom 3 BFG Edition GPL Source Code Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. +Copyright (C) 2013 Robert Beckebans This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). @@ -389,7 +390,13 @@ idSoundSystemLocal::GetIXAudio2 */ void* idSoundSystemLocal::GetIXAudio2() const { + // RB begin +#if defined(USE_OPENAL) + return NULL; +#else return ( void* )hardware.GetIXAudio2(); +#endif + // RB end } /*