Search code examples
audiowasapi

Infinite loop reading packet data in 1sec loopback recording


I ported the MSDN capture stream example - https://msdn.microsoft.com/en-us/library/windows/desktop/dd370800

and modified it for loopback, exactly as seen here -

https://github.com/slavanap/WaveRec/blob/754b0cfdeec8d1edc59c60d179867ca6088bbfaa/wavetest.cpp

So I am requesting a duration of 1 second recording, and actual duration verifies that it is 1 second.

However I am stuck in an infinite loop in this packet reading here, packetLength is always a value of 448 (numFramesAvailable is also 448, I'm not sure why its never becoming 0 as the while loop is expecting.

https://github.com/slavanap/WaveRec/blob/754b0cfdeec8d1edc59c60d179867ca6088bbfaa/wavetest.cpp#L208-L232

Code is -

        while (packetLength != 0)
        {
            // Get the available data in the shared buffer.
            hr = pCaptureClient->GetBuffer(
                                   &pData,
                                   &numFramesAvailable,
                                   &flags, NULL, NULL);
            EXIT_ON_ERROR(hr)

            if (flags & AUDCLNT_BUFFERFLAGS_SILENT)
            {
                pData = NULL;  // Tell CopyData to write silence.
            }

            // Copy the available capture data to the audio sink.
            // hr = pMySink->CopyData(pData, numFramesAvailable, &bDone);
            // EXIT_ON_ERROR(hr)

            hr = pCaptureClient->ReleaseBuffer(numFramesAvailable);
            EXIT_ON_ERROR(hr)

            hr = pCaptureClient->GetNextPacketSize(&packetLength);
            EXIT_ON_ERROR(hr)
        }

My ported code is in ctypes and is here - https://github.com/Noitidart/ostypes_playground/blob/audio-capture/bootstrap.js#L71-L180


Solution

  • I guess, there is hidden bug in Microsoft example that appears to happen in your case. Inner loop processing time of your code is much enough that new data appears in incoming audio buffer, thus leaving you spin in inner loop forever or until you can process incoming data at decent speed. Thus, I suggest to add && !bDone condition to inner loop.

    while (bDone == FALSE)
    {
        ...
    
        while (packetLength != 0 && bDone == FALSE)
        {
            ...
        }
    }