2013-01-02 20:45:47 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Doom 3 BFG Edition GPL Source Code
Copyright ( C ) 1993 - 2012 id Software LLC , a ZeniMax Media company .
2013-01-03 15:56:25 +00:00
Copyright ( C ) 2013 Robert Beckebans
2013-01-02 20:45:47 +00:00
This file is part of the Doom 3 BFG Edition GPL Source Code ( " Doom 3 BFG Edition Source Code " ) .
Doom 3 BFG Edition Source Code is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with Doom 3 BFG Edition Source Code . If not , see < http : //www.gnu.org/licenses/>.
In addition , the Doom 3 BFG Edition Source Code is also subject to certain additional terms . You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code . If not , please request a copy in writing from id Software at the address below .
If you have questions concerning this license or the applicable additional terms , you may contact in writing id Software LLC , c / o ZeniMax Media Inc . , Suite 120 , Rockville , Maryland 20850 USA .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
# pragma hdrstop
# include "precompiled.h"
# include "../snd_local.h"
idCVar s_skipHardwareSets ( " s_skipHardwareSets " , " 0 " , CVAR_BOOL , " Do all calculation, but skip XA2 calls " ) ;
2013-01-03 15:56:25 +00:00
idCVar s_debugHardware ( " s_debugHardware " , " 1 " , CVAR_BOOL , " Print a message any time a hardware voice changes " ) ;
2013-01-02 20:45:47 +00:00
// The whole system runs at this sample rate
static int SYSTEM_SAMPLE_RATE = 44100 ;
static float ONE_OVER_SYSTEM_SAMPLE_RATE = 1.0f / SYSTEM_SAMPLE_RATE ;
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idStreamingVoiceContext
= = = = = = = = = = = = = = = = = = = = = = = =
*/
2013-01-03 15:56:25 +00:00
/*
2013-01-02 20:45:47 +00:00
class idStreamingVoiceContext : public IXAudio2VoiceCallback
{
public :
STDMETHOD_ ( void , OnVoiceProcessingPassStart ) ( UINT32 BytesRequired ) { }
STDMETHOD_ ( void , OnVoiceProcessingPassEnd ) ( ) { }
STDMETHOD_ ( void , OnStreamEnd ) ( ) { }
STDMETHOD_ ( void , OnBufferStart ) ( void * pContext )
{
idSoundSystemLocal : : bufferContext_t * bufferContext = ( idSoundSystemLocal : : bufferContext_t * ) pContext ;
bufferContext - > voice - > OnBufferStart ( bufferContext - > sample , bufferContext - > bufferNumber ) ;
}
STDMETHOD_ ( void , OnLoopEnd ) ( void * ) { }
STDMETHOD_ ( void , OnVoiceError ) ( void * , HRESULT hr )
{
idLib : : Warning ( " OnVoiceError( %d ) " , hr ) ;
}
STDMETHOD_ ( void , OnBufferEnd ) ( void * pContext )
{
idSoundSystemLocal : : bufferContext_t * bufferContext = ( idSoundSystemLocal : : bufferContext_t * ) pContext ;
soundSystemLocal . ReleaseStreamBufferContext ( bufferContext ) ;
}
} streamContext ;
2013-01-03 15:56:25 +00:00
*/
2013-01-02 20:45:47 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : idSoundVoice_OpenAL
= = = = = = = = = = = = = = = = = = = = = = = =
*/
idSoundVoice_OpenAL : : idSoundVoice_OpenAL ( )
2013-01-03 19:17:54 +00:00
:
triggered ( false ) ,
openalSource ( 0 ) ,
leadinSample ( NULL ) ,
loopingSample ( NULL ) ,
formatTag ( 0 ) ,
numChannels ( 0 ) ,
sampleRate ( 0 ) ,
paused ( true ) ,
hasVUMeter ( false )
2013-01-02 20:45:47 +00:00
{
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : ~ idSoundVoice_OpenAL
= = = = = = = = = = = = = = = = = = = = = = = =
*/
idSoundVoice_OpenAL : : ~ idSoundVoice_OpenAL ( )
{
DestroyInternal ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : CompatibleFormat
= = = = = = = = = = = = = = = = = = = = = = = =
*/
bool idSoundVoice_OpenAL : : CompatibleFormat ( idSoundSample_OpenAL * s )
{
2013-01-03 15:56:25 +00:00
if ( alIsSource ( openalSource ) )
2013-01-02 20:45:47 +00:00
{
// If this voice has never been allocated, then it's compatible with everything
return true ;
}
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
return false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : Create
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : Create ( const idSoundSample * leadinSample_ , const idSoundSample * loopingSample_ )
{
if ( IsPlaying ( ) )
{
// This should never hit
Stop ( ) ;
return ;
}
2013-01-03 15:56:25 +00:00
2013-01-03 19:17:54 +00:00
triggered = true ;
2013-01-02 20:45:47 +00:00
leadinSample = ( idSoundSample_OpenAL * ) leadinSample_ ;
loopingSample = ( idSoundSample_OpenAL * ) loopingSample_ ;
2013-01-03 15:56:25 +00:00
if ( alIsSource ( openalSource ) & & CompatibleFormat ( leadinSample ) )
2013-01-02 20:45:47 +00:00
{
sampleRate = leadinSample - > format . basic . samplesPerSec ;
}
else
{
DestroyInternal ( ) ;
formatTag = leadinSample - > format . basic . formatTag ;
numChannels = leadinSample - > format . basic . numChannels ;
sampleRate = leadinSample - > format . basic . samplesPerSec ;
2013-01-03 15:56:25 +00:00
//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 )
2013-01-02 20:45:47 +00:00
{
// 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 ;
}
2013-01-03 15:56:25 +00:00
alSourcef ( openalSource , AL_ROLLOFF_FACTOR , 0.0f ) ;
2013-01-03 19:17:54 +00:00
// 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 ] ;
}
2013-01-02 20:45:47 +00:00
if ( s_debugHardware . GetBool ( ) )
{
if ( loopingSample = = NULL | | loopingSample = = leadinSample )
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i created for %s \n " , Sys_Milliseconds ( ) , openalSource , leadinSample ? leadinSample - > GetName ( ) : " <null> " ) ;
2013-01-02 20:45:47 +00:00
}
else
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i created for %s and %s \n " , Sys_Milliseconds ( ) , openalSource , leadinSample ? leadinSample - > GetName ( ) : " <null> " , loopingSample ? loopingSample - > GetName ( ) : " <null> " ) ;
2013-01-02 20:45:47 +00:00
}
}
}
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
sourceVoiceRate = sampleRate ;
2013-01-03 15:56:25 +00:00
//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 ?
2013-01-03 19:17:54 +00:00
alSourcef ( openalSource , AL_GAIN , 0.0f ) ;
//OnBufferStart( leadinSample, 0 );
2013-01-02 20:45:47 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : DestroyInternal
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : DestroyInternal ( )
{
2013-01-03 15:56:25 +00:00
if ( alIsSource ( openalSource ) )
2013-01-02 20:45:47 +00:00
{
if ( s_debugHardware . GetBool ( ) )
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i destroyed \n " , Sys_Milliseconds ( ) , openalSource ) ;
2013-01-02 20:45:47 +00:00
}
2013-01-03 15:56:25 +00:00
alDeleteSources ( 1 , & openalSource ) ;
openalSource = 0 ;
2013-01-02 20:45:47 +00:00
hasVUMeter = false ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : Start
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : Start ( int offsetMS , int ssFlags )
{
if ( s_debugHardware . GetBool ( ) )
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i starting %s @ %dms \n " , Sys_Milliseconds ( ) , openalSource , leadinSample ? leadinSample - > GetName ( ) : " <null> " , offsetMS ) ;
2013-01-02 20:45:47 +00:00
}
if ( ! leadinSample )
{
return ;
}
2013-01-03 15:56:25 +00:00
if ( ! alIsSource ( openalSource ) )
2013-01-02 20:45:47 +00:00
{
return ;
}
if ( leadinSample - > IsDefault ( ) )
{
idLib : : Warning ( " Starting defaulted sound sample %s " , leadinSample - > GetName ( ) ) ;
}
bool flicker = ( ssFlags & SSF_NO_FLICKER ) = = 0 ;
if ( flicker ! = hasVUMeter )
{
hasVUMeter = flicker ;
2013-01-03 15:56:25 +00:00
/*
2013-01-02 20:45:47 +00:00
if ( flicker )
{
IUnknown * vuMeter = NULL ;
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
if ( XAudio2CreateVolumeMeter ( & vuMeter , 0 ) = = S_OK )
{
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
XAUDIO2_EFFECT_DESCRIPTOR descriptor ;
descriptor . InitialState = true ;
descriptor . OutputChannels = leadinSample - > NumChannels ( ) ;
descriptor . pEffect = vuMeter ;
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
XAUDIO2_EFFECT_CHAIN chain ;
chain . EffectCount = 1 ;
chain . pEffectDescriptors = & descriptor ;
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
pSourceVoice - > SetEffectChain ( & chain ) ;
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
vuMeter - > Release ( ) ;
}
}
else
{
pSourceVoice - > SetEffectChain ( NULL ) ;
}
2013-01-03 15:56:25 +00:00
*/
2013-01-02 20:45:47 +00:00
}
assert ( offsetMS > = 0 ) ;
int offsetSamples = MsecToSamples ( offsetMS , leadinSample - > SampleRate ( ) ) ;
if ( loopingSample = = NULL & & offsetSamples > = leadinSample - > playLength )
{
return ;
}
RestartAt ( offsetSamples ) ;
Update ( ) ;
UnPause ( ) ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : RestartAt
= = = = = = = = = = = = = = = = = = = = = = = =
*/
int idSoundVoice_OpenAL : : RestartAt ( int offsetSamples )
{
offsetSamples & = ~ 127 ;
idSoundSample_OpenAL * sample = leadinSample ;
if ( offsetSamples > = leadinSample - > playLength )
{
if ( loopingSample ! = NULL )
{
offsetSamples % = loopingSample - > playLength ;
sample = loopingSample ;
}
else
{
return 0 ;
}
}
int previousNumSamples = 0 ;
for ( int i = 0 ; i < sample - > buffers . Num ( ) ; i + + )
{
if ( sample - > buffers [ i ] . numSamples > sample - > playBegin + offsetSamples )
{
return SubmitBuffer ( sample , i , sample - > playBegin + offsetSamples - previousNumSamples ) ;
}
previousNumSamples = sample - > buffers [ i ] . numSamples ;
}
return 0 ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
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 ;
}
2013-01-03 15:56:25 +00:00
2013-01-03 20:25:34 +00:00
#if 0
2013-01-02 20:45:47 +00:00
idSoundSystemLocal : : bufferContext_t * bufferContext = soundSystemLocal . ObtainStreamBufferContext ( ) ;
if ( bufferContext = = NULL )
{
idLib : : Warning ( " No free buffer contexts! " ) ;
return 0 ;
}
bufferContext - > voice = this ;
bufferContext - > sample = sample ;
bufferContext - > bufferNumber = bufferNumber ;
2013-01-03 20:25:34 +00:00
# endif
2013-01-02 20:45:47 +00:00
2013-01-03 15:56:25 +00:00
// TODO openal stream
2013-01-03 19:17:54 +00:00
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 )
{
2013-01-03 20:25:34 +00:00
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 ;
2013-01-03 19:17:54 +00:00
}
else
{
format = sample - > NumChannels ( ) = = 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16 ;
}
2013-01-03 20:25:34 +00:00
int rate = sample - > SampleRate ( ) ; /*44100*/
2013-01-03 19:17:54 +00:00
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*/ );
2013-01-03 20:25:34 +00:00
alBufferData ( openalStreamingBuffer [ j ] , format , sample - > buffers [ bufferNumber ] . buffer , sample - > buffers [ bufferNumber ] . bufferSize , rate ) ;
2013-01-03 19:17:54 +00:00
//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
2013-01-03 15:56:25 +00:00
return 0 ;
/*
2013-01-02 20:45:47 +00:00
XAUDIO2_BUFFER buffer = { 0 } ;
if ( offset > 0 )
{
int previousNumSamples = 0 ;
if ( bufferNumber > 0 )
{
previousNumSamples = sample - > buffers [ bufferNumber - 1 ] . numSamples ;
}
buffer . PlayBegin = offset ;
buffer . PlayLength = sample - > buffers [ bufferNumber ] . numSamples - previousNumSamples - offset ;
}
buffer . AudioBytes = sample - > buffers [ bufferNumber ] . bufferSize ;
buffer . pAudioData = ( BYTE * ) sample - > buffers [ bufferNumber ] . buffer ;
buffer . pContext = bufferContext ;
if ( ( loopingSample = = NULL ) & & ( bufferNumber = = sample - > buffers . Num ( ) - 1 ) )
{
buffer . Flags = XAUDIO2_END_OF_STREAM ;
}
pSourceVoice - > SubmitSourceBuffer ( & buffer ) ;
return buffer . AudioBytes ;
2013-01-03 15:56:25 +00:00
*/
2013-01-02 20:45:47 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : Update
= = = = = = = = = = = = = = = = = = = = = = = =
*/
bool idSoundVoice_OpenAL : : Update ( )
{
2013-01-03 15:56:25 +00:00
/*
2013-01-02 20:45:47 +00:00
if ( pSourceVoice = = NULL | | leadinSample = = NULL )
{
return false ;
}
XAUDIO2_VOICE_STATE state ;
pSourceVoice - > GetState ( & state ) ;
const int srcChannels = leadinSample - > NumChannels ( ) ;
float pLevelMatrix [ MAX_CHANNELS_PER_VOICE * MAX_CHANNELS_PER_VOICE ] = { 0 } ;
CalculateSurround ( srcChannels , pLevelMatrix , 1.0f ) ;
if ( s_skipHardwareSets . GetBool ( ) )
{
return true ;
}
pSourceVoice - > SetOutputMatrix ( soundSystemLocal . hardware . pMasterVoice , srcChannels , dstChannels , pLevelMatrix , OPERATION_SET ) ;
assert ( idMath : : Fabs ( gain ) < = XAUDIO2_MAX_VOLUME_LEVEL ) ;
pSourceVoice - > SetVolume ( gain , OPERATION_SET ) ;
SetSampleRate ( sampleRate , OPERATION_SET ) ;
// we don't do this any longer because we pause and unpause explicitly when the soundworld is paused or unpaused
// UnPause();
2013-01-03 15:56:25 +00:00
*/
2013-01-02 20:45:47 +00:00
return true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : IsPlaying
= = = = = = = = = = = = = = = = = = = = = = = =
*/
bool idSoundVoice_OpenAL : : IsPlaying ( )
{
2013-01-03 15:56:25 +00:00
if ( ! alIsSource ( openalSource ) )
2013-01-02 20:45:47 +00:00
{
return false ;
}
2013-01-03 15:56:25 +00:00
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 );
2013-01-02 20:45:47 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : FlushSourceBuffers
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : FlushSourceBuffers ( )
{
2013-01-03 15:56:25 +00:00
if ( alIsSource ( openalSource ) )
2013-01-02 20:45:47 +00:00
{
2013-01-03 15:56:25 +00:00
//pSourceVoice->FlushSourceBuffers();
2013-01-02 20:45:47 +00:00
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : Pause
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : Pause ( )
{
2013-01-03 15:56:25 +00:00
if ( ! alIsSource ( openalSource ) | | paused )
2013-01-02 20:45:47 +00:00
{
return ;
}
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
if ( s_debugHardware . GetBool ( ) )
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i pausing %s \n " , Sys_Milliseconds ( ) , openalSource , leadinSample ? leadinSample - > GetName ( ) : " <null> " ) ;
2013-01-02 20:45:47 +00:00
}
2013-01-03 15:56:25 +00:00
alSourcePause ( openalSource ) ;
//pSourceVoice->Stop( 0, OPERATION_SET );
2013-01-02 20:45:47 +00:00
paused = true ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : UnPause
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : UnPause ( )
{
2013-01-03 15:56:25 +00:00
if ( ! alIsSource ( openalSource ) | | ! paused )
2013-01-02 20:45:47 +00:00
{
return ;
}
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
if ( s_debugHardware . GetBool ( ) )
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i unpausing %s \n " , Sys_Milliseconds ( ) , openalSource , leadinSample ? leadinSample - > GetName ( ) : " <null> " ) ;
2013-01-02 20:45:47 +00:00
}
2013-01-03 15:56:25 +00:00
alSourcePlay ( openalSource ) ;
//pSourceVoice->Start( 0, OPERATION_SET );
2013-01-02 20:45:47 +00:00
paused = false ;
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : Stop
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : Stop ( )
{
2013-01-03 15:56:25 +00:00
if ( ! alIsSource ( openalSource ) )
2013-01-02 20:45:47 +00:00
{
return ;
}
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
if ( ! paused )
{
if ( s_debugHardware . GetBool ( ) )
{
2013-01-03 15:56:25 +00:00
idLib : : Printf ( " %dms: %i stopping %s \n " , Sys_Milliseconds ( ) , openalSource , leadinSample ? leadinSample - > GetName ( ) : " <null> " ) ;
2013-01-02 20:45:47 +00:00
}
2013-01-03 15:56:25 +00:00
alSourceStop ( openalSource ) ;
alSourcei ( openalSource , AL_BUFFER , 0 ) ;
2013-01-03 19:17:54 +00:00
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;
2013-01-03 15:56:25 +00:00
//pSourceVoice->Stop( 0, OPERATION_SET );
2013-01-02 20:45:47 +00:00
paused = true ;
}
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : GetAmplitude
= = = = = = = = = = = = = = = = = = = = = = = =
*/
float idSoundVoice_OpenAL : : GetAmplitude ( )
{
2013-01-03 15:56:25 +00:00
// TODO
return 1.0f ;
/*
2013-01-02 20:45:47 +00:00
if ( ! hasVUMeter )
{
return 1.0f ;
}
float peakLevels [ MAX_CHANNELS_PER_VOICE ] ;
float rmsLevels [ MAX_CHANNELS_PER_VOICE ] ;
XAUDIO2FX_VOLUMEMETER_LEVELS levels ;
levels . ChannelCount = leadinSample - > NumChannels ( ) ;
levels . pPeakLevels = peakLevels ;
levels . pRMSLevels = rmsLevels ;
if ( levels . ChannelCount > MAX_CHANNELS_PER_VOICE )
{
levels . ChannelCount = MAX_CHANNELS_PER_VOICE ;
}
if ( pSourceVoice - > GetEffectParameters ( 0 , & levels , sizeof ( levels ) ) ! = S_OK )
{
return 0.0f ;
}
if ( levels . ChannelCount = = 1 )
{
return rmsLevels [ 0 ] ;
}
float rms = 0.0f ;
for ( uint32 i = 0 ; i < levels . ChannelCount ; i + + )
{
rms + = rmsLevels [ i ] ;
}
return rms / ( float ) levels . ChannelCount ;
2013-01-03 15:56:25 +00:00
*/
2013-01-02 20:45:47 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : ResetSampleRate
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : SetSampleRate ( uint32 newSampleRate , uint32 operationSet )
{
2013-01-03 15:56:25 +00:00
/*
2013-01-02 20:45:47 +00:00
if ( pSourceVoice = = NULL | | leadinSample = = NULL )
{
return ;
}
sampleRate = newSampleRate ;
XAUDIO2_FILTER_PARAMETERS filter ;
filter . Type = LowPassFilter ;
filter . OneOverQ = 1.0f ; // [0.0f, XAUDIO2_MAX_FILTER_ONEOVERQ]
float cutoffFrequency = 1000.0f / Max ( 0.01f , occlusion ) ;
if ( cutoffFrequency * 6.0f > = ( float ) sampleRate )
{
filter . Frequency = XAUDIO2_MAX_FILTER_FREQUENCY ;
}
else
{
filter . Frequency = 2.0f * idMath : : Sin ( idMath : : PI * cutoffFrequency / ( float ) sampleRate ) ;
}
assert ( filter . Frequency > = 0.0f & & filter . Frequency < = XAUDIO2_MAX_FILTER_FREQUENCY ) ;
filter . Frequency = idMath : : ClampFloat ( 0.0f , XAUDIO2_MAX_FILTER_FREQUENCY , filter . Frequency ) ;
pSourceVoice - > SetFilterParameters ( & filter , operationSet ) ;
float freqRatio = pitch * ( float ) sampleRate / ( float ) sourceVoiceRate ;
assert ( freqRatio > = XAUDIO2_MIN_FREQ_RATIO & & freqRatio < = XAUDIO2_MAX_FREQ_RATIO ) ;
freqRatio = idMath : : ClampFloat ( XAUDIO2_MIN_FREQ_RATIO , XAUDIO2_MAX_FREQ_RATIO , freqRatio ) ;
// if the value specified for maxFreqRatio is too high for the specified format, the call to CreateSourceVoice will fail
if ( numChannels = = 1 )
{
assert ( freqRatio * ( float ) SYSTEM_SAMPLE_RATE < = XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MONO ) ;
}
else
{
assert ( freqRatio * ( float ) SYSTEM_SAMPLE_RATE < = XAUDIO2_MAX_RATIO_TIMES_RATE_XMA_MULTICHANNEL ) ;
}
2013-01-03 15:56:25 +00:00
2013-01-02 20:45:47 +00:00
pSourceVoice - > SetFrequencyRatio ( freqRatio , operationSet ) ;
2013-01-03 15:56:25 +00:00
*/
2013-01-02 20:45:47 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = =
idSoundVoice_OpenAL : : OnBufferStart
= = = = = = = = = = = = = = = = = = = = = = = =
*/
void idSoundVoice_OpenAL : : OnBufferStart ( idSoundSample_OpenAL * sample , int bufferNumber )
{
2013-01-03 15:56:25 +00:00
//SetSampleRate( sample->SampleRate(), XAUDIO2_COMMIT_NOW );
2013-01-02 20:45:47 +00:00
idSoundSample_OpenAL * nextSample = sample ;
int nextBuffer = bufferNumber + 1 ;
if ( nextBuffer = = sample - > buffers . Num ( ) )
{
if ( sample = = leadinSample )
{
if ( loopingSample = = NULL )
{
return ;
}
nextSample = loopingSample ;
}
nextBuffer = 0 ;
}
SubmitBuffer ( nextSample , nextBuffer , 0 ) ;
}