如何使用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.h和sampler2.cpp
代码很糟糕,我们不知道如何正确使用WASAPI。我们的目标是(快速)创建一个可以利用大于10毫秒的采样间隔的采样器类。
答案 0 :(得分:1)
您的示例使用waveout API。您可以检查MSDN以获得WASAPI参考和使用情况。 这是WASAPI用法的基本描述: 客户端调用IAudioRenderClient接口中的方法以将渲染数据写入端点缓冲区。要请求特定大小的端点缓冲区,客户端将调用IAudioClient::Initialize方法。为了获得分配的缓冲区的大小(可能与请求的大小不同),客户端调用IAudioClient::GetBufferSize方法。 要通过端点缓冲区移动渲染数据流,客户端会交替调用IAudioRenderClient::GetBuffer方法和IAudioRenderClient::ReleaseBuffer方法。客户端以一系列数据包的形式访问端点缓冲区中的数据。 GetBuffer调用检索下一个数据包,以便客户端可以用渲染数据填充它。在将数据写入数据包之后,客户端调用ReleaseBuffer将完成的数据包添加到呈现队列中。 还有此Microsoft C ++ WASAPI example。