This commit is contained in:
Glenn Maynard
2005-06-04 00:16:27 +00:00
parent 722357f566
commit d9374832cf
2 changed files with 52 additions and 52 deletions
@@ -21,20 +21,20 @@ const int num_chunks = 8;
const int chunksize_frames = buffersize_frames / num_chunks; const int chunksize_frames = buffersize_frames / num_chunks;
const int chunksize = buffersize / num_chunks; /* in bytes */ const int chunksize = buffersize / num_chunks; /* in bytes */
static CString wo_ssprintf( MMRESULT err, const char *fmt, ...) static CString wo_ssprintf( MMRESULT err, const char *szFmt, ...)
{ {
char buf[MAXERRORLENGTH]; char szBuf[MAXERRORLENGTH];
waveOutGetErrorText(err, buf, MAXERRORLENGTH); waveOutGetErrorText( err, szBuf, MAXERRORLENGTH );
va_list va; va_list va;
va_start(va, fmt); va_start( va, szFmt );
CString s = vssprintf( fmt, va ); CString s = vssprintf( szFmt, va );
va_end(va); va_end( va );
return s += ssprintf( "(%s)", buf ); return s += ssprintf( "(%s)", szBuf );
} }
int RageSound_WaveOut::MixerThread_start(void *p) int RageSound_WaveOut::MixerThread_start( void *p )
{ {
((RageSound_WaveOut *) p)->MixerThread(); ((RageSound_WaveOut *) p)->MixerThread();
return 0; return 0;
@@ -45,15 +45,15 @@ void RageSound_WaveOut::MixerThread()
if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) ) if( !SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_ABOVE_NORMAL) )
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
while( !shutdown ) while( !m_bShutdown )
{ {
while( GetData() ) while( GetData() )
; ;
WaitForSingleObject(sound_event, 10); WaitForSingleObject( m_hSoundEvent, 10 );
} }
waveOutReset(wo); waveOutReset( m_hWaveOut );
} }
bool RageSound_WaveOut::GetData() bool RageSound_WaveOut::GetData()
@@ -61,19 +61,20 @@ bool RageSound_WaveOut::GetData()
/* Look for a free buffer. */ /* Look for a free buffer. */
int b; int b;
for( b = 0; b < num_chunks; ++b ) for( b = 0; b < num_chunks; ++b )
if(buffers[b].dwFlags & WHDR_DONE) break; if( m_aBuffers[b].dwFlags & WHDR_DONE )
break;
if( b == num_chunks ) if( b == num_chunks )
return false; return false;
/* Call the callback. */ /* Call the callback. */
this->Mix( (int16_t *) buffers[b].lpData, chunksize_frames, last_cursor_pos, GetPosition( NULL ) ); this->Mix( (int16_t *) m_aBuffers[b].lpData, chunksize_frames, m_iLastCursorPos, GetPosition( NULL ) );
MMRESULT ret = waveOutWrite(wo, &buffers[b], sizeof(buffers[b])); MMRESULT ret = waveOutWrite( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
if(ret != MMSYSERR_NOERROR) if(ret != MMSYSERR_NOERROR)
RageException::Throw(wo_ssprintf(ret, "waveOutWrite failed")); RageException::Throw(wo_ssprintf(ret, "waveOutWrite failed"));
/* Increment last_cursor_pos. */ /* Increment m_iLastCursorPos. */
last_cursor_pos += chunksize_frames; m_iLastCursorPos += chunksize_frames;
return true; return true;
} }
@@ -84,25 +85,25 @@ void RageSound_WaveOut::SetupDecodingThread()
LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") ); LOG->Warn( werr_ssprintf(GetLastError(), "Failed to set sound thread priority") );
} }
int64_t RageSound_WaveOut::GetPosition( const RageSoundBase *snd ) const int64_t RageSound_WaveOut::GetPosition( const RageSoundBase *pSound ) const
{ {
MMTIME tm; MMTIME tm;
tm.wType = TIME_SAMPLES; tm.wType = TIME_SAMPLES;
MMRESULT ret = waveOutGetPosition(wo, &tm, sizeof(tm)); MMRESULT ret = waveOutGetPosition( m_hWaveOut, &tm, sizeof(tm) );
if(ret != MMSYSERR_NOERROR) if( ret != MMSYSERR_NOERROR )
RageException::Throw(wo_ssprintf(ret, "waveOutGetPosition failed")); RageException::Throw( wo_ssprintf(ret, "waveOutGetPosition failed") );
return tm.u.sample; return tm.u.sample;
} }
RageSound_WaveOut::RageSound_WaveOut() RageSound_WaveOut::RageSound_WaveOut()
{ {
shutdown = false; m_bShutdown = false;
last_cursor_pos = 0; m_iLastCursorPos = 0;
sound_event = CreateEvent(NULL, false, true, NULL); m_hSoundEvent = CreateEvent( NULL, false, true, NULL );
wo = NULL; m_hWaveOut = NULL;
} }
CString RageSound_WaveOut::Init() CString RageSound_WaveOut::Init()
@@ -116,19 +117,19 @@ CString RageSound_WaveOut::Init()
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
MMRESULT ret = waveOutOpen( &wo, WAVE_MAPPER, &fmt, (DWORD_PTR) sound_event, NULL, CALLBACK_EVENT ); MMRESULT ret = waveOutOpen( &m_hWaveOut, WAVE_MAPPER, &fmt, (DWORD_PTR) m_hSoundEvent, NULL, CALLBACK_EVENT );
if( ret != MMSYSERR_NOERROR ) if( ret != MMSYSERR_NOERROR )
return wo_ssprintf( ret, "waveOutOpen failed" ); return wo_ssprintf( ret, "waveOutOpen failed" );
ZERO( buffers ); ZERO( m_aBuffers );
for(int b = 0; b < num_chunks; ++b) for(int b = 0; b < num_chunks; ++b)
{ {
buffers[b].dwBufferLength = chunksize; m_aBuffers[b].dwBufferLength = chunksize;
buffers[b].lpData = new char[chunksize]; m_aBuffers[b].lpData = new char[chunksize];
ret = waveOutPrepareHeader(wo, &buffers[b], sizeof(buffers[b])); ret = waveOutPrepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
if( ret != MMSYSERR_NOERROR ) if( ret != MMSYSERR_NOERROR )
return wo_ssprintf( ret, "waveOutPrepareHeader failed" ); return wo_ssprintf( ret, "waveOutPrepareHeader failed" );
buffers[b].dwFlags |= WHDR_DONE; m_aBuffers[b].dwFlags |= WHDR_DONE;
} }
/* We have a very large writeahead; make sure we have a large enough decode /* We have a very large writeahead; make sure we have a large enough decode
@@ -136,7 +137,7 @@ CString RageSound_WaveOut::Init()
SetDecodeBufferSize( buffersize_frames * 3/2 ); SetDecodeBufferSize( buffersize_frames * 3/2 );
StartDecodeThread(); StartDecodeThread();
MixingThread.SetName("Mixer thread"); MixingThread.SetName( "Mixer thread" );
MixingThread.Create( MixerThread_start, this ); MixingThread.Create( MixerThread_start, this );
return ""; return "";
@@ -147,25 +148,25 @@ RageSound_WaveOut::~RageSound_WaveOut()
/* Signal the mixing thread to quit. */ /* Signal the mixing thread to quit. */
if( MixingThread.IsCreated() ) if( MixingThread.IsCreated() )
{ {
shutdown = true; m_bShutdown = true;
SetEvent( sound_event ); SetEvent( m_hSoundEvent );
LOG->Trace("Shutting down mixer thread ..."); LOG->Trace( "Shutting down mixer thread ..." );
MixingThread.Wait(); MixingThread.Wait();
LOG->Trace("Mixer thread shut down."); LOG->Trace( "Mixer thread shut down." );
} }
if( wo != NULL ) if( m_hWaveOut != NULL )
{ {
for( int b = 0; b < num_chunks && buffers[b].lpData != NULL; ++b ) for( int b = 0; b < num_chunks && m_aBuffers[b].lpData != NULL; ++b )
{ {
waveOutUnprepareHeader( wo, &buffers[b], sizeof(buffers[b]) ); waveOutUnprepareHeader( m_hWaveOut, &m_aBuffers[b], sizeof(m_aBuffers[b]) );
delete [] buffers[b].lpData; delete [] m_aBuffers[b].lpData;
} }
waveOutClose( wo ); waveOutClose( m_hWaveOut );
} }
CloseHandle(sound_event); CloseHandle( m_hSoundEvent );
} }
float RageSound_WaveOut::GetPlayLatency() const float RageSound_WaveOut::GetPlayLatency() const
@@ -9,26 +9,25 @@
class RageSound_WaveOut: public RageSound_Generic_Software class RageSound_WaveOut: public RageSound_Generic_Software
{ {
public: public:
int64_t GetPosition( const RageSoundBase *snd ) const;
float GetPlayLatency() const;
RageSound_WaveOut(); RageSound_WaveOut();
~RageSound_WaveOut(); ~RageSound_WaveOut();
CString Init(); CString Init();
private: int64_t GetPosition( const RageSoundBase *pSound ) const;
HWAVEOUT wo; float GetPlayLatency() const;
HANDLE sound_event;
WAVEHDR buffers[8];
bool shutdown;
int last_cursor_pos;
static int MixerThread_start(void *p); private:
static int MixerThread_start( void *p );
void MixerThread(); void MixerThread();
RageThread MixingThread; RageThread MixingThread;
bool GetData(); bool GetData();
void SetupDecodingThread(); void SetupDecodingThread();
HWAVEOUT m_hWaveOut;
HANDLE m_hSoundEvent;
WAVEHDR m_aBuffers[8];
bool m_bShutdown;
int m_iLastCursorPos;
}; };
#define USE_RAGE_SOUND_WAVE_OUT #define USE_RAGE_SOUND_WAVE_OUT