Reputation: 187
Well I was trying to use AndroidRecorder to get maxAmplitude() and convert it in decibel.
Here is the formula I am using - Double powerDb = 20 * log10((mRecorder.getMaxAmplitude()/2700.0));
But when I see my logs for powerDB I see values ranging from negative 15 to 21.8 (Positive).
How much I shout in front of mic that does not go above 21.8 and sometimes normally speaking it goes to 21.8.
How can I get more width in values so I can actual differentiate between low and high sound, I am planning to trigger my app on the basis of some loud sound.
Upvotes: 1
Views: 399
Reputation: 9341
Your first problem lies in how you are scaling numbers. GetMaxAmplitude
returns a value between 0 and 32767. You want this number scaled to a value between 0 and 1. To do that you need to divide by 32767 not 2700 (where did that number come from?).
double maxAmplScaled = mRecorder.getMaxAmplitude/32767.0;
Now that you have your data scaled correctly you can convert to dB. This will give you a decibel number between minus infinity and zero.
double db = 20*log10(maxAmplScaled);
// 20*log10(0) == -inf
// 20*log10(1) == 0
From this point your question about "width in values" is a bit of a misunderstanding of a decibel (logarithmic) scale. When thinking in decibels, every -6 dB represents a halving of the level. Or every -20 dB represents a divide by 10.
// dividing by 2s
20*log10(1) == 0
20*log10(0.5) == -6.0205
20*log10(0.25) == -12.041
20*log10(0.125) == -18.062
// or dividing by 10s
20*log10(1) == 0
20*log10(0.1) == -20
20*log10(0.01) == -40
20*log10(0.001) == -60
In a log scale like dB you can just as easily differentiate the numbers but you do so by using addition/subtraction instead of by division/multiplication.
In a linear scale if you wanted to determine if amplitude A
was less than half of amplitude B
you would use division. if (amplitudeB < amplitudeA/2)...
whereas in a dB scale you would use subtraction: if (dbB < dbA-6.0205)...
.
Upvotes: 2