XAudio2-只播放部分音频

XAudio2 - playing only a part of the audio

本文关键字:音频 播放部 XAudio2-      更新时间:2023-10-16

我正在尝试使用xaudio2播放mp3/wma。我设法使用Media Foundation Source Reader对象来进行解码。我的问题是,它没有播放完整的音频;我只能播放一部分音频。

我想做的是,从IMFSourceReader获得下一个样本,并将其作为sourcevoice的下一个缓冲区提交。重复此操作直到从IMFSourceReader读取所有数据。

 while (true)
{
    DWORD dwFlags = 0;
    // Read the next sample.
    hr = pReader->ReadSample(
        (DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM,
        0, NULL, &dwFlags, NULL, &pSample );

    if (dwFlags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED)
    {
        printf("Type change - not supported by WAVE file format.n");
        break;
    }
    if (dwFlags & MF_SOURCE_READERF_ENDOFSTREAM)
    {
        printf("End of input file.n");
        break;
    }
    if (pSample == NULL)
    {
        printf("No samplen");
        continue;
    }
    // Get a pointer to the audio data in the sample.
    hr = pSample->ConvertToContiguousBuffer(&pBuffer);
    if (FAILED(hr)) { break; }

    hr = pBuffer->Lock(&pAudioData, NULL, &cbBuffer);
    if (FAILED(hr)) { break; }

    // Make sure not to exceed the specified maximum size.
    if (cbMaxAudioData - cbAudioData < cbBuffer)
    {
        cbBuffer = cbMaxAudioData - cbAudioData;
    }
    // Write this data to the output file.
    hr = WriteToFile(hFile, pAudioData, cbBuffer);
    int audioBufferLength = cbBuffer;

    if (FAILED(hr)) { break; }
    SubmitBuffer(pAudioData, audioBufferLength);
    // Unlock the buffer.
    hr = pBuffer->Unlock();

    pAudioData = NULL;
    if (FAILED(hr)) { break; }
    // Update running total of audio data.
    cbAudioData += cbBuffer;
    if (cbAudioData >= cbMaxAudioData)
    {
        break;
    }
    SafeRelease(&pSample);
    SafeRelease(&pBuffer);
}
void AudioDecoder::SubmitBuffer(byte *pAudioData, int audioBufferLength)
{
    byte * pAudioBuffer = new byte[audioBufferLength];
    CopyMemory(pAudioBuffer, pAudioData, audioBufferLength);
    if (pAudioBuffer != nullptr)
    {
     // Create an XAUDIO2_BUFFER for submitting audio data
     XAUDIO2_BUFFER buffer = {0};
     buffer.AudioBytes = audioBufferLength;
     buffer.pAudioData = pAudioBuffer;
     buffer.pContext = pAudioBuffer;
     HRESULT hresult = m_pSourceVoice->SubmitSourceBuffer(&buffer);
    }
}

在此之后,我将调用m_pSourceVoice->Start()。这将启动音频,但不会播放完整的音频。我还需要添加其他内容吗?

这个循环看起来不考虑在提交更多缓冲区之前是否已经完成任何缓冲区,因此可能会达到XAUDIO2_MAX_QUEUED_buffers的限制。你能在while循环中创建一个计数器来查看有多少缓冲区提交给源语音吗?

如果你达到了限制,你可以在完全解码文件之前开始播放,并通过源语音回调提交额外的缓冲区。http://msdn.microsoft.com/en-us/library/windows/desktop/ee415769(v=vs.85).aspx