解決できない問題があります。私のアプリケーションは、実行時にデフォルトのオーディオ デバイスを切り替えることができるはずです。これを実現するために、DirectXTK の XAudio2 を使用しています。
IMMNotificationClient をオーディオ クラスに実装して、デフォルトのデバイスの変更に対応できるようにしました。
たとえば、デフォルトのデバイスが変更された場合、現在のソース ボイスを停止し、オーディオ エンジンをリセットして、ソース ボイスを再開します。すべてが期待どおりに機能します。
ただし、デフォルトのデバイスが USB サウンドカードで、ソース音声の再生中にプラグを抜くと、アプリケーションがフリーズします。
これは、音声を停止するときに元の音声がハングアップするためです。ソースバッファをフラッシュするときも時々あります。ソース ボイスが使用していたオーディオ デバイスを取り外すと、ソース ボイスを停止できなくなったようです。
誰かが同じ問題を抱えていて、これを解決できましたか?
オーディオエンジンをリセットするために使用している関数は次のとおりです。
HRESULT DX::XAudioEngine::ResetAudioDevice()
{
HRESULT hr = S_OK;
this->m_retryAudio = TRUE;
if (SUCCEEDED(hr) && m_pSourceVoice)
{
hr = m_pSourceVoice->Stop();
}
if (SUCCEEDED(hr))
{
hr = m_pSourceVoice->FlushSourceBuffers();
}
if (m_audEngine && m_pSourceVoice)
{
// Get the source voice back from the smart pointer
IXAudio2SourceVoice* ptmpSrcVoice = nullptr;
ptmpSrcVoice = m_pSourceVoice.release();
// Destroy the voice
ptmpSrcVoice->DestroyVoice();
}
m_audEngine->Reset(&m_waveFormat, NULL);
// Create source voice
IXAudio2SourceVoice* ptmpSrcVoice = nullptr;
m_audEngine->AllocateVoice(
(WAVEFORMATEX*)&m_waveFormat,
SoundEffectInstance_Default,
false,
&ptmpSrcVoice
);
// Add source voice to smart pointer
m_pSourceVoice.reset(ptmpSrcVoice);
// Set the input volume
if (this->m_inputVolume != 1.0f) {
hr = m_pSourceVoice->SetVolume(this->m_inputVolume);
}
hr = m_pSourceVoice->Start(0);
this->m_retryAudio = FALSE;
return hr;
}