我正在编写一个通过WASAPI在Windows上读取音频端点的应用程序。现在我有类似的捕获线程代码(将此代码视为最小示例):
DWORD CWASAPICapture::DoCaptureThread()
{
BYTE *pData;
UINT32 framesAvailable = 1;
DWORD flags, state;
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
if (FAILED(hr))
{
printf("Unable to initialize COM in render thread: %x\n", hr);
return hr;
}
while (framesAvailable != 0) {
// get the available data in the shared buffer.
state = WaitForSingleObject(_AudioSamplesReadyEvent, INFINITE);
hr = _CaptureClient->GetBuffer(&pData, &framesAvailable, &flags, NULL, NULL);
if ((state != 0) || (hr != S_OK)) {
// my breakpoint
assert(false);
}
UINT32 framesToCopy = min(framesAvailable, static_cast<UINT32>((_CaptureBufferSize - _CurrentCaptureIndex) / _FrameSize));
if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
{
ZeroMemory(&_CaptureBuffer[_CurrentCaptureIndex], framesToCopy*_FrameSize);
} else {
CopyMemory(&_CaptureBuffer[_CurrentCaptureIndex], pData, framesToCopy*_FrameSize);
}
_CurrentCaptureIndex += framesToCopy*_FrameSize;
// release data
hr = _CaptureClient->ReleaseBuffer(framesAvailable);
assert(hr == S_OK);
}
CoUninitialize();
return 0;
}
在Init部分,我请求缓冲区1s持续时间,blockAlign等于8,所以我的captureBufferSize = 3528000字节。 _AudioSamplesReadyEvent设置为_AudioClient-&gt; SetEventHandle(_AudioSamplesReadyEvent)。数据包大小= 441.其他代码基于官方Windows SDK CaptureSharedEventDriven示例,this method我已更改。
程序总是在我的断点上失败(按设计)并且我正在观察变量,期望值是hr = AUDCLNT_S_BUFFER_EMPTY(0x08890001)和_CurrentCaptureIndex = 3528000,我甚至从10个案例中获得了这个值。 ..通常hr = AUDCLNT_S_BUFFER_EMPTY(0x08890001)和_CurrentCaptureIndex等于随机值,最常见的是0,3528(8个数据包)和10584个(24个数据包)。
首先,当我刚开始使用带有_AudioClient-&gt; SetEventHandle的WaitForSingleObject时,我认为它在_AudioClient-&gt; Initialize()(MSDN描述非常流畅时)填充请求时间的缓冲区时发出信号但是那个错误,接下来我的建议是它等待一个数据包被填满,但正如我的例子所示,我没有缓冲区中的可用帧。我尝试使用GetNextPacketSize nex到WaitSingleObject,但结果仍然相同。
UPD1: Sleep()
放置之前,而不是WaitForSingleObject()
工作正常,我得到所有帧我的线程睡觉时间。
UPD2: minimal example