What does Android's getMaxAmplitude() function for the MediaRecorder actually give me?

Lukas Ruge picture Lukas Ruge · May 18, 2012 · Viewed 18k times · Source

The Android MediaRecorder has a function

.getMaxAmplitude();
which, as the API tells me, "Returns the maximum absolute amplitude that was sampled since the last call to this method." but I can't find what amplitude this is? Is it in pascal or watts?

I have found on several pages on the web that you can calculate a value closely corelated to decibels using (as suggested here).

double db = (20 * Math.log10(amplitude / REFERENCE)); 

which would let me assume that the returned value is in some linear scale (probably something like milipascal...)

REFERENCE=0.1 (I am aware that this should be something like 2*10^(-5) Pascal ((20 uPascal)), but that returns strange values... 0.1 strangely works better.)

Right now I measure the MaxAmplitude() using the

getMaxAmplitude()
and put this into the variable amplitude.

This is the method:

public double getNoiseLevel() 
{
    //Log.d("SPLService", "getNoiseLevel() ");
    int x = mRecorder.getMaxAmplitude();
    double x2 = x;
    Log.d("SPLService", "x="+x);
    double db = (20 * Math.log10(x2 / REFERENCE));
    //Log.d("SPLService", "db="+db);
    if(db>0)
    {
        return db;
    }
    else
    {
        return 0;
    }
}

This is done 5 times in half a second, which gets kind of an average

for(int i=0; i<5; i++)
{
    try 
    {
            Thread.sleep(100);
    } 
    catch (InterruptedException e) 
    {
            e.printStackTrace();
            return 0;
    }
    level = level+getNoiseLevel();
    if(level>0)
    {
        counter++;
    }
}
level=level/counter;
Log.d(LOG_TAG, "level="+level);

I get something that kinda looks like decibel but I'm not sure its actualy decibel at all...

So, could anyone help me on this? It seems very odd that the API does not specefy at all what is returned...

Answer

Lukas Ruge picture Lukas Ruge · Oct 17, 2012

I could find the answer to this question and I'll share it here for anyone who cares: The MediaRecorder.getMaxAmplitude() function returns unsigned 16-bit integer values (0-32767). Which is probably just the abs() of the CD-quality sample values that range from -32768 to 32767. This means that they probably represent a 16-bit digitalization of the electrical output from 0-100% maximum voltage range of the microphone build into that mobile phone. Since even in one brand of mobile these microphones sometimes vary in their precise range not even to similar phones will necessarily return the same value given the same distance to the same sound source.

This value however correlates to sound pressure in Pascal since it's also a linear quantisation of the solund pressure, in the area where sound can be measured with the given microphone (which will not cover the entire sprectrum due to the limitations of the phone).