Get decibel values whilst recording sound?

Neeta picture Neeta · Jan 7, 2012 · Viewed 8.6k times · Source

Is there a way of getting the decibel value of sound whilst it's being recorded? I'm using MediaRecorder to record the sound at the moment

I can't use any applications on the Marketplace as I can't be sure the user will have it installed on their phone e.g. Audalyzer

I'm using the following formulas but not sure if they're correct or if my results are correct!

short data[] = new short[bufferSize];
read = recorder.read(data, 0, bufferSize);
double p2 = data[data.length-1];
System.out.println("p2: " + p2);
double decibel;

if (p2==0)
   decibel=Double.NEGATIVE_INFINITY;
else
   decibel = 20.0*Math.log10(p2/65535.0);
   System.out.println("p2/65535: " + (p2/65535.0));

System.out.println("decibel: " + decibel);

Current results:

    01-11 16:43:03.821: I/System.out(14530): p2: 0.0
01-11 16:43:03.821: I/System.out(14530): p2/65535: 0.0
01-11 16:43:03.821: I/System.out(14530): decibel: -Infinity
01-11 16:43:03.911: I/System.out(14530): p2: 0.0
01-11 16:43:03.911: I/System.out(14530): p2/65535: 0.0
01-11 16:43:03.911: I/System.out(14530): decibel: -Infinity
01-11 16:43:04.001: I/System.out(14530): p2: 0.0
01-11 16:43:04.001: I/System.out(14530): p2/65535: 0.0
01-11 16:43:04.001: I/System.out(14530): decibel: -Infinity
01-11 16:43:04.091: I/System.out(14530): p2: 0.0
01-11 16:43:04.091: I/System.out(14530): p2/65535: 0.0
01-11 16:43:04.091: I/System.out(14530): decibel: -Infinity
01-11 16:43:04.191: I/System.out(14530): p2: 0.0
01-11 16:43:04.191: I/System.out(14530): p2/65535: 0.0
01-11 16:43:04.191: I/System.out(14530): decibel: -Infinity
01-11 16:43:04.281: I/System.out(14530): p2: 0.0
01-11 16:43:04.281: I/System.out(14530): p2/65535: 0.0
01-11 16:43:04.281: I/System.out(14530): decibel: -Infinity
01-11 16:43:04.371: I/System.out(14530): p2: 0.0
01-11 16:43:04.371: I/System.out(14530): p2/65535: 0.0
01-11 16:43:04.371: I/System.out(14530): decibel: -Infinity

Answer

Matthieu picture Matthieu · Jan 7, 2012

Using AudioRecord, you can access the audio samples directly... from there, you can compute the volume of the sounds in decibels or whichever way you want to...

This seems to be about the same question too (and has the formula for the calculation)

EDIT (based on the comments and extra code):

Now, the variable data[] you are using is it declared as an array or bytes or of shorts? That will change which one of the read() function will be used. If you declare it as shorts, then that will take care of your 16 bits. If you declare it as an array of bytes, you'll have to combine two consecutive bytes.

You should not worry about negative and positive values, you should just declare data[] as an array of 'unsigned short'.

You need to understand the decibel value is comparing your current volume to something else. I am not really an expert, but I believe most of the time you compare it to the maximum possible amplitude. I believe, right now, the calculation you are doing is comparing two consecutive samples, that's why the value is rather low... Instead of p1, use value 65535 (that's the maximum value possible) instead. Then you should see the decibel value is a negative value when there is nothing and should increase with noise (but still remain negative).

EDIT (based on latest code):

Since the sample size is 16 bits, use shorts...

short buffer[] = new short[bufferSize];
read = recorder.read(buffer, 0, bufferSize);
double p2 = data[data.length-1];
double decibel;
if (p2==0)
    decibel=Double.NEGATIVE_INFINITY;
else
    decibel = 20.0*Math.log10(p2/65535.0);

Try to print all the values along the way (data[data.length-1], p2, p2/65535, Math.log10(p2/65535)...etc...) you'll find where there is a 0 coming up where there should not.