Salil
Salil

Reputation: 88

How do I construct a 16 bit sample from NAudio WaveIn?

I am reading the microphone using NAudio using the following code:

    WaveIn waveInStream;
    WaveFileWriter waveFileWriter;

    private void Form1_Load(object sender, EventArgs e)
    {
        waveInStream = new WaveIn();
        waveInStream.DataAvailable += new EventHandler<WaveInEventArgs>(waveInStream_DataAvailable);
        waveInStream.StartRecording();
        waveFileWriter = new WaveFileWriter("D:\\output.wav", waveInStream.WaveFormat);
    }

    void waveInStream_DataAvailable(object sender, WaveInEventArgs e)
    {
        UInt64 allVals = 0;
        for (int i = 0; i < e.BytesRecorded; i += 2)
        {
            allVals += (UInt64)(((int)e.Buffer[0] << 16) | ((int)e.Buffer[1]));
        }
        UInt64 avg = allVals / ((UInt64)e.BytesRecorded * 2);
        avg /= 1000;
        textBox1.AppendText(avg.ToString() + "\r\n");
        waveFileWriter.Write(e.Buffer, 0, e.BytesRecorded);
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        waveInStream.StopRecording();
        waveInStream.Dispose();
        waveFileWriter.Close();
    }

I haven't worked much with the averaging code. But I doubt I am constructing the 16 bit value correctly using the correct endianness. I tried both ways but I am not getting values that are proportional to the sound level in the room.

Upvotes: 0

Views: 1219

Answers (1)

Mark Heath
Mark Heath

Reputation: 49522

the 16 bit samples are signed, with zero representing silence, so your attempt of calculating an average using unsigned values will not work. You should use the absolute value of the Int16 samples.

Another way of converting the bytes to samples if you are not comfortable with bit shifting is to use the BitConverter class (the code you show does not work).

Upvotes: 3

Related Questions