Search code examples
c++audiodirectxxaudio2

Why does XAudio2 play .wav files only when the system is paused?


I've followed the tutorial along Microsoft's website, and created my own SoundEngine and Sound class structure to have the code abstracted away in main, however whenever I make a call such as batmanWav->play(), it will only play the audio if I write std::cin.get() or system("PAUSE")

Why is this? I will be trying to port this to a game that's already been worked on, but I obviously don't want the game to stop every time a sound is played.

EDIT: I was asked to show some code which has the issues

int main() 
{
CoInitializeEx(nullptr, COINIT_MULTITHREADED);

Sound batman("batman.wav");
Sound alien("alien.wav");

alien.play();

batman.play();
system("PAUSE");
CoUninitialize();

}

Sound.cpp

HRESULT Sound::play()
{
HRESULT hr = S_OK;
if (FAILED(hr = pSourceVoice->Start(0)))
    return hr;

return hr;
}

For each Sound object I initialized a source voice, and each one refers to the same mastering voice and IXAudio2 *pXAudio2 object. The code I used to load wave file data was taken straight off MSDN docs.


Solution

  • As someone already noted, the problem is that your application exits before the sound really starts playing. XAudio2 is a non-blocking API, which means that you have to keep the memory live and the audio graph active until the sounds complete playing.

    In other words, when you called IXAudio2SourceVoice::Start, nothing happens except that it logs that you want to start the audio. Another thread which was created as part of your IXAudio2 object then sees the request and begins to process the playback request. By that point, your application has exited and the process terminated unless you 'pause'.

    Try something like the following from XAudio2BasicSound:

    hr = pSourceVoice->Start( 0 );
    
    // Let the sound play
    BOOL isRunning = TRUE;
    while( SUCCEEDED( hr ) && isRunning )
    {
        XAUDIO2_VOICE_STATE state;
        pSourceVoice->GetState( &state );
        isRunning = ( state.BuffersQueued > 0 ) != 0;
    
        Sleep( 10 );
    }
    

    You should look at these samples and at DirectX Tool Kit for Audio.