mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2024-12-02 08:51:57 +00:00
Fixed OpenAL bug when deleting the OpenAL buffers that caused the game to hang.
This commit is contained in:
parent
699e0e39f5
commit
4884cc5793
7 changed files with 161 additions and 144 deletions
|
@ -4,6 +4,7 @@
|
|||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2013 Robert Beckebans
|
||||
Copyright (c) 2010 by Chris Robinson <chris.kcat@gmail.com> (OpenAL Info Utility)
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -61,135 +62,98 @@ idSoundHardware_OpenAL::idSoundHardware_OpenAL()
|
|||
lastResetTime = 0;
|
||||
}
|
||||
|
||||
void idSoundHardware_OpenAL::PrintDeviceList( const char* list )
|
||||
{
|
||||
if( !list || *list == '\0' )
|
||||
{
|
||||
idLib::Printf( " !!! none !!!\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
idLib::Printf( " %s\n", list );
|
||||
list += strlen( list ) + 1;
|
||||
}
|
||||
while( *list != '\0' );
|
||||
}
|
||||
}
|
||||
|
||||
void idSoundHardware_OpenAL::PrintALCInfo( ALCdevice* device )
|
||||
{
|
||||
ALCint major, minor;
|
||||
|
||||
if( device )
|
||||
{
|
||||
const ALCchar* devname = NULL;
|
||||
idLib::Printf( "\n" );
|
||||
if( alcIsExtensionPresent( device, "ALC_ENUMERATE_ALL_EXT" ) != AL_FALSE )
|
||||
{
|
||||
devname = alcGetString( device, ALC_ALL_DEVICES_SPECIFIER );
|
||||
}
|
||||
|
||||
if( CheckALCErrors( device ) != ALC_NO_ERROR || !devname )
|
||||
{
|
||||
devname = alcGetString( device, ALC_DEVICE_SPECIFIER );
|
||||
}
|
||||
|
||||
idLib::Printf( "** Info for device \"%s\" **\n", devname );
|
||||
}
|
||||
alcGetIntegerv( device, ALC_MAJOR_VERSION, 1, &major );
|
||||
alcGetIntegerv( device, ALC_MINOR_VERSION, 1, &minor );
|
||||
|
||||
if( CheckALCErrors( device ) == ALC_NO_ERROR )
|
||||
idLib::Printf( "ALC version: %d.%d\n", major, minor );
|
||||
|
||||
if( device )
|
||||
{
|
||||
idLib::Printf( "OpenAL extensions: %s", alGetString( AL_EXTENSIONS ) );
|
||||
|
||||
//idLib::Printf("ALC extensions:");
|
||||
//printList(alcGetString(device, ALC_EXTENSIONS), ' ');
|
||||
CheckALCErrors( device );
|
||||
}
|
||||
}
|
||||
|
||||
void idSoundHardware_OpenAL::PrintALInfo()
|
||||
{
|
||||
idLib::Printf( "OpenAL vendor string: %s\n", alGetString( AL_VENDOR ) );
|
||||
idLib::Printf( "OpenAL renderer string: %s\n", alGetString( AL_RENDERER ) );
|
||||
idLib::Printf( "OpenAL version string: %s\n", alGetString( AL_VERSION ) );
|
||||
idLib::Printf( "OpenAL extensions: %s", alGetString( AL_EXTENSIONS ) );
|
||||
//PrintList(alGetString(AL_EXTENSIONS), ' ');
|
||||
CheckALErrors();
|
||||
}
|
||||
|
||||
void listDevices_f( const idCmdArgs& args )
|
||||
{
|
||||
#if 1
|
||||
// TODO
|
||||
|
||||
idLib::Warning( "No audio devices found" );
|
||||
return;
|
||||
#else
|
||||
UINT32 deviceCount = 0;
|
||||
if( pXAudio2->GetDeviceCount( &deviceCount ) != S_OK || deviceCount == 0 )
|
||||
idLib::Printf( "Available playback devices:\n" );
|
||||
if( alcIsExtensionPresent( NULL, "ALC_ENUMERATE_ALL_EXT" ) != AL_FALSE )
|
||||
{
|
||||
idLib::Warning( "No audio devices found" );
|
||||
return;
|
||||
idSoundHardware_OpenAL::PrintDeviceList( alcGetString( NULL, ALC_ALL_DEVICES_SPECIFIER ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
idSoundHardware_OpenAL::PrintDeviceList( alcGetString( NULL, ALC_DEVICE_SPECIFIER ) );
|
||||
}
|
||||
|
||||
for( unsigned int i = 0; i < deviceCount; i++ )
|
||||
//idLib::Printf("Available capture devices:\n");
|
||||
//printDeviceList(alcGetString(NULL, ALC_CAPTURE_DEVICE_SPECIFIER));
|
||||
|
||||
if( alcIsExtensionPresent( NULL, "ALC_ENUMERATE_ALL_EXT" ) != AL_FALSE )
|
||||
{
|
||||
XAUDIO2_DEVICE_DETAILS deviceDetails;
|
||||
if( pXAudio2->GetDeviceDetails( i, &deviceDetails ) != S_OK )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
idStaticList< const char*, 5 > roles;
|
||||
if( deviceDetails.Role & DefaultConsoleDevice )
|
||||
{
|
||||
roles.Append( "Console Device" );
|
||||
}
|
||||
if( deviceDetails.Role & DefaultMultimediaDevice )
|
||||
{
|
||||
roles.Append( "Multimedia Device" );
|
||||
}
|
||||
if( deviceDetails.Role & DefaultCommunicationsDevice )
|
||||
{
|
||||
roles.Append( "Communications Device" );
|
||||
}
|
||||
if( deviceDetails.Role & DefaultGameDevice )
|
||||
{
|
||||
roles.Append( "Game Device" );
|
||||
}
|
||||
idStaticList< const char*, 11 > channelNames;
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_FRONT_LEFT )
|
||||
{
|
||||
channelNames.Append( "Front Left" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_FRONT_RIGHT )
|
||||
{
|
||||
channelNames.Append( "Front Right" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_FRONT_CENTER )
|
||||
{
|
||||
channelNames.Append( "Front Center" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_LOW_FREQUENCY )
|
||||
{
|
||||
channelNames.Append( "Low Frequency" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_BACK_LEFT )
|
||||
{
|
||||
channelNames.Append( "Back Left" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_BACK_RIGHT )
|
||||
{
|
||||
channelNames.Append( "Back Right" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_FRONT_LEFT_OF_CENTER )
|
||||
{
|
||||
channelNames.Append( "Front Left of Center" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_FRONT_RIGHT_OF_CENTER )
|
||||
{
|
||||
channelNames.Append( "Front Right of Center" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_BACK_CENTER )
|
||||
{
|
||||
channelNames.Append( "Back Center" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_SIDE_LEFT )
|
||||
{
|
||||
channelNames.Append( "Side Left" );
|
||||
}
|
||||
if( deviceDetails.OutputFormat.dwChannelMask & SPEAKER_SIDE_RIGHT )
|
||||
{
|
||||
channelNames.Append( "Side Right" );
|
||||
}
|
||||
char mbcsDisplayName[ 256 ];
|
||||
wcstombs( mbcsDisplayName, deviceDetails.DisplayName, sizeof( mbcsDisplayName ) );
|
||||
idLib::Printf( "%3d: %s\n", i, mbcsDisplayName );
|
||||
idLib::Printf( " %d channels, %d Hz\n", deviceDetails.OutputFormat.Format.nChannels, deviceDetails.OutputFormat.Format.nSamplesPerSec );
|
||||
if( channelNames.Num() != deviceDetails.OutputFormat.Format.nChannels )
|
||||
{
|
||||
idLib::Printf( S_COLOR_YELLOW "WARNING: " S_COLOR_RED "Mismatch between # of channels and channel mask\n" );
|
||||
}
|
||||
if( channelNames.Num() == 1 )
|
||||
{
|
||||
idLib::Printf( " %s\n", channelNames[0] );
|
||||
}
|
||||
else if( channelNames.Num() == 2 )
|
||||
{
|
||||
idLib::Printf( " %s and %s\n", channelNames[0], channelNames[1] );
|
||||
}
|
||||
else if( channelNames.Num() > 2 )
|
||||
{
|
||||
idLib::Printf( " %s", channelNames[0] );
|
||||
for( int i = 1; i < channelNames.Num() - 1; i++ )
|
||||
{
|
||||
idLib::Printf( ", %s", channelNames[i] );
|
||||
}
|
||||
idLib::Printf( ", and %s\n", channelNames[channelNames.Num() - 1] );
|
||||
}
|
||||
if( roles.Num() == 1 )
|
||||
{
|
||||
idLib::Printf( " Default %s\n", roles[0] );
|
||||
}
|
||||
else if( roles.Num() == 2 )
|
||||
{
|
||||
idLib::Printf( " Default %s and %s\n", roles[0], roles[1] );
|
||||
}
|
||||
else if( roles.Num() > 2 )
|
||||
{
|
||||
idLib::Printf( " Default %s", roles[0] );
|
||||
for( int i = 1; i < roles.Num() - 1; i++ )
|
||||
{
|
||||
idLib::Printf( ", %s", roles[i] );
|
||||
}
|
||||
idLib::Printf( ", and %s\n", roles[roles.Num() - 1] );
|
||||
}
|
||||
idLib::Printf( "Default playback device: %s\n", alcGetString( NULL, ALC_DEFAULT_ALL_DEVICES_SPECIFIER ) );
|
||||
}
|
||||
#endif
|
||||
// RB end
|
||||
else
|
||||
{
|
||||
idLib::Printf( "Default playback device: %s\n", alcGetString( NULL, ALC_DEFAULT_DEVICE_SPECIFIER ) );
|
||||
}
|
||||
|
||||
//idLib::Printf("Default capture device: %s\n", alcGetString(NULL, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER));
|
||||
|
||||
idSoundHardware_OpenAL::PrintALCInfo( NULL );
|
||||
|
||||
idSoundHardware_OpenAL::PrintALCInfo( ( ALCdevice* )soundSystem->GetOpenALDevice() );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -77,13 +77,11 @@ public:
|
|||
idSoundVoice* AllocateVoice( const idSoundSample* leadinSample, const idSoundSample* loopingSample );
|
||||
void FreeVoice( idSoundVoice* voice );
|
||||
|
||||
// video playback needs this
|
||||
/*
|
||||
IXAudio2* GetIXAudio2() const
|
||||
// listDevices needs this
|
||||
ALCdevice* GetOpenALDevice() const
|
||||
{
|
||||
return pXAudio2;
|
||||
return openalDevice;
|
||||
};
|
||||
*/
|
||||
|
||||
int GetNumZombieVoices() const
|
||||
{
|
||||
|
@ -94,6 +92,11 @@ public:
|
|||
return freeVoices.Num();
|
||||
}
|
||||
|
||||
// OpenAL info
|
||||
static void PrintDeviceList( const char* list );
|
||||
static void PrintALCInfo( ALCdevice* device );
|
||||
static void PrintALInfo();
|
||||
|
||||
protected:
|
||||
friend class idSoundSample_OpenAL;
|
||||
friend class idSoundVoice_OpenAL;
|
||||
|
|
|
@ -280,17 +280,17 @@ void idSoundSample_OpenAL::LoadResource()
|
|||
void idSoundSample_OpenAL::CreateOpenALBuffer()
|
||||
{
|
||||
// build OpenAL buffer
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
alGenBuffers( 1, &openalBuffer );
|
||||
|
||||
if( alGetError() != AL_NO_ERROR )
|
||||
if( CheckALErrors() != AL_NO_ERROR )
|
||||
{
|
||||
common->Error( "idSoundSample_OpenAL::CreateOpenALBuffer: error generating OpenAL hardware buffer" );
|
||||
}
|
||||
|
||||
if( alIsBuffer( openalBuffer ) )
|
||||
{
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
|
||||
// RB: TODO decode idWaveFile::FORMAT_ADPCM to idWaveFile::FORMAT_PCM
|
||||
// and build one big OpenAL buffer using the alBufferSubData extension
|
||||
|
@ -352,7 +352,7 @@ void idSoundSample_OpenAL::CreateOpenALBuffer()
|
|||
alBufferData( openalBuffer, GetOpenALBufferFormat(), buffer, bufferSize, format.basic.samplesPerSec );
|
||||
}
|
||||
|
||||
if( alGetError() != AL_NO_ERROR )
|
||||
if( CheckALErrors() != AL_NO_ERROR )
|
||||
{
|
||||
common->Error( "idSoundSample_OpenAL::CreateOpenALBuffer: error loading data into OpenAL hardware buffer" );
|
||||
}
|
||||
|
@ -579,19 +579,19 @@ void idSoundSample_OpenAL::MakeDefault()
|
|||
playLength = DEFAULT_NUM_SAMPLES;
|
||||
|
||||
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
alGenBuffers( 1, &openalBuffer );
|
||||
|
||||
if( alGetError() != AL_NO_ERROR )
|
||||
if( CheckALErrors() != AL_NO_ERROR )
|
||||
{
|
||||
common->Error( "idSoundSample_OpenAL::MakeDefault: error generating OpenAL hardware buffer" );
|
||||
}
|
||||
|
||||
if( alIsBuffer( openalBuffer ) )
|
||||
{
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
alBufferData( openalBuffer, GetOpenALBufferFormat(), defaultBuffer, totalBufferSize, format.basic.samplesPerSec );
|
||||
if( alGetError() != AL_NO_ERROR )
|
||||
if( CheckALErrors() != AL_NO_ERROR )
|
||||
{
|
||||
common->Error( "idSoundSample_OpenAL::MakeDefault: error loading data into OpenAL hardware buffer" );
|
||||
}
|
||||
|
@ -627,9 +627,10 @@ void idSoundSample_OpenAL::FreeData()
|
|||
|
||||
if( alIsBuffer( openalBuffer ) )
|
||||
{
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
|
||||
alDeleteBuffers( 1, &openalBuffer );
|
||||
if( alGetError() != AL_NO_ERROR )
|
||||
if( CheckALErrors() != AL_NO_ERROR )
|
||||
{
|
||||
common->Error( "idSoundSample_OpenAL::FreeData: error unloading data from OpenAL hardware buffer" );
|
||||
}
|
||||
|
|
|
@ -145,9 +145,10 @@ void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSo
|
|||
|
||||
//soundSystemLocal.hardware.pXAudio2->CreateSourceVoice( &pSourceVoice, ( const WAVEFORMATEX* )&leadinSample->format, XAUDIO2_VOICE_USEFILTER, 4.0f, &streamContext );
|
||||
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
|
||||
alGenSources( 1, &openalSource );
|
||||
if( alGetError() != AL_NO_ERROR )
|
||||
if( CheckALErrors() != 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)
|
||||
|
@ -568,9 +569,10 @@ void idSoundVoice_OpenAL::FlushSourceBuffers()
|
|||
|
||||
if( openalStreamingBuffer[0] && openalStreamingBuffer[1] && openalStreamingBuffer[2] )
|
||||
{
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
|
||||
alDeleteBuffers( 3, &openalStreamingBuffer[0] );
|
||||
if( alGetError() == AL_NO_ERROR )
|
||||
if( CheckALErrors() == AL_NO_ERROR )
|
||||
{
|
||||
openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
|
||||
}
|
||||
|
@ -578,9 +580,10 @@ void idSoundVoice_OpenAL::FlushSourceBuffers()
|
|||
|
||||
if( lastopenalStreamingBuffer[0] && lastopenalStreamingBuffer[1] && lastopenalStreamingBuffer[2] )
|
||||
{
|
||||
alGetError();
|
||||
CheckALErrors();
|
||||
|
||||
alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
|
||||
if( alGetError() == AL_NO_ERROR )
|
||||
if( CheckALErrors() == AL_NO_ERROR )
|
||||
{
|
||||
lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
|
||||
}
|
||||
|
@ -654,7 +657,7 @@ void idSoundVoice_OpenAL::Stop()
|
|||
}
|
||||
|
||||
alSourceStop( openalSource );
|
||||
//alSourcei( openalSource, AL_BUFFER, 0 );
|
||||
alSourcei( openalSource, AL_BUFFER, 0 );
|
||||
|
||||
//pSourceVoice->Stop( 0, OPERATION_SET );
|
||||
paused = true;
|
||||
|
|
|
@ -105,6 +105,28 @@ typedef enum
|
|||
#include "OpenAL/AL_SoundVoice.h"
|
||||
#include "OpenAL/AL_SoundHardware.h"
|
||||
|
||||
ID_INLINE_EXTERN ALenum CheckALErrors_( const char* filename, int line )
|
||||
{
|
||||
ALenum err = alGetError();
|
||||
if( err != AL_NO_ERROR )
|
||||
{
|
||||
idLib::Printf( "OpenAL Error: %s (0x%x), @ %s %d\n", alGetString( err ), err, filename, line );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#define CheckALErrors() CheckALErrors_(__FILE__, __LINE__)
|
||||
|
||||
ID_INLINE_EXTERN ALCenum CheckALCErrors_( ALCdevice* device, const char* filename, int linenum )
|
||||
{
|
||||
ALCenum err = alcGetError( device );
|
||||
if( err != ALC_NO_ERROR )
|
||||
{
|
||||
idLib::Printf( "ALC Error: %s (0x%x), @ %s %d\n", alcGetString( device, err ), err, filename, linenum );
|
||||
}
|
||||
return err;
|
||||
}
|
||||
#define CheckALCErrors(x) CheckALCErrors_((x), __FILE__, __LINE__)
|
||||
|
||||
#elif defined(_MSC_VER) // DG: stub out xaudio for MinGW etc
|
||||
|
||||
#define OPERATION_SET 1
|
||||
|
@ -460,6 +482,10 @@ public:
|
|||
|
||||
virtual void* GetIXAudio2() const; // FIXME: stupid name; get rid of this? not sure if it's really needed..
|
||||
|
||||
// RB begin
|
||||
virtual void* GetOpenALDevice() const;
|
||||
// RB end
|
||||
|
||||
// for the sound level meter window
|
||||
virtual cinData_t ImageForTime( const int milliseconds, const bool waveform );
|
||||
|
||||
|
|
|
@ -399,6 +399,22 @@ void* idSoundSystemLocal::GetIXAudio2() const
|
|||
// RB end
|
||||
}
|
||||
|
||||
/*
|
||||
========================
|
||||
idSoundSystemLocal::GetOpenALDevice
|
||||
========================
|
||||
*/
|
||||
// RB begin
|
||||
void* idSoundSystemLocal::GetOpenALDevice() const
|
||||
{
|
||||
#if defined(USE_OPENAL)
|
||||
return ( void* )hardware.GetOpenALDevice();
|
||||
#else
|
||||
return ( void* )hardware.GetIXAudio2();
|
||||
#endif
|
||||
}
|
||||
// RB end
|
||||
|
||||
/*
|
||||
========================
|
||||
idSoundSystemLocal::SoundTime
|
||||
|
|
|
@ -321,6 +321,10 @@ public:
|
|||
// video playback needs to get this
|
||||
virtual void* GetIXAudio2() const = 0; // FIXME: stupid name if we have other backends
|
||||
|
||||
#if defined(USE_OPENAL)
|
||||
virtual void* GetOpenALDevice() const = 0;
|
||||
#endif
|
||||
|
||||
// for the sound level meter window
|
||||
virtual cinData_t ImageForTime( const int milliseconds, const bool waveform ) = 0;
|
||||
|
||||
|
|
Loading…
Reference in a new issue