1

我运行以下代码:

void SoundOut()
{
    HWAVEOUT wo;
    WAVEHDR whdr;
    whdr.dwBufferLength = std::vector<SampleType>::size() * m_format.nBlockAlign;
    whdr.lpData = reinterpret_cast<LPSTR>(&(std::vector<SampleType>::front()));
    whdr.dwFlags = 0;
    cout << "waveOpen result " << waveOutOpen(&wo, WAVE_MAPPER, &m_format, 0, 0, CALLBACK_NULL) << endl;;
    cout << "waveOutPrepareHeader" << waveOutPrepareHeader(wo, &whdr, sizeof(WAVEHDR)) << endl;;
    cout << "waveOutWrite" << waveOutWrite(wo, &whdr, sizeof(WAVEHDR)) << endl;;
    cout << "waveOutUnprepareHeader" << waveOutUnprepareHeader(wo, &whdr, sizeof(WAVEHDR)) << endl;;
    cout << "waveOutClose" << waveOutClose(wo) << endl;;
};

标准输出如下所示:

waveOpen result 0
waveOutPrepareHeader 0
waveOutWrite 0
waveOutUnprepareHeader 33
waveOutClose 33

根据 SOUNDWIN.H 文件,代码 33 表示 WAVERR_STILLPLAYING。但是没有听到任何声音,waveOutWrite 立即返回(将 88000 个样本写入声卡)。建议这个立即返回意味着代码 33,但是为什么 waveOutWrite 立即返回并且什么也没听到?
通常,为什么 waveOutWrite 成功完成并且没有任何声音?
去哪里看?

4

3 回答 3

1

您应该准备一次缓冲区,然后在播放完成时取消准备它们。缓冲区可以在两者之间重复使用,但在播放的同时准备/取消准备缓冲区通常不是一个好主意。

问题来自这样一个事实,即当您写入数据时会立即排队等待播放(请记住,waveOut API 仅是仿真/兼容层),但是缓冲区稍后会在延迟回调中返回。请参阅关于此的WOM_DONE 消息。仅当 API 不再使用缓冲区时才允许取消准备。

于 2012-10-19T10:23:01.497 回答
0

您开始播放缓冲区并尝试立即释放它......您应该在清理所有内容(waveOutUnprepareHeader,waveOutClose)之前停止声音(调用waveOutStop或waveOutReset)。无论如何,如果您想听到任何声音,您应该稍后在另一个函数中停止声音(或者至少在停止声音之前插入睡眠)。

于 2015-08-06T09:36:47.403 回答
0

我通过轮询声音播放和延迟解决了这个问题:

WAVEHDR header = { buffer, sizeof(buffer), 0, 0, 0, 0, 0, 0 };
waveOutPrepareHeader(hWaveOut, &header, sizeof(WAVEHDR));
waveOutWrite(hWaveOut, &header, sizeof(WAVEHDR));
/*
* wait a while for the block to play then start trying
* to unprepare the header. this will fail until the block has
* played.
*/
while (waveOutUnprepareHeader(hWaveOut,&header,sizeof(WAVEHDR)) == WAVERR_STILLPLAYING) 
Sleep(100);
waveOutClose(hWaveOut);

在 Windows 中使用 waveOut 接口播放音频

于 2016-03-18T10:59:26.550 回答