Changed OpenAL to use buffers instead of streaming

This commit is contained in:
Robert Beckebans 2013-01-05 00:13:35 +01:00
parent 9ac405223b
commit a2fe079600
8 changed files with 235 additions and 99 deletions

View file

@ -15,6 +15,21 @@ option(SDL2
option(OPENAL
"Use OpenAL soft instead of XAudio2" ON)
if(MSVC)
#message(STATUS CMAKE_ROOT: ${CMAKE_ROOT})
#if(CMAKE_CL_64)
# SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin/win64)
#else()
# SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/../bin/win32)
#endif()
#message(STATUS EXECUTABLE_OUTPUT_PATH: ${EXECUTABLE_OUTPUT_PATH})
#message(STATUS PROJECT_BINARY_DIR: ${PROJECT_BINARY_DIR})
#message(STATUS CMAKE_BINARY_DIR: ${CMAKE_BINARY_DIR})
else()
message(STATUS CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE})
endif()
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
add_definitions(-pipe)
@ -1051,6 +1066,13 @@ if(MSVC)
set(OpenAL_LIBRARIES
OpenAL32)
if(CMAKE_CL_64)
install(FILES libs/openal-soft/lib/win64/OpenAL64.dll DESTINATION .)
else()
install(FILES libs/openal-soft/lib/win32/OpenAL32.dll DESTINATION .)
install(FILES libs/openal-soft/lib/win32/OpenAL32.pdb DESTINATION .)
endif()
else()
add_definitions(-DUSE_DOOMCLASSIC)
@ -1161,10 +1183,10 @@ if(MSVC)
#CMAKE_BINARY_DIR
if(CMAKE_CL_64)
install(TARGETS RBDoom3BFG
RUNTIME DESTINATION ../bin/win64)
RUNTIME DESTINATION .)
else()
install(TARGETS RBDoom3BFG
RUNTIME DESTINATION ../bin/win32)
RUNTIME DESTINATION .)
endif()
else()

View file

@ -2,5 +2,5 @@ cd ..
del /s /q build
mkdir build
cd build
cmake -G "Visual Studio 10" ../neo
cmake -G "Visual Studio 10" -DCMAKE_INSTALL_PREFIX=../bin/win32 ../neo
pause

View file

@ -2,5 +2,5 @@ cd ..
del /s /q build
mkdir build
cd build
cmake -G "Visual Studio 10 Win64" ../neo
cmake -G "Visual Studio 10 Win64" -DCMAKE_INSTALL_PREFIX=../bin/win64 ../neo
pause

View file

@ -2,5 +2,5 @@ cd ..
del /s /q build
mkdir build
cd build
cmake -G "Visual Studio 11" ../neo
cmake -G "Visual Studio 11" -DCMAKE_INSTALL_PREFIX=../bin/win8-32 ../neo
pause

View file

@ -2,5 +2,5 @@ cd ..
del /s /q build
mkdir build
cd build
cmake -G "Visual Studio 11 Win64" ../neo
cmake -G "Visual Studio 11 Win64" -DCMAKE_INSTALL_PREFIX=../bin/win8-64 ../neo
pause

View file

@ -79,6 +79,8 @@ idSoundSample_OpenAL::idSoundSample_OpenAL()
playLength = 0;
lastPlayedTime = 0;
openalBuffer = 0;
}
/*
@ -257,6 +259,30 @@ void idSoundSample_OpenAL::LoadResource()
}
}
}
// build OpenAL buffer
alGetError();
alGenBuffers( 1, &openalBuffer );
if( alGetError() != AL_NO_ERROR )
{
common->Error( "idSoundSample_OpenAL::MakeDefault: error generating OpenAL hardware buffer" );
}
if( alIsBuffer( openalBuffer ) )
{
alGetError();
// RB: TODO decode idWaveFile::FORMAT_ADPCM to idWaveFile::FORMAT_PCM
// and build one big OpenAL buffer using the alBufferSubData extension
alBufferData( openalBuffer, GetOpenALBufferFormat(), buffers[0].buffer, buffers[0].bufferSize, format.basic.samplesPerSec );
if( alGetError() != AL_NO_ERROR )
{
common->Error( "idSoundSample_OpenAL::MakeDefault: error loading data into OpenAL hardware buffer" );
}
}
return;
}
}
@ -487,6 +513,25 @@ void idSoundSample_OpenAL::MakeDefault()
playBegin = 0;
playLength = DEFAULT_NUM_SAMPLES;
alGetError();
alGenBuffers( 1, &openalBuffer );
if( alGetError() != AL_NO_ERROR )
{
common->Error( "idSoundSample_OpenAL::MakeDefault: error generating OpenAL hardware buffer" );
}
if( alIsBuffer( openalBuffer ) )
{
alGetError();
alBufferData( openalBuffer, GetOpenALBufferFormat(), defaultBuffer, totalBufferSize, format.basic.samplesPerSec );
if( alGetError() != AL_NO_ERROR )
{
common->Error( "idSoundSample_OpenAL::MakeDefault: error loading data into OpenAL hardware buffer" );
}
}
}
/*
@ -515,6 +560,20 @@ void idSoundSample_OpenAL::FreeData()
totalBufferSize = 0;
playBegin = 0;
playLength = 0;
if( alIsBuffer( openalBuffer ) )
{
alGetError();
alDeleteBuffers( 1, &openalBuffer );
if( alGetError() != AL_NO_ERROR )
{
common->Error( "idSoundSample_OpenAL::FreeData: error unloading data from OpenAL hardware buffer" );
}
else
{
openalBuffer = 0;
}
}
}
/*
@ -557,3 +616,30 @@ float idSoundSample_OpenAL::GetAmplitude( int timeMS ) const
}
return ( float )amplitude[index] / 255.0f;
}
ALenum idSoundSample_OpenAL::GetOpenALBufferFormat() const
{
ALenum alFormat;
if( format.basic.formatTag == idWaveFile::FORMAT_PCM )
{
alFormat = NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else if( format.basic.formatTag == idWaveFile::FORMAT_ADPCM )
{
alFormat = NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
//alFormat = NumChannels() == 1 ? AL_FORMAT_IMA_ADPCM_MONO16_EXT : AL_FORMAT_IMA_ADPCM_STEREO16_EXT;
}
else if( format.basic.formatTag == idWaveFile::FORMAT_XMA2 )
{
alFormat = NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else
{
alFormat = NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
return alFormat;
}

View file

@ -130,6 +130,8 @@ public:
float GetAmplitude( int timeMS ) const;
ALenum GetOpenALBufferFormat() const;
protected:
friend class idSoundHardware_OpenAL;
friend class idSoundVoice_OpenAL;
@ -163,6 +165,9 @@ protected:
int totalBufferSize; // total size of all the buffers
idList<sampleBuffer_t, TAG_AUDIO> buffers;
// OpenAL buffer that contains all buffers
ALuint openalBuffer;
int playBegin;
int playLength;

View file

@ -156,8 +156,23 @@ void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSo
alSourcef( openalSource, AL_ROLLOFF_FACTOR, 0.0f );
// handle streaming sounds (decode on the fly) both single shot AND looping
//if( triggered )
//if( ( loopingSample == NULL && leadinSample->openalBuffer != 0 ) || ( loopingSample != NULL && soundShader->entries[0]->hardwareBuffer ) )
if( leadinSample->openalBuffer != NULL )
{
alSourcei( openalSource, AL_BUFFER, 0 );
// handle uncompressed (non streaming) single shot and looping sounds
/*
if( triggered )
{
alSourcei( openalSource, AL_BUFFER, looping ? chan->soundShader->entries[0]->openalBuffer : leadinSample->openalBuffer );
}
*/
}
else
// handle streaming sounds (decode on the fly) both single shot AND looping
//if( triggered )
{
alSourcei( openalSource, AL_BUFFER, 0 );
alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
@ -359,81 +374,89 @@ int idSoundVoice_OpenAL::SubmitBuffer( idSoundSample_OpenAL* sample, int bufferN
bufferContext->bufferNumber = bufferNumber;
#endif
// TODO openal stream
ALint finishedbuffers;
if( !triggered )
if( sample->openalBuffer != 0 )
{
alGetSourcei( openalSource, AL_BUFFERS_PROCESSED, &finishedbuffers );
alSourceUnqueueBuffers( openalSource, finishedbuffers, &openalStreamingBuffer[0] );
if( finishedbuffers == 3 )
{
triggered = true;
}
alSourcei( openalSource, AL_BUFFER, sample->openalBuffer );
alSourcei( openalSource, AL_LOOPING, ( sample == loopingSample && loopingSample != NULL ? AL_TRUE : AL_FALSE ) );
return sample->totalBufferSize;
}
else
{
finishedbuffers = 3;
}
ALenum format;
if( sample->format.basic.formatTag == idWaveFile::FORMAT_PCM )
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else if( sample->format.basic.formatTag == idWaveFile::FORMAT_ADPCM )
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else if( sample->format.basic.formatTag == idWaveFile::FORMAT_XMA2 )
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
int rate = sample->SampleRate(); /*44100*/
for( int j = 0; j < finishedbuffers && j < 1; j++ )
{
/*
chan->GatherChannelSamples( chan->openalStreamingOffset * sample->objectInfo.nChannels, MIXBUFFER_SAMPLES * sample->objectInfo.nChannels, alignedInputSamples );
for( int i = 0; i < ( MIXBUFFER_SAMPLES * sample->objectInfo.nChannels ); i++ )
ALint finishedbuffers;
if( !triggered )
{
if( alignedInputSamples[i] < -32768.0f )
( ( short* )alignedInputSamples )[i] = -32768;
else if( alignedInputSamples[i] > 32767.0f )
( ( short* )alignedInputSamples )[i] = 32767;
else
( ( short* )alignedInputSamples )[i] = idMath::FtoiFast( alignedInputSamples[i] );
alGetSourcei( openalSource, AL_BUFFERS_PROCESSED, &finishedbuffers );
alSourceUnqueueBuffers( openalSource, finishedbuffers, &openalStreamingBuffer[0] );
if( finishedbuffers == 3 )
{
triggered = true;
}
}
*/
//alBufferData( buffers[0], sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, sample->buffers[bufferNumber].buffer, sample->buffers[bufferNumber].bufferSize, sample->SampleRate() /*44100*/ );
alBufferData( openalStreamingBuffer[j], format, sample->buffers[bufferNumber].buffer, sample->buffers[bufferNumber].bufferSize, rate );
//openalStreamingOffset += MIXBUFFER_SAMPLES;
}
if( finishedbuffers > 0 )
{
//alSourceQueueBuffers( openalSource, finishedbuffers, &buffers[0] );
alSourceQueueBuffers( openalSource, 1, &openalStreamingBuffer[0] );
if( bufferNumber == 0 )
else
{
alSourcePlay( openalSource );
triggered = false;
finishedbuffers = 3;
}
return sample->buffers[bufferNumber].bufferSize;
ALenum format;
if( sample->format.basic.formatTag == idWaveFile::FORMAT_PCM )
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else if( sample->format.basic.formatTag == idWaveFile::FORMAT_ADPCM )
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else if( sample->format.basic.formatTag == idWaveFile::FORMAT_XMA2 )
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
else
{
format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
}
int rate = sample->SampleRate(); /*44100*/
for( int j = 0; j < finishedbuffers && j < 1; j++ )
{
/*
chan->GatherChannelSamples( chan->openalStreamingOffset * sample->objectInfo.nChannels, MIXBUFFER_SAMPLES * sample->objectInfo.nChannels, alignedInputSamples );
for( int i = 0; i < ( MIXBUFFER_SAMPLES * sample->objectInfo.nChannels ); i++ )
{
if( alignedInputSamples[i] < -32768.0f )
( ( short* )alignedInputSamples )[i] = -32768;
else if( alignedInputSamples[i] > 32767.0f )
( ( short* )alignedInputSamples )[i] = 32767;
else
( ( short* )alignedInputSamples )[i] = idMath::FtoiFast( alignedInputSamples[i] );
}
*/
//alBufferData( buffers[0], sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16, sample->buffers[bufferNumber].buffer, sample->buffers[bufferNumber].bufferSize, sample->SampleRate() /*44100*/ );
alBufferData( openalStreamingBuffer[j], format, sample->buffers[bufferNumber].buffer, sample->buffers[bufferNumber].bufferSize, rate );
//openalStreamingOffset += MIXBUFFER_SAMPLES;
}
if( finishedbuffers > 0 )
{
//alSourceQueueBuffers( openalSource, finishedbuffers, &buffers[0] );
alSourceQueueBuffers( openalSource, 1, &openalStreamingBuffer[0] );
if( bufferNumber == 0 )
{
//alSourcePlay( openalSource );
triggered = false;
}
return sample->buffers[bufferNumber].bufferSize;
}
}
// should never happen
@ -539,6 +562,30 @@ void idSoundVoice_OpenAL::FlushSourceBuffers()
if( alIsSource( openalSource ) )
{
//pSourceVoice->FlushSourceBuffers();
alSourcei( openalSource, AL_BUFFER, 0 );
if( openalStreamingBuffer[0] && openalStreamingBuffer[1] && openalStreamingBuffer[2] )
{
alGetError();
alDeleteBuffers( 3, &openalStreamingBuffer[0] );
if( alGetError() == AL_NO_ERROR )
{
openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
}
}
if( lastopenalStreamingBuffer[0] && lastopenalStreamingBuffer[1] && lastopenalStreamingBuffer[2] )
{
alGetError();
alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
if( alGetError() == AL_NO_ERROR )
{
lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
}
}
openalStreamingOffset = 0;
}
}
@ -606,31 +653,7 @@ void idSoundVoice_OpenAL::Stop()
}
alSourceStop( openalSource );
alSourcei( openalSource, AL_BUFFER, 0 );
if( openalStreamingBuffer[0] && openalStreamingBuffer[1] && openalStreamingBuffer[2] )
{
alGetError();
alDeleteBuffers( 3, &openalStreamingBuffer[0] );
if( alGetError() == AL_NO_ERROR )
{
openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
}
}
if( lastopenalStreamingBuffer[0] && lastopenalStreamingBuffer[1] && lastopenalStreamingBuffer[2] )
{
alGetError();
alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] );
if( alGetError() == AL_NO_ERROR )
{
lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
}
}
openalStreamingOffset = 0;
//openalStreamingBuffer[0] = openalStreamingBuffer[1] = openalStreamingBuffer[2] = 0;
//lastopenalStreamingBuffer[0] = lastopenalStreamingBuffer[1] = lastopenalStreamingBuffer[2] = 0;
//alSourcei( openalSource, AL_BUFFER, 0 );
//pSourceVoice->Stop( 0, OPERATION_SET );
paused = true;