WasapiLoopbackCapture DataAvailable event reads duplicate wrong data, even if the device is not playing any sound

55 views Asked by At

When using WasapiLoopbackCapture, in the DataAvailable event, the buffer reads duplicate data.

WasapiCapture = wasapiCapture; // "WasapiCapture" is a local variable.
WasapiCapture.WaveFormat = new WaveFormat(44100, 16, 2);
WasapiCapture.DataAvailable += WaveIn_DataAvailable;
WasapiCapture.StartRecording();

Here is the definition of WaveIn_DataAvailable(the code is correct):

private void WaveIn_DataAvailable(object? sender, WaveInEventArgs e)
{
    int bytesPerSamplePerChannel = WasapiCapture.WaveFormat.BitsPerSample / 8;
    int bytesPerSample = bytesPerSamplePerChannel * WasapiCapture.WaveFormat.Channels;
    int bufferSampleCount = e.Buffer.Length / bytesPerSample;

    if (bufferSampleCount >= AudioValuesL.Length)
    {
        bufferSampleCount = AudioValuesL.Length;
    }
    // Convert to floats with value from -1 to 1
    for (int i = 0; i < bufferSampleCount; i++)
    {
        AudioValuesL[i] = BitConverter.ToInt16(e.Buffer, i * bytesPerSample) / 32768d;
        AudioValuesR[i] = BitConverter.ToInt16(e.Buffer, i * bytesPerSample + 2) / 32768d;
    }
}

When the application runs to a certain point, the data in the converted AudioValuesL and AudioValuesR appears to be the same as the last time, and there is no problem with the conversion code. It may be that there is a problem with the buffer received by WaveInEventArgs, and this duplication is likely to occur in GC collecting.

Is there any way to solve this problem? Because when this problem occurs, I can't receive any valid data, even if the device is not playing any sound, I keep receiving a piece of wrong audio data.

Since WasapiLoopcackCapture is derived from WasapiCapture, I checked the source code of WasapiCapture, after enable(line 281, NAudio/NAudio.Wasapi/WasapiCapture.cs)

//Debug.WriteLine(string.Format("packet size: {0} samples", packetSize / 4));

in ReadNextPacket method, run the program. Everything was working fine at first, the debug output window was outputting normal values, and when I started receiving duplicate data, it kept outputting "packet size: 0 samples".

1

There are 1 answers

0
Mark Heath On

You should use the BytesRecorded property of the WaveInEventArgs, instead of Buffer.Length. The buffer can be larger than the number of bytes that have been captured.