WINAPI如何处理IAudioClient-> SetEventHandle()有效?

时间:2017-06-26 12:16:55

标签: c++ windows winapi audio-recording wasapi

我正在编写一个通过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,但结果仍然相同。

我的问题是:

  1. 为什么我的例子会那样工作?
  2. 究竟是什么IAudioClient-&gt; SetEventHandle()发出关于WaitForSingleObject()的信号?
  3. 如何正确读取我要求的大小的缓冲区?
  4. UPD1: Sleep()放置之前,而不是WaitForSingleObject()工作正常,我得到所有帧我的线程睡觉时间。

    UPD2: minimal example

0 个答案:

没有答案