我的游戏应用程序使用 XAudio2.lib,并针对 Windows 8 和 Windows 10。代码如下:
#include <Xaudio2.h>
HRESULT hr = XAudio2Create(&s_audioEngine, 0);
hr = s_audioEngine->CreateMasteringVoice(&s_masteringVoice);
s_audioEngine->RegisterForCallbacks(&s_callbacks);
一切都很好。我可以拔掉耳机,然后再插回去,没有问题。 IXAudio2EngineCallback::OnCriticalError(HRESULT error)
从未被召唤过。
在我们决定支持Windows 7之前,一切都很好。我了解到在这种情况下我必须使用XAudio2的DirectX版本。所以我在预处理器定义中设置了_WIN32_WINNT=0x0601
,从依赖项中删除了XAudio2.lib
并将代码更改为
#if (_WIN32_WINNT >= 0x0602 /*_WIN32_WINNT_WIN8*/)
#include <Xaudio2.h>
#else
#include <C:Program Files (x86)Microsoft DirectX SDK (June 2010)Includexaudio2.h>
#endif
它现在可以启动,播放声音,但是当我拔下耳机时,它会调用IXAudio2EngineCallback::OnCriticalError
这意味着我必须重新启动音频引擎并重新创建所有音频内容。
不想有这样的痛苦,所以我正在阅读MSDN,我看到:
如果将 NULL 或 szDeviceId 参数指定为 IXAudio2::CreateMasteringVoice,则系统使用虚拟音频 表示音频终结点的客户端。在这种情况下,如果 底层 WASAPI 渲染设备变得不可用,系统变得不可用 自动选择新的音频渲染设备进行渲染, 音频处理继续,并且不会引发 OnCriticalError。
什么意思?什么
如果指定了 NULL 或 szDeviceId 参数?
谁能解释一下我如何打电话给CreateMasteringVoice
以避免OnCriticalError
?
基本上在XAudio 2.7或XAudio 2.8中,如果扬声器或耳机被拔下,WASAPI会告诉XAudio端点已经消失。恢复的唯一方法是销毁整个XAudio图形并重新创建它。在Windows 10,XAudio 2.9上,使用"默认"设备而不是特定设备,WASAPI将负责自动迁移端点,因此XAudio不会被告知端点已丢失。
如果您使用 XAUDIO2_NO_VIRTUAL_AUDIO_CLIENT
,则可以在 Windows 10 上重现相同的行为。
有关处理此"丢失设备"情况的示例,请参阅音频 DirectX 工具包。