0

I'm pretty new to this so I'll try to explain as best I can. I want to count the number of times the audio level goes above a certain level. I have found/created some code which can detect if the level has gone above a certain threshold, but can't figure out how to count the number of times it has risen above that threshold reliably. the sound/noise is being created by a switch which is connected to the microphone, every time it switches a noise is created by the switching. Do I need to use some sort of filtering?

C#.net Naudio Library Steve.

    public void StartListening()
    {
        WaveIn waveInStream = new WaveIn();
        waveInStream.BufferMilliseconds = 500;
        waveInStream.DataAvailable += new EventHandler<WaveInEventArgs>(waveInStream_DataAvailable);
        waveInStream.StartRecording();
    }

    //Handler for the sound listener
    private void waveInStream_DataAvailable(object sender, WaveInEventArgs e)
    {
        bool result = ProcessData(e);
        if (result)
        {
            intCounter++;
            label1.Text = intCounter.ToString();
        }
        else
        {
            //no peak in sound
        }
    }

    //calculate the sound level based on the AudioThresh
    private bool ProcessData(WaveInEventArgs e)
    {
        bool result = false;

        bool Tr = false;
        double Sum2 = 0;
        int Count = e.BytesRecorded / 2;
        for (int index = 0; index < e.BytesRecorded; index += 2)
        {
            double Tmp = (short)((e.Buffer[index + 1] << 8) | e.Buffer[index + 0]);
            Tmp /= 32768.0;
            Sum2 += Tmp * Tmp;
            if (Tmp > AudioThresh)
                Tr = true;
        }

        Sum2 /= Count;

        // If the Mean-Square is greater than a threshold, set a flag to indicate that noise has happened
        if (Sum2 > AudioThresh)
        {
            result = true;
        }
        else
        {
            result = false;
        }
        return result;
    }

1 Answers1

0

Firstly, you should be dealing with audio in decibels. This post here includes a c# sharp example on how to calculate your audio buffer as an RMS value in decibels:

Calculate decibels in c#

Secondly, split your methods so that their names are meaningful thus easier to read and manage. You have named your method ProcessData and it returns a bool but the comment on the method is: calculate the sound level based on the AudioThresh. I suggest you split it up for example:

private float calculateDBinRMS(buffer){
 // This method calculates and returns the RMS value of the buffer in DB
}

private bool hasReachedThreshold(buffer, AudioThres) {
 if(calculateDBinRMS(buffer) >= AudioThres)
  return true;
 return false;
}

I'm not sure where your AudioThres is coming from in the first place but using the above code, it should be in decibels.

Filtering won't completely eliminate transient signals even though they do tend to reside in the higher frequency ranges (generally speaking, domestic audio recorded with a microphone). The buffer length will have the greatest impact in determining an overall peak vs average RMS figure. A small buffer will give you more of a 'peak' result and a larger buffer will give you more of average overall (RMS) value which is probably what you are after.

Also, the noise in general that you are experiencing from your microphone might be coming from a dirty switch or dirty connections from the microphone to your computer.

After all of this is considered, counting the number of times the threshold is reached should be trivial.

Community
  • 1
  • 1
ronnied
  • 106
  • 1
  • 4