连续WASAPI环形缓冲区采样

时间:2018-11-18 18:23:49

标签: c++ winapi audio sampling wasapi

如何使用WASAPI(或类似的东西)将音频连续采样到(线程安全的)环形缓冲区中,以便使用者线程可以在设定的时间间隔内从该缓冲区读取?

当前,我们有一个.sample()方法,该方法在设定的采样间隔后返回大量样本,但是由于内存分配等原因,这会产生相当大的开销。我很确定我们做错了。

std::vector<short> sampler2::sample()
{
    // prepare header
    waveInPrepareHeader(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

    // insert a wave input buffer
    waveInAddBuffer(hWaveIn, &WaveInHdr, sizeof(WAVEHDR));

    // commence sampling input
    waveInStart(hWaveIn);

    // sleep for the duration of a sample interval
    std::this_thread::sleep_for(milliseconds(SAMPLE_INTERVAL));

    // create vector
    std::vector<short> samplesChunk(&waveIn[0], &waveIn[0] + NUMPTS);

    // return vector
    return samplesChunk;
}

GitHub链接:sampler2.hsampler2.cpp

代码很糟糕,我们不知道如何正确使用WASAPI。我们的目标是(快速)创建一个可以利用大于10毫秒的采样间隔的采样器类。

1 个答案:

答案 0 :(得分:1)

您的示例使用waveout API。您可以检查MSDN以获得WASAPI参考和使用情况。 这是WASAPI用法的基本描述: 客户端调用IAudioRenderClient接口中的方法以将渲染数据写入端点缓冲区。要请求特定大小的端点缓冲区,客户端将调用IAudioClient::Initialize方法。为了获得分配的缓冲区的大小(可能与请求的大小不同),客户端调用IAudioClient::GetBufferSize方法。 要通过端点缓冲区移动渲染数据流,客户端会交替调用IAudioRenderClient::GetBuffer方法和IAudioRenderClient::ReleaseBuffer方法。客户端以一系列数据包的形式访问端点缓冲区中的数据。 GetBuffer调用检索下一个数据包,以便客户端可以用渲染数据填充它。在将数据写入数据包之后,客户端调用ReleaseBuffer将完成的数据包添加到呈现队列中。 还有此Microsoft C ++ WASAPI example