Replaced most XAudio2 calls with OpenAL

This commit is contained in:
Robert Beckebans 2013-01-03 16:56:25 +01:00
parent 9a40f246b6
commit 038037e524
9 changed files with 200 additions and 230 deletions

View file

@ -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

View file

@ -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();
}
*/

View file

@ -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<idSoundVoice_OpenAL, MAX_HARDWARE_VOICES* 2 > voices;

View file

@ -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;

View file

@ -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").

View file

@ -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() : "<null>" );
idLib::Printf( "%dms: %i created for %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>" );
}
else
{
idLib::Printf( "%dms: %p created for %s and %s\n", Sys_Milliseconds(), pSourceVoice, leadinSample ? leadinSample->GetName() : "<null>", loopingSample ? loopingSample->GetName() : "<null>" );
idLib::Printf( "%dms: %i created for %s and %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>", loopingSample ? loopingSample->GetName() : "<null>" );
}
}
}
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() : "<null>", offsetMS );
idLib::Printf( "%dms: %i starting %s @ %dms\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>", 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() : "<null>" );
idLib::Printf( "%dms: %i pausing %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>" );
}
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() : "<null>" );
idLib::Printf( "%dms: %i unpausing %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>" );
}
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() : "<null>" );
idLib::Printf( "%dms: %i stopping %s\n", Sys_Milliseconds(), openalSource, leadinSample ? leadinSample->GetName() : "<null>" );
}
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;

View file

@ -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;

View file

@ -97,6 +97,16 @@ typedef enum
#define OPERATION_SET 1
#if defined(USE_OPENAL)
#include <AL/al.h>
#include <AL/alc.h>
#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 <dxsdkver.h>
@ -112,11 +122,6 @@ typedef enum
#include <xma2defs.h>
#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"

View file

@ -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
}
/*