简体   繁体   中英

Why OnCriticalError is called in DirectX version of XAudio2?

My game app uses XAudio2.lib and was targeted for Windows 8 and Windows 10. The code was as follows:

#include <Xaudio2.h>
HRESULT hr = XAudio2Create(&s_audioEngine, 0);
hr = s_audioEngine->CreateMasteringVoice(&s_masteringVoice);
s_audioEngine->RegisterForCallbacks(&s_callbacks);

and everything was fine. I could unplug headsets, and then plug it back, and there were no problems. IXAudio2EngineCallback::OnCriticalError(HRESULT error) had never been called.

It was fine until we decided to support Windows 7. I learnt that I have to use DirectX version of XAudio2 in this case. So I set _WIN32_WINNT=0x0601 in preprocessor definitions, removed XAudio2.lib from dependencies and changed code to

#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
#include <Xaudio2.h>
#else
#include <C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include\xaudio2.h>
#endif

It now launches, plays sound, but when I unplug headsets, it calls IXAudio2EngineCallback::OnCriticalError that means that I have to restart audio engine and recreate all the audio stuff.

I do not want to have such a pain, so I am reading MSDN, and I see:

If you specified NULL or szDeviceId parameter to IXAudio2::CreateMasteringVoice, then the system uses a Virtual Audio Client to represent the audio endpoint. In this case, if the underlying WASAPI rendering device becomes unavailable, the system automatically selects a new audio rendering device for rendering, audio processing continues, and OnCriticalError is not raised.

What does it mean? What is

If you specified NULL or szDeviceId parameter?

Can anyone explain how do I call CreateMasteringVoice to avoid OnCriticalError ?

Basically with XAudio 2.7 or XAudio 2.8, if a speaker or headphones are unplugged, WASAPI tells XAudio the endpoint is gone. The only way to recover is to destroy the entire XAudio graph and re-create it. On Windows 10, XAudio 2.9, using the 'default' device rather than a specific one, WASAPI will take care of auto migrating the endpoint so XAudio doesn't get told the endpoint has gone missing.

You can reproduce the same behavior on Windows 10 if you use XAUDIO2_NO_VIRTUAL_AUDIO_CLIENT .

See DirectX Tool Kit for Audio for examples of handling this 'lost device' scenario.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM