Cannot play sound with win32 XAudio2 in window procedure callback

112 Views Asked by At

I'm preparing a birthday present for my classmate and I want to play the birthday song with XAudio2. However, I couldn't hear any sound. The code that plays sound was failed in window procedure, but succeed in main or WinMain.

The code below is from MSDN. It is called when WndProc got WM_PAINT message.

HRESULT hr = S_OK;
LPCWSTR strFileName = L".\\bgm.wav";
// Open the file
HANDLE hFile = CreateFile(
    strFileName,
    GENERIC_READ,
    FILE_SHARE_READ,
    NULL,
    OPEN_EXISTING,
    0,
    NULL);

if (INVALID_HANDLE_VALUE == hFile)
    return HRESULT_FROM_WIN32(GetLastError());

if (INVALID_SET_FILE_POINTER == SetFilePointer(hFile, 0, NULL, FILE_BEGIN))
    return HRESULT_FROM_WIN32(GetLastError());

DWORD dwChunkSize;
DWORD dwChunkPosition;
FindChunk(hFile, fourccRIFF, dwChunkSize, dwChunkPosition);
DWORD filetype;
ReadChunkData(hFile, &filetype, sizeof(DWORD), dwChunkPosition);
if (filetype != fourccWAVE) return S_FALSE;
FindChunk(hFile, fourccFMT, dwChunkSize, dwChunkPosition);
ReadChunkData(hFile, &(wfx), dwChunkSize, dwChunkPosition);
FindChunk(hFile, fourccDATA, dwChunkSize, dwChunkPosition);
BYTE* pDataBuffer = new BYTE[dwChunkSize];
ReadChunkData(hFile, pDataBuffer, dwChunkSize, dwChunkPosition);
buf.AudioBytes = dwChunkSize;
buf.pAudioData = pDataBuffer;
buf.Flags = XAUDIO2_END_OF_STREAM;
hr = pXAudio2->CreateSourceVoice(&(pSourceVoice), (WAVEFORMATEX*)&(wfx));
if (FAILED(hr)) return hr;  // My code returns here with XAUDIO_E_INVALID_CALL
if (FAILED(hr = pSourceVoice->SubmitSourceBuffer(&buf)))
    return hr;
pSourceVoice->Start();
return hr;

And what's more, where can I put the code if pXAudio2->CreateSourceVoice cannot be called in callback?

1

There are 1 best solutions below

2
YangXiaoPo-MSFT On

According to IXAudio2::CreateSourceVoice,

It is invalid to call CreateSourceVoice from within a callback (that is, IXAudio2EngineCallback or IXAudio2VoiceCallback). If you call CreateSourceVoice within a callback, it returns XAUDIO2_E_INVALID_CALL.