win32: stop trying to send audio data after device removal
This commit is contained in:
parent
f1ac3dc6d3
commit
d7dc9acf2f
@ -20,17 +20,25 @@ CWaveOut::~CWaveOut(void)
|
||||
DeInitSoundOutput();
|
||||
}
|
||||
|
||||
void CALLBACK WaveCallback(HWAVEOUT hWave, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
|
||||
void CALLBACK CWaveOut::WaveCallback(HWAVEOUT hWave, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2)
|
||||
{
|
||||
CWaveOut *wo = (CWaveOut*)dwUser;
|
||||
if (uMsg == WOM_DONE)
|
||||
{
|
||||
InterlockedDecrement(((volatile LONG *)dwUser));
|
||||
InterlockedDecrement(&wo->bufferCount);
|
||||
SetEvent(GUI.SoundSyncEvent);
|
||||
}
|
||||
else if (uMsg == WOM_CLOSE) // also sent on device removals
|
||||
{
|
||||
// this stops any output from being sent to the non existing device
|
||||
wo->initDone = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool CWaveOut::SetupSound()
|
||||
{
|
||||
DeInitSoundOutput();
|
||||
|
||||
WAVEFORMATEX wfx;
|
||||
wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
wfx.nChannels = 2;
|
||||
@ -43,7 +51,7 @@ bool CWaveOut::SetupSound()
|
||||
// subtract -1, we added "Default" as first index - Default will yield -1, which is WAVE_MAPPER
|
||||
int device_index = FindDeviceIndex(GUI.AudioDevice) - 1;
|
||||
|
||||
waveOutOpen(&hWaveOut, device_index, &wfx, (DWORD_PTR)WaveCallback, (DWORD_PTR)&bufferCount, CALLBACK_FUNCTION);
|
||||
waveOutOpen(&hWaveOut, device_index, &wfx, (DWORD_PTR)WaveCallback, (DWORD_PTR)this, CALLBACK_FUNCTION);
|
||||
|
||||
UINT32 blockTime = GUI.SoundBufferSize / blockCount;
|
||||
singleBufferSamples = (Settings.SoundPlaybackRate * blockTime) / 1000;
|
||||
@ -91,7 +99,7 @@ bool CWaveOut::InitSoundOutput()
|
||||
|
||||
void CWaveOut::DeInitSoundOutput()
|
||||
{
|
||||
if (!initDone)
|
||||
if (!hWaveOut)
|
||||
return;
|
||||
|
||||
StopPlayback();
|
||||
@ -109,6 +117,7 @@ void CWaveOut::DeInitSoundOutput()
|
||||
waveHeaders.clear();
|
||||
|
||||
waveOutClose(hWaveOut);
|
||||
hWaveOut = NULL;
|
||||
|
||||
initDone = false;
|
||||
}
|
||||
|
@ -44,4 +44,6 @@ class CWaveOut : public IS9xSoundOutput
|
||||
void SetVolume(double volume);
|
||||
std::vector<std::wstring> GetDeviceList();
|
||||
int FindDeviceIndex(TCHAR *audio_device);
|
||||
|
||||
static void CALLBACK WaveCallback(HWAVEOUT hWave, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2);
|
||||
};
|
||||
|
@ -108,6 +108,8 @@ bool CXAudio2::InitXAudio2(void)
|
||||
if(initDone)
|
||||
return true;
|
||||
|
||||
DeInitXAudio2();
|
||||
|
||||
HRESULT hr;
|
||||
if ( FAILED(hr = XAudio2Create( &pXAudio2, 0 , XAUDIO2_DEFAULT_PROCESSOR ) ) ) {
|
||||
DXTRACE_ERR_MSGBOX(TEXT("Unable to create XAudio2 object."),hr);
|
||||
@ -115,6 +117,7 @@ bool CXAudio2::InitXAudio2(void)
|
||||
return false;
|
||||
}
|
||||
initDone = true;
|
||||
pXAudio2->RegisterForCallbacks(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
#include <windows.h>
|
||||
#include "IS9xSoundOutput.h"
|
||||
|
||||
class CXAudio2 : public IXAudio2VoiceCallback, public IS9xSoundOutput
|
||||
class CXAudio2 : public IXAudio2VoiceCallback, public IXAudio2EngineCallback, public IS9xSoundOutput
|
||||
{
|
||||
private:
|
||||
IXAudio2SourceVoice *pSourceVoice;
|
||||
@ -56,6 +56,23 @@ public:
|
||||
STDMETHODIMP_(void) OnVoiceProcessingPassStart(UINT32 BytesRequired) {}
|
||||
|
||||
|
||||
// inherited from IXAudio2EngineCallback - we only use OnCriticalError
|
||||
|
||||
// Called by XAudio2 just before an audio processing pass begins.
|
||||
STDMETHODIMP_(void) OnProcessingPassStart() {}
|
||||
|
||||
// Called just after an audio processing pass ends.
|
||||
STDMETHODIMP_(void) OnProcessingPassEnd() {}
|
||||
|
||||
// Called in the event of a critical system error which requires XAudio2
|
||||
// to be closed down and restarted. The error code is given in Error.
|
||||
STDMETHODIMP_(void) OnCriticalError(HRESULT Error)
|
||||
{
|
||||
// this stops any output from being sent to the non existing device
|
||||
initDone = false;
|
||||
}
|
||||
|
||||
|
||||
// Inherited from IS9xSoundOutput
|
||||
bool InitSoundOutput(void) { return InitXAudio2(); }
|
||||
void DeInitSoundOutput(void) { DeInitXAudio2(); }
|
||||
|
Loading…
Reference in New Issue
Block a user