diff --git a/neo/sound/OpenAL/AL_SoundHardware.cpp b/neo/sound/OpenAL/AL_SoundHardware.cpp index 110b7ac5..47c503a3 100644 --- a/neo/sound/OpenAL/AL_SoundHardware.cpp +++ b/neo/sound/OpenAL/AL_SoundHardware.cpp @@ -222,6 +222,7 @@ void idSoundHardware_OpenAL::Init() 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 ) ); + common->Printf( "OpenAL extensions: %s\n", alGetString( AL_EXTENSIONS ) ); //pMasterVoice->SetVolume( DBtoLinear( s_volume_dB.GetFloat() ) ); diff --git a/neo/sound/OpenAL/AL_SoundVoice.cpp b/neo/sound/OpenAL/AL_SoundVoice.cpp index 68d80f9b..59898853 100644 --- a/neo/sound/OpenAL/AL_SoundVoice.cpp +++ b/neo/sound/OpenAL/AL_SoundVoice.cpp @@ -73,14 +73,16 @@ idSoundVoice_OpenAL::idSoundVoice_OpenAL ======================== */ idSoundVoice_OpenAL::idSoundVoice_OpenAL() - : openalSource( 0 ), - leadinSample( NULL ), - loopingSample( NULL ), - formatTag( 0 ), - numChannels( 0 ), - sampleRate( 0 ), - paused( true ), - hasVUMeter( false ) + : + triggered( false ), + openalSource( 0 ), + leadinSample( NULL ), + loopingSample( NULL ), + formatTag( 0 ), + numChannels( 0 ), + sampleRate( 0 ), + paused( true ), + hasVUMeter( false ) { } @@ -125,6 +127,8 @@ void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSo return; } + triggered = true; + leadinSample = ( idSoundSample_OpenAL* )leadinSample_; loopingSample = ( idSoundSample_OpenAL* )loopingSample_; @@ -152,6 +156,27 @@ 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 ) + { + alSourcei( openalSource, AL_BUFFER, 0 ); + alDeleteBuffers( 3, &lastopenalStreamingBuffer[0] ); + lastopenalStreamingBuffer[0] = openalStreamingBuffer[0]; + lastopenalStreamingBuffer[1] = openalStreamingBuffer[1]; + lastopenalStreamingBuffer[2] = openalStreamingBuffer[2]; + + alGenBuffers( 3, &openalStreamingBuffer[0] ); + /* + if( soundSystemLocal.alEAXSetBufferMode ) + { + soundSystemLocal.alEAXSetBufferMode( 3, &chan->openalStreamingBuffer[0], alGetEnumValue( ID_ALCHAR "AL_STORAGE_ACCESSIBLE" ) ); + } + */ + openalStreamingBuffer[0]; + openalStreamingBuffer[1]; + openalStreamingBuffer[2]; + } + if( s_debugHardware.GetBool() ) { if( loopingSample == NULL || loopingSample == leadinSample ) @@ -173,7 +198,9 @@ void idSoundVoice_OpenAL::Create( const idSoundSample* leadinSample_, const idSo alSource3f( openalSource, AL_POSITION, 0.0f, 0.0f, 0.0f ); // RB: FIXME 0.0f ? - alSourcef( openalSource, AL_GAIN, 1.0f ); + alSourcef( openalSource, AL_GAIN, 0.0f ); + + //OnBufferStart( leadinSample, 0 ); } /* @@ -331,6 +358,73 @@ int idSoundVoice_OpenAL::SubmitBuffer( idSoundSample_OpenAL* sample, int bufferN bufferContext->bufferNumber = bufferNumber; // TODO openal stream + + ALint finishedbuffers; + + if( !triggered ) + { + alGetSourcei( openalSource, AL_BUFFERS_PROCESSED, &finishedbuffers ); + alSourceUnqueueBuffers( openalSource, finishedbuffers, &openalStreamingBuffer[0] ); + if( finishedbuffers == 3 ) + { + triggered = true; + } + } + else + { + finishedbuffers = 3; + } + + ALenum format; + + if( sample->format.basic.formatTag == idWaveFile::FORMAT_PCM ) + { + format = sample->NumChannels() == 1 ? AL_FORMAT_MONO_IMA4 : AL_FORMAT_STEREO_IMA4; + } + else + { + format = sample->NumChannels() == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16; + } + + 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, sample->SampleRate() /*44100*/ ); + //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 return 0; /* @@ -502,6 +596,30 @@ 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; + //pSourceVoice->Stop( 0, OPERATION_SET ); paused = true; } diff --git a/neo/sound/OpenAL/AL_SoundVoice.h b/neo/sound/OpenAL/AL_SoundVoice.h index 9afa5ad9..9fdb1cec 100644 --- a/neo/sound/OpenAL/AL_SoundVoice.h +++ b/neo/sound/OpenAL/AL_SoundVoice.h @@ -42,6 +42,20 @@ public: idSoundVoice_OpenAL(); ~idSoundVoice_OpenAL(); + void SetPosition( const idVec3& p ) + { + idSoundVoice_Base::SetPosition( p ); + + alSource3f( openalSource, AL_POSITION, -p.y, p.z, -p.x ); + } + + void SetGain( float gain ) + { + idSoundVoice_Base::SetGain( gain ); + + alSourcef( openalSource, AL_GAIN, ( gain ) < ( 1.0f ) ? ( gain ) : ( 1.0f ) ); + } + void Create( const idSoundSample* leadinSample, const idSoundSample* loopingSample ); // Start playing at a particular point in the buffer. Does an Update() too @@ -95,7 +109,11 @@ private: void SetSampleRate( uint32 newSampleRate, uint32 operationSet ); //IXAudio2SourceVoice* pSourceVoice; + bool triggered; ALuint openalSource; + ALuint openalStreamingOffset; + ALuint openalStreamingBuffer[3]; + ALuint lastopenalStreamingBuffer[3]; idSoundSample_OpenAL* leadinSample; idSoundSample_OpenAL* loopingSample; diff --git a/neo/sound/SoundVoice.h b/neo/sound/SoundVoice.h index 2f92912b..7963a70b 100644 --- a/neo/sound/SoundVoice.h +++ b/neo/sound/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"). @@ -43,14 +44,18 @@ public: void CalculateSurround( int srcChannels, float pLevelMatrix[ MAX_CHANNELS_PER_VOICE* MAX_CHANNELS_PER_VOICE ], float scale ); - void SetPosition( const idVec3& p ) + // RB begin + virtual void SetPosition( const idVec3& p ) { position = p; } - void SetGain( float g ) + + virtual void SetGain( float g ) { gain = g; } + // RB end + void SetCenterChannel( float c ) { centerChannel = c; diff --git a/neo/sound/snd_local.h b/neo/sound/snd_local.h index b4eabca6..de2a5223 100644 --- a/neo/sound/snd_local.h +++ b/neo/sound/snd_local.h @@ -101,6 +101,7 @@ typedef enum #include #include +#include #include "OpenAL/AL_SoundSample.h" #include "OpenAL/AL_SoundVoice.h" diff --git a/neo/sound/snd_world.cpp b/neo/sound/snd_world.cpp index c7d87dfe..a5a17bea 100644 --- a/neo/sound/snd_world.cpp +++ b/neo/sound/snd_world.cpp @@ -372,8 +372,10 @@ void idSoundWorldLocal::Update() const bool canMute = channel->CanMute(); if( canMute && channel->volumeDB <= DB_SILENCE ) { +#if !defined(USE_OPENAL) channel->Mute(); continue; +#endif } // Calculate the sort key.