Search code examples
c#bufferarraysnaudiopcm

NAudio C#: How to obtain a byte array from WaveInEventArgs for further manipulation


I have developed an Android application which is working and is trying to make a C# version of it. I'm stuck at trying to retrieve the buffer data and passing it into a byte array. I have referenced my project to NAudio etc.

My project now enables me to read microphone input and output it through the speakers at almost no lag, as I have adjusted the latency programmatically. However, I have difficulty trying to retrieve the buffer data, how do I play around with the waveInEventArgs? I do understand that data from waveIn gets passed into the waveInEventArgs.buffer but I just cannot retrieve the buffer data to place it. How do I go about it?

Here are my codes:

    private void RecorderOnDataAvailable(object sender, WaveInEventArgs waveInEventArgs)
    {
        bufferedWaveProvider.AddSamples(waveInEventArgs.Buffer, 0, waveInEventArgs.BytesRecorded);
    }

    public String processAudioFrame(short[] audioFrame)
    {
        double rms = 0;
        for (int i = 0; i < audioFrame.Length; i++)
        {
            rms += audioFrame[i] * audioFrame[i];
        }

        rms = Math.Sqrt(rms / audioFrame.Length);

        double mGain = 2500.0 / Math.Pow(10.0, 90.0 / 20.0);
        double mAlpha = 0.9;
        double mRmsSmoothed = 0;

        //compute a smoothed version for less flickering of the display
        mRmsSmoothed = mRmsSmoothed * mAlpha + (1 - mAlpha) * rms;
        double rmsdB = 20.0 * Math.Log10(mGain * mRmsSmoothed);

        //assign values from rmsdB to debels for comparison in errorCorrection() method
        double debels = rmsdB + 20;

        String value = debels.ToString();
        return value;
    }

The variable value will be returned as a string to display the outcome at the textbox that I have implemented in the design.

Thank you! I just embarked on this project 2 days ago so explaining it in simpler terms is much appreciated.


Solution

  • Probably the easiest approach is for you to convert the byte array into a short array using Buffer.BlockCopy and then pass it into your processAudioFrame function. Something like this:

     short[] sampleData = new short[waveInEventArgs.BytesRecorded / 2];
     Buffer.BlockCopy(waveInEventArgs.Buffer, 0, sampleData, 0, waveInEventArgs.BytesRecorded);
     var decibels = processAudioFrame(sampleData)