0

I'm using NAudio to generate a WAV file. The Wav file contains environment noise (detected and recorded via mic). I need to process this file to show average loudness (dB) against different frequency bands. I read much about 1:3 Octave band analysis where the frequency windows are 31, 62, 125, 250, 500 Hz and so on. And we can have an average loudness against each window. This is exactly what I want to do but HOW to achieve this seems confusing. What I have done so far is (using NAudio tutorial) to read a WAV file and process it. Here is the code:

private void RenderFile()
{
    using (WaveFileReader reader = new WaveFileReader(this.voiceRecorderState.ActiveFile))
    {
        this.samplesPerSecond = reader.WaveFormat.SampleRate;
        SampleAggregator.NotificationCount = reader.WaveFormat.SampleRate/10;
        //Sample rate is 44100

        byte[] buffer = new byte[1024];
        WaveBuffer waveBuffer = new WaveBuffer(buffer);
        waveBuffer.ByteBufferCount = buffer.Length;
        int bytesRead;
        do
        {
            bytesRead = reader.Read(waveBuffer, 0, buffer.Length);
            int samples = bytesRead / 2;

            double sum = 0;
            for (int sample = 0; sample < samples; sample++)
            {
                if (bytesRead > 0)
                {
                    sampleAggregator.Add(waveBuffer.ShortBuffer[sample] / 32768f);
                    double sample1 = waveBuffer.ShortBuffer[sample] / 32768.0;
                    sum += (sample1 * sample1);

                }
            }
            double rms = Math.Sqrt(sum / (SampleAggregator.NotificationCount));
            double decibel = (double)(20 * Math.Log10(rms));
            if (calculatedBCount == 0)
            {
                dBList.Add(decibel);
                //  System.Diagnostics.Debug.WriteLine(decibel.ToString() + " in dB");
            }
        } while (bytesRead > 0);
        int totalSamples = (int)reader.Length / 2;
        TotalWaveFormSamples = totalSamples / sampleAggregator.NotificationCount;
        calculatedBCount++;
        SelectAll();

        //System.Diagnostics.Debug.WriteLine("Average Noise: " + avg.ToString() + " dB");
    }
    audioPlayer.LoadFile(this.voiceRecorderState.ActiveFile);
}


public int Read(byte[] buffer, int offset, int count)
{
    if (waveBuffer == null || waveBuffer.MaxSize < count)
    {
        waveBuffer = new WaveBuffer(count);
    }

    int bytesRead = source.Read(waveBuffer, 0, count);

    if (bytesRead > 0) bytesRead = count;

    int frames = bytesRead / sizeof(float); // MRH: was count
    float pitch = pitchDetector.DetectPitch(waveBuffer.FloatBuffer, frames);
    PitchList.Add(pitch);
    return frames * 4;
}

Using a 5 second WAV file, from above two methods, I get a list of Pitches and Decibels The decibels list contains 484 values like:

-56.19945639
-55.13139952
-55.06947441
-56.70789076
-57.24140093
-55.98546603
-55.67407176
-55.53060998
-55.98480268
-54.85796943
-57.00735818
-55.64980974
-57.07235475

PitchList contains 62 values which include:

75.36621
247.631836
129.199219
75.36621
96.8994141
96.8994141
86.13281
75.36621
129.199219
107.666016

How can I use these results for identifying what is average loudness against 31Hz, 62Hz, 125Hz, 250Hz and so on.

Am I doing some wrong or everything wrong, maybe?

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
imran2155
  • 111
  • 1
  • 11

1 Answers1

0

Please correct me if I am wrong but...I'm afraid You cannot convert HZ to DB because there is no relation between them. Hz is a measure of frequency and Db is a measure of amplitude, sort like kilos to meters.

joint_ops
  • 312
  • 1
  • 5
  • 20
  • Thanks for response. I think Fast Fourier Transform algorithm is used for this purpose. And NAudio uses FFt to switch from time to frequency domain. – imran2155 Nov 24 '15 at 16:07