2

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
litterbugkid
  • 3,534
  • 7
  • 36
  • 54
  • I assume you are trying to get the signal level in dB? In this case, 0db is the maximum, and everything else is negative. However, if you are trying to measure SPL, this is impossible. Your application is not aware of the microphone, gain structure in the audio device, etc. You would have to provide your own calibration method. – Brad Jan 08 '12 at 22:10
  • If everything else is negative how do I get a valid dB value from that? – litterbugkid Jan 10 '12 at 17:44
  • it *is* valid, but isn't sound pressure level... rather, it is the signal level relative to nominal (0dB, the highest representable signal level). Sound pressure level measured in dB is entirely different than signal level measured in dB. Measurements in dB are just measurements relative to something else. Again, without calibrating the microphone/device, you cannot convert from the signal level to SPL. – Brad Jan 10 '12 at 22:17
  • I'm having (almost) the same issue. I have the amplitude ratio and I'm using the same formulas to calculate dB value each 100ms or so, but somehow I'm getting more -Infinity than regular values (which looks a little bit strange). Maybe somehow we're calculating log10(0)? Did you find a solution for this? @Brad what are all the factors for calibrating the mic in the device? Are all of them measurable?(ps: I'm using getMaxAmpltitude to get the mic amp ratio which I think it's not considering them) ? – Wissem Sep 21 '12 at 16:23
  • @Wissem, You would need to know a scale of SPL to the signal dB measured of the device. This won't be a simple ratio. The microphone will be more sensitive to specific frequencies than others. The worst part of this though will be all of the signal filtering problems you are bound to run into. I'm sure there will be internal compression, EQ, and other processing happening before your application ever gets the signal. Turn as much of that off as possible. – Brad Sep 21 '12 at 16:42

1 Answers1

2

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.

Community
  • 1
  • 1
Matthieu
  • 16,103
  • 10
  • 59
  • 86
  • I've got the raw pcm bytes like that link you've given, but when I use your formula it comes out with infinity :/ As I'm recording I'm using the last 2 byte values in the byte array, is this wrong? – litterbugkid Jan 07 '12 at 20:04
  • if you use getAudioFormat, that will tell you if the audio is 8bit or 16bits.... from there, you know if you should use only 1 byte or 2. You should probably debug by looking at what value you get in the data, do the math by hand and make sure your code is doing the right thing (post if if you are not sure) – Matthieu Jan 07 '12 at 22:20
  • I found that I get the audio in 16 bits. I have copied the formulas I'm using above and I'm not sure if my results are correct. – litterbugkid Jan 08 '12 at 11:44
  • Tried out your code, it seems to always come out with -Infinity. I've posted the variable tracking above to see what you think. – litterbugkid Jan 11 '12 at 16:43
  • You can see that p2 is always 0... try to print data[data.length-1], or maybe you should use data[0] instead. – Matthieu Jan 11 '12 at 17:28