diff --git a/stepmania/src/arch/Sound/RageSoundDriver.h b/stepmania/src/arch/Sound/RageSoundDriver.h index 19d249dea7..079e8502dd 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver.h +++ b/stepmania/src/arch/Sound/RageSoundDriver.h @@ -6,6 +6,10 @@ class RageSoundDriver { public: friend class RageSoundManager; + + /* Initialize. On failure, an error message is returned. */ + virtual CString Init() { return ""; } + /* A RageSound calls this to request to be played. * XXX: define what we should do when it can't be played (eg. out of * channels) */ diff --git a/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.cpp b/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.cpp index bbac8901a8..f012e3a203 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.cpp @@ -100,8 +100,12 @@ RageSound_WaveOut::RageSound_WaveOut() sound_event = CreateEvent(NULL, false, true, NULL); - WAVEFORMATEX fmt; + wo = NULL; +} +CString RageSound_WaveOut::Init() +{ + WAVEFORMATEX fmt; fmt.wFormatTag = WAVE_FORMAT_PCM; fmt.nChannels = channels; fmt.cbSize = 0; @@ -110,20 +114,18 @@ RageSound_WaveOut::RageSound_WaveOut() fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8; fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign; - MMRESULT ret = waveOutOpen(&wo, WAVE_MAPPER, &fmt, - (DWORD_PTR) sound_event, NULL, CALLBACK_EVENT); - - if(ret != MMSYSERR_NOERROR) - RageException::ThrowNonfatal(wo_ssprintf(ret, "waveOutOpen failed")); + MMRESULT ret = waveOutOpen( &wo, WAVE_MAPPER, &fmt, (DWORD_PTR) sound_event, NULL, CALLBACK_EVENT ); + if( ret != MMSYSERR_NOERROR ) + return wo_ssprintf( ret, "waveOutOpen failed" ); + ZERO( buffers ); for(int b = 0; b < num_chunks; ++b) { - memset(&buffers[b], 0, sizeof(buffers[b])); buffers[b].dwBufferLength = chunksize; buffers[b].lpData = new char[chunksize]; ret = waveOutPrepareHeader(wo, &buffers[b], sizeof(buffers[b])); - if(ret != MMSYSERR_NOERROR) - RageException::ThrowNonfatal(wo_ssprintf(ret, "waveOutPrepareHeader failed")); + if( ret != MMSYSERR_NOERROR ) + return wo_ssprintf( ret, "waveOutPrepareHeader failed" ); buffers[b].dwFlags |= WHDR_DONE; } @@ -134,25 +136,34 @@ RageSound_WaveOut::RageSound_WaveOut() MixingThread.SetName("Mixer thread"); MixingThread.Create( MixerThread_start, this ); + + return ""; } RageSound_WaveOut::~RageSound_WaveOut() { /* Signal the mixing thread to quit. */ - shutdown = true; - SetEvent( sound_event ); - LOG->Trace("Shutting down mixer thread ..."); - MixingThread.Wait(); - LOG->Trace("Mixer thread shut down."); + if( MixingThread.IsCreated() ) + { + shutdown = true; + SetEvent( sound_event ); + LOG->Trace("Shutting down mixer thread ..."); + MixingThread.Wait(); + LOG->Trace("Mixer thread shut down."); + } + + if( wo != NULL ) + { + for( int b = 0; b < num_chunks && buffers[b].lpData != NULL; ++b ) + { + waveOutUnprepareHeader( wo, &buffers[b], sizeof(buffers[b]) ); + delete [] buffers[b].lpData; + } + + waveOutClose( wo ); + } CloseHandle(sound_event); - waveOutClose(wo); - - for(int b = 0; b < num_chunks; ++b) - { - waveOutUnprepareHeader( wo, &buffers[b], sizeof(buffers[b]) ); - delete [] buffers[b].lpData; - } } float RageSound_WaveOut::GetPlayLatency() const diff --git a/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.h b/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.h index 6c6b1846be..865d9e53a1 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.h +++ b/stepmania/src/arch/Sound/RageSoundDriver_WaveOut.h @@ -30,6 +30,7 @@ public: RageSound_WaveOut(); ~RageSound_WaveOut(); + CString Init(); }; #endif diff --git a/stepmania/src/arch/arch.cpp b/stepmania/src/arch/arch.cpp index e31016d148..0298218680 100644 --- a/stepmania/src/arch/arch.cpp +++ b/stepmania/src/arch/arch.cpp @@ -137,8 +137,19 @@ RageSoundDriver *MakeRageSoundDriver(CString drivers) if(!DriversToTry[i].CompareNoCase("QT1")) ret = new RageSound_QT1; #endif if(!DriversToTry[i].CompareNoCase("Null")) ret = new RageSound_Null; - if( !ret ) - LOG->Warn("Unknown sound driver name: %s", DriversToTry[i].c_str()); + + if( ret == NULL ) + { + LOG->Warn( "Unknown sound driver name: %s", DriversToTry[i].c_str() ); + continue; + } + + CString sError = ret->Init(); + if( sError != "" ) + { + LOG->Info( "Couldn't load driver %s: %s", DriversToTry[i].c_str(), sError.c_str() ); + SAFE_DELETE( ret ); + } } catch(const RageException &e) { LOG->Info("Couldn't load driver %s: %s", DriversToTry[i].c_str(), e.what()); }