Replace Sleep function with waitable event
This commit is contained in:
parent
8c9a679eca
commit
587379dc29
|
@ -39,6 +39,27 @@
|
|||
#include "../Globals.h" // for 'speedup' and 'synchronize'
|
||||
|
||||
|
||||
// Synchronization Event
|
||||
class XAudio2_BufferNotify : public IXAudio2VoiceCallback
|
||||
{
|
||||
public:
|
||||
HANDLE hBufferEndEvent;
|
||||
|
||||
XAudio2_BufferNotify() { hBufferEndEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); }
|
||||
~XAudio2_BufferNotify() { CloseHandle( hBufferEndEvent ); }
|
||||
|
||||
STDMETHOD_( void, OnBufferEnd ) ( void *pBufferContext ) { SetEvent( hBufferEndEvent ); }
|
||||
|
||||
// dummies:
|
||||
STDMETHOD_( void, OnVoiceProcessingPassStart ) () {}
|
||||
STDMETHOD_( void, OnVoiceProcessingPassEnd ) () {}
|
||||
STDMETHOD_( void, OnStreamEnd ) () {}
|
||||
STDMETHOD_( void, OnBufferStart ) ( void *pBufferContext ) {}
|
||||
STDMETHOD_( void, OnLoopEnd ) ( void *pBufferContext ) {}
|
||||
STDMETHOD_( void, OnVoiceError ) ( void *pBufferContext, HRESULT Error ) {};
|
||||
};
|
||||
|
||||
|
||||
// Class Declaration
|
||||
class XAudio2_Output
|
||||
: public ISound
|
||||
|
@ -67,14 +88,15 @@ private:
|
|||
bool initialized;
|
||||
bool playing;
|
||||
UINT32 freq;
|
||||
BYTE *buffers;
|
||||
BYTE *buffers;
|
||||
int currentBuffer;
|
||||
|
||||
IXAudio2 *xaud;
|
||||
IXAudio2MasteringVoice *mVoice; // dest
|
||||
IXAudio2SourceVoice *sVoice; // source
|
||||
IXAudio2MasteringVoice *mVoice; // listener
|
||||
IXAudio2SourceVoice *sVoice; // sound source
|
||||
XAUDIO2_BUFFER buf;
|
||||
XAUDIO2_VOICE_STATE vState;
|
||||
XAudio2_BufferNotify notify; // buffer end notification
|
||||
};
|
||||
|
||||
|
||||
|
@ -85,7 +107,7 @@ XAudio2_Output::XAudio2_Output()
|
|||
initialized = false;
|
||||
playing = false;
|
||||
freq = 0;
|
||||
buffers = 0;
|
||||
buffers = NULL;
|
||||
currentBuffer = 0;
|
||||
|
||||
xaud = NULL;
|
||||
|
@ -181,7 +203,7 @@ bool XAudio2_Output::init()
|
|||
|
||||
|
||||
// Create Sound Emitter
|
||||
hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, XAUDIO2_MAX_FREQ_RATIO );
|
||||
hr = xaud->CreateSourceVoice( &sVoice, &wfx, 0, 4.0f, ¬ify );
|
||||
|
||||
if( FAILED( hr ) ) {
|
||||
systemMessage( IDS_XAUDIO2_CANNOT_CREATE_SOURCEVOICE, NULL );
|
||||
|
@ -203,7 +225,25 @@ void XAudio2_Output::write()
|
|||
{
|
||||
if( !initialized || failed ) return;
|
||||
|
||||
bool drop = false;
|
||||
while( true ) {
|
||||
sVoice->GetState( &vState );
|
||||
|
||||
ASSERT( vState.BuffersQueued <= NBUFFERS );
|
||||
|
||||
if( vState.BuffersQueued < NBUFFERS ) {
|
||||
// there is at least one free buffer
|
||||
break;
|
||||
} else {
|
||||
// the maximum number of buffers is currently queued
|
||||
if( synchronize && !speedup && !theApp.throttle ) {
|
||||
// wait for one buffer to finish playing
|
||||
WaitForSingleObject( notify.hBufferEndEvent, INFINITE );
|
||||
} else {
|
||||
// drop current audio frame
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// copy & protect the audio data in own memory area while playing it
|
||||
CopyMemory( &buffers[ currentBuffer * soundBufferLen ], soundFinalWave, soundBufferLen );
|
||||
|
@ -214,32 +254,7 @@ void XAudio2_Output::write()
|
|||
currentBuffer++;
|
||||
currentBuffer %= ( NBUFFERS + 1 );
|
||||
|
||||
while( true ) {
|
||||
sVoice->GetState( &vState );
|
||||
ASSERT( vState.BuffersQueued <= NBUFFERS );
|
||||
|
||||
if( vState.BuffersQueued == NBUFFERS ) {
|
||||
// all buffers filled
|
||||
if( speedup || !synchronize || theApp.throttle ) {
|
||||
drop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if( synchronize ) {
|
||||
// wait for about half the time one buffer needs to finish
|
||||
// unoptimized: ( sourceBufferLen * 1000 ) / ( freq * 2 * 2 ) * 1/2
|
||||
Sleep( soundBufferLen / ( freq >> 7 ) );
|
||||
}
|
||||
} else {
|
||||
// still room for new audio
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !drop ) {
|
||||
// add the sound buffer to the queue
|
||||
sVoice->SubmitSourceBuffer( &buf );
|
||||
}
|
||||
sVoice->SubmitSourceBuffer( &buf ); // send buffer to queue
|
||||
}
|
||||
|
||||
|
||||
|
@ -281,6 +296,8 @@ void XAudio2_Output::reset()
|
|||
|
||||
void XAudio2_Output::setThrottle( unsigned short throttle )
|
||||
{
|
||||
if( !initialized || failed ) return;
|
||||
|
||||
if( throttle == 0 ) throttle = 100;
|
||||
sVoice->SetFrequencyRatio( (float)throttle / 100.0f );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue