C++ XAudio2-仅播放部分音频

C++ XAudio2-仅播放部分音频,c++,audio,directx,xaudio2,C++,Audio,Directx,Xaudio2,我正在尝试使用xaudio2播放mp3/wma。我成功地使用了媒体基础源读取器对象来进行解码。我的问题是,它没有播放完整的音频;我只能播放部分音频 我想做的是,从IMFSourceReader获取下一个示例,并将其作为sourcevoice的下一个缓冲区提交。在从IMFSourceReader读取所有数据之前,将重复此操作 while (true) { DWORD dwFlags = 0; // Read the next sample. hr = pReader-&

我正在尝试使用xaudio2播放mp3/wma。我成功地使用了媒体基础源读取器对象来进行解码。我的问题是,它没有播放完整的音频;我只能播放部分音频

我想做的是,从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 sample\n");
        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);
    }

}
while(true)
{
DWORD dwFlags=0;
//阅读下一个示例。
hr=预订单->重新取样(
(DWORD)MF\u源\u读取器\u第一\u音频流,
0、NULL和dwFlags、NULL和pSample);
if(dwFlags&MF\u SOURCE\u READERF\u CURRENTMEDIATYPECHANGED)
{
printf(“类型更改-WAVE文件格式不支持。\n”);
打破
}
if(dwFlags&MF\u源\u读取器\u ENDOFSTREAM)
{
printf(“输入文件结束。\n”);
打破
}
if(pSample==NULL)
{
printf(“无样本”);
继续;
}
//获取指向示例中音频数据的指针。
hr=pSample->converttocontiguaousbuffer(&pBuffer);
如果(失败(hr)){break;}
hr=pBuffer->Lock(&pAudioData、NULL和&cbBuffer);
如果(失败(hr)){break;}
//确保不超过指定的最大尺寸。
if(cbMaxAudioData-cbAudioDataUnlock();
pAudioData=NULL;
如果(失败(hr)){break;}
//更新音频数据的运行总数。
cbAudioData+=cbBuffer;
如果(cbAudioData>=CBMAXAxAudioData)
{
打破
}
安全释放(&pSample);
安全释放(&pBuffer);
}
void AudioDecoder::SubmitBuffer(字节*pAudioData,int audioBufferLength)
{
byte*pAudioBuffer=新字节[audioBufferLength];
CopyMemory(pAudioBuffer、pAudioData、audioBufferLength);
if(pAudioBuffer!=nullptr)
{
//创建用于提交音频数据的XAUDIO2_缓冲区
XAUDIO2_缓冲区={0};
buffer.AudioBytes=audioBufferLength;
buffer.pAudioData=pAudioBuffer;
buffer.pContext=pAudioBuffer;
HRESULT HRESULT=m_p资源->提交资源缓冲区(&buffer);
}
}

在此之后,我调用m\u pSourceVoice->Start()。这将启动音频,但不会播放完整的音频。我还需要补充什么吗

如果在提交更多缓冲区之前已完成任何缓冲区,则此循环看起来无法解释,因此可能会运行到XAUDIO2_MAX_QUEUED_缓冲区的限制。您能否在while循环上创建一个计数器,以查看提交给源语音的缓冲区数量

如果达到限制,可以在完全解码文件之前开始播放,并通过源语音回调提交额外缓冲区。

是的,你是对的。。。我没有考虑XAUDIO2_MAX_队列缓冲区,这导致了问题。非常感谢你