如何在 XAudio2 上同时播放多个声音



我目前正在尝试使用 XAudio2 在 Windows 中制作游戏应用程序,但我无法弄清楚如何在播放声音时使应用程序不阻塞。我尝试在此存储库的示例中调用一个新线程。

但它只会导致错误。我尝试在函数中传递对主语音的引用,但随后它只是引发"XAudio2:必须首先创建主语音"错误。我错过了什么吗?我只是想让它同时播放两种声音并从那里构建。我浏览了文档,但它非常模糊。

XAudio2 是一个非阻塞 API。要同时播放两个声音,您至少需要两个"源声音"和一个"主语音"。

DX::ThrowIfFailed(
    CoInitializeEx( nullptr, COINIT_MULTITHREADED )
);
Microsoft::WRL::ComPtr<IXAudio2> pXAudio2;
// Note that only IXAudio2 (and APOs) are COM reference counted
DX::ThrowIfFailed(
    XAudio2Create( pXAudio2.GetAddressOf(), 0 )
);
IXAudio2MasteringVoice* pMasteringVoice = nullptr;
DX::ThrowIfFailed(
    pXAudio2->CreateMasteringVoice( &pMasteringVoice )
);
IXAudio2SourceVoice* pSourceVoice1 = nullptr;
DX::ThrowIfFailed(
    pXaudio2->CreateSourceVoice( &pSourceVoice1, &wfx ) )
    // The default 'pSendList' will be just to the pMasteringVoice
);
IXAudio2SourceVoice* pSourceVoice2 = nullptr;
DX::ThrowIfFailed(
    pXaudio2->CreateSourceVoice( &pSourceVoice2, &wfx) )
    // Doesn't have to be same format as other source voice
    // And doesn't have to match the mastering voice either
);
DX::ThrowIfFailed(
    pSourceVoice1->SubmitSourceBuffer( &buffer )
);
DX::ThrowIfFailed(
    pSourceVoice2->SubmitSourceBuffer( &buffer /* could be different WAV data or not */)
);
DX::ThrowIfFailed(
    pSourceVoice1->Start( 0 );
);
DX::ThrowIfFailed(
    pSourceVoice2->Start( 0 );
);

您应该查看GitHub上的示例以及用于音频的DirectX工具包。

如果要确保两个源语音同时开始,则可以使用:

DX::ThrowIfFailed(
    pSourceVoice1->Start( 0, 1 );
);
DX::ThrowIfFailed(
    pSourceVoice2->Start( 0, 1 );
);
DX::ThrowIfFailed(
    pSourceVoice2->CommitChanges( 1 );
);

如果你想同时播放多个声音,有一个playSound功能,并启动各种线程来播放你的各种声音,每个声音都是某个源声音。

XAudio2 将负责将每个声音映射到可用通道(或者如果您有更高级的系统,您可以使用 IXAudio2Voice::SetOutputMatrix 自行指定映射(。

void playSound( IXAudio2SourceVoice* sourceVoice )
{
    BOOL isPlayingSound = TRUE;
    XAUDIO2_VOICE_STATE soundState = {0};
    HRESULT hres = sourceVoice->Start( 0u );
    while ( SUCCEEDED( hres ) && isPlayingSound )
    {// loop till sound completion
        sourceVoice->GetState( &soundState );
        isPlayingSound = ( soundState.BuffersQueued > 0 ) != 0;
        Sleep( 100 );
    }
}

例如,要同时播放两个声音:

IXAudio2SourceVoice* pSourceVoice1 = nullptr;
IXAudio2SourceVoice* pSourceVoice2 = nullptr;
// setup the source voices, load the sounds etc..
std::thread thr1{ playSound, pSourceVoice1 };
std::thread thr2{ playSound, pSourceVoice2 };
thr1.join();
thr2.join();

最新更新