mirror of https://github.com/LIJI32/SameBoy.git
Fix XAudio2.7 hanging on device disconnection
This commit is contained in:
parent
e89df2df43
commit
c9fb3b3ec6
|
@ -109,8 +109,27 @@ static unsigned _audio_get_frequency(void)
|
|||
return audio_frequency;
|
||||
}
|
||||
|
||||
static void nop(IXAudio2EngineCallback *this)
|
||||
{
|
||||
}
|
||||
|
||||
static bool _audio_init(void);
|
||||
|
||||
static _Atomic bool needs_restart = false;
|
||||
|
||||
static void critical_error(IXAudio2EngineCallback *this, HRESULT error)
|
||||
{
|
||||
needs_restart = true;
|
||||
}
|
||||
|
||||
|
||||
static size_t _audio_get_queue_length(void)
|
||||
{
|
||||
if (needs_restart) {
|
||||
_audio_init();
|
||||
if (!xaudio2) return 0;
|
||||
_audio_set_paused(!playing);
|
||||
}
|
||||
static XAUDIO2_VOICE_STATE state;
|
||||
IXAudio2SourceVoice_GetState(source_voice, &state);
|
||||
|
||||
|
@ -120,6 +139,12 @@ static size_t _audio_get_queue_length(void)
|
|||
static void _audio_queue_sample(GB_sample_t *sample)
|
||||
{
|
||||
if (!playing) return;
|
||||
|
||||
if (needs_restart) {
|
||||
_audio_init();
|
||||
if (!xaudio2) return;
|
||||
_audio_set_paused(!playing);
|
||||
}
|
||||
|
||||
static XAUDIO2_BUFFER buffer = {.AudioBytes = sizeof(*sample) * BATCH_SIZE, };
|
||||
sample_pool[pos] = *sample;
|
||||
|
@ -133,6 +158,14 @@ static void _audio_queue_sample(GB_sample_t *sample)
|
|||
|
||||
static bool _audio_init(void)
|
||||
{
|
||||
if (needs_restart) {
|
||||
needs_restart = false;
|
||||
if (xaudio2) {
|
||||
xaudio2->lpVtbl->Release(xaudio2);
|
||||
xaudio2 = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
if (FAILED(hr)) {
|
||||
fprintf(stderr, "CoInitializeEx failed: %lx\n", hr);
|
||||
|
@ -168,6 +201,19 @@ static bool _audio_init(void)
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
static IXAudio2EngineCallbackVtbl callbacks = {
|
||||
nop,
|
||||
nop,
|
||||
.OnCriticalError = critical_error
|
||||
};
|
||||
|
||||
static IXAudio2EngineCallback callbackObject = {
|
||||
.lpVtbl = &callbacks
|
||||
};
|
||||
|
||||
IXAudio2SourceVoice_RegisterForCallbacks(xaudio2, &callbackObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,6 +49,21 @@ typedef struct IXAudio2 {
|
|||
typedef struct IXAudio2Vtbl IXAudio2Vtbl;
|
||||
typedef void *IXAudio2MasteringVoice;
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2EngineCallback
|
||||
DECLARE_INTERFACE(IXAudio2EngineCallback)
|
||||
{
|
||||
// Called by XAudio2 just before an audio processing pass begins.
|
||||
STDMETHOD_(void, OnProcessingPassStart) (THIS) PURE;
|
||||
|
||||
// Called just after an audio processing pass ends.
|
||||
STDMETHOD_(void, OnProcessingPassEnd) (THIS) PURE;
|
||||
|
||||
// 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.
|
||||
STDMETHOD_(void, OnCriticalError) (THIS_ HRESULT Error) PURE;
|
||||
};
|
||||
|
||||
#undef INTERFACE
|
||||
#define INTERFACE IXAudio2
|
||||
|
||||
|
@ -61,8 +76,8 @@ struct IXAudio2Vtbl {
|
|||
STDMETHOD(Initialize) (THIS_ UINT32 Flags,
|
||||
XAUDIO2_PROCESSOR XAudio2Processor) PURE;
|
||||
|
||||
void *RegisterForCallbacks;
|
||||
void *UnregisterForCallbacks;
|
||||
STDMETHOD(RegisterForCallbacks) (THIS_ __in IXAudio2EngineCallback *pCallback) PURE;
|
||||
void *UnregisterForCallbacks;
|
||||
|
||||
STDMETHOD(CreateSourceVoice) (THIS_ __deref_out IXAudio2SourceVoice **ppSourceVoice,
|
||||
__in const WAVEFORMATEX *pSourceFormat,
|
||||
|
@ -91,6 +106,7 @@ DEFINE_CLSID(XAudio2, 5a508685, a254, 4fba, 9b, 82, 9a, 24, b0, 03, 06, af);
|
|||
DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb);
|
||||
|
||||
|
||||
#define IXAudio2SourceVoice_RegisterForCallbacks(This, pCallback) ((This)->lpVtbl->RegisterForCallbacks(This,pCallback))
|
||||
#define IXAudio2SourceVoice_Start(This,Flags,OperationSet) ((This)->lpVtbl->Start(This,Flags,OperationSet))
|
||||
#define IXAudio2SourceVoice_Stop(This,Flags,OperationSet) ((This)->lpVtbl->Stop(This,Flags,OperationSet))
|
||||
#define IXAudio2SourceVoice_SubmitSourceBuffer(This,pBuffer,pBufferWMA) ((This)->lpVtbl->SubmitSourceBuffer(This,pBuffer,pBufferWMA))
|
||||
|
|
Loading…
Reference in New Issue