Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate decibels

Tags:

I'm recording mic input using the XNA library (I don't think this is really technology specific, but it never hurts). Every time I get a sample I would like to calculate the decibels. I have done many searches on the internet and not found a rock solid example...

Here is my attempt at calculating decibels from a sample:

        double peak = 0;          for (var i = 0; i < _buffer.Length; i = i + 2)         {             var sample = BitConverter.ToInt16(_buffer, i);             if (sample > peak)                 peak = sample;             else if (sample < -peak)                 peak = -sample;         }          var decibel = (20 * Math.Log10(peak/32768)); 

If I output the decibel value to the screen I can see the values get higher as I get louder and lower as I speak softer. However, it always hovers around -40 when I'm absolutely quiet...I would assume it would be -90. I must have a calculation wrong in the block above?? from what I have read on some sites -40 is equivalent to "soft talking"...however, it's totally quiet.

Also, If I mute my mic it goes straight to -90.

Am I doing it wrong?

like image 568
Ryan Eastabrook Avatar asked Nov 11 '10 07:11

Ryan Eastabrook


People also ask

How loud is 60 decibels?

Sound is measured in decibels (dB). A whisper is about 30 dB, normal conversation is about 60 dB, and a motorcycle engine running is about 95 dB. Noise above 70 dB over a prolonged period of time may start to damage your hearing. Loud noise above 120 dB can cause immediate harm to your ears.


1 Answers

When measuring the level of a sound signal, you should calculate the dB from the RMS value. In your sample you are looking at the absolute peak level. A single (peak) sample value determines your dB value, even when all other samples are exactly 0.

try this:

double sum = 0; for (var i = 0; i < _buffer.length; i = i + 2) {     double sample = BitConverter.ToInt16(_buffer, i) / 32768.0;     sum += (sample * sample); } double rms = Math.Sqrt(sum / (_buffer.length / 2)); var decibel = 20 * Math.Log10(rms); 

For 'instantaneous' dB levels you would normally calculate the RMS over a segment of 20-50 ms. Note that the calculated dB value is relative to full-scale. For sound the dB value should be related to 20 uPa, and you will need to calibrate your signal to find the proper conversion from digital values to pressure values.

like image 150
Han Avatar answered Sep 22 '22 12:09

Han