FaISalBLiNK
FaISalBLiNK

Reputation: 711

Decibel Sound Meter for Android

I am new to Android and looking to write an app for measuring decibel sound level. The idea is that when a sound reaches a certain level the user gets a alert. That's it. Can anyone help me out with this. Can I do this using HTML5/Javascript ? any help will be appreciated.

Upvotes: 8

Views: 24141

Answers (3)

Patrick
Patrick

Reputation: 1121

this code works for me:

import android.app.Activity;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.widget.TextView;

public class Noise extends Activity {

    TextView mStatusView;
    MediaRecorder mRecorder;
    Thread runner;
    private static double mEMA = 0.0;
    static final private double EMA_FILTER = 0.6;

    final Runnable updater = new Runnable(){

        public void run(){          
            updateTv();
        };
    };
    final Handler mHandler = new Handler();

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.noiselevel);
        mStatusView = (TextView) findViewById(R.id.status);


        if (runner == null)
        { 
            runner = new Thread(){
                public void run()
                {
                    while (runner != null)
                    {
                        try
                        {
                            Thread.sleep(1000);
                            Log.i("Noise", "Tock");
                        } catch (InterruptedException e) { };
                        mHandler.post(updater);
                    }
                }
            };
            runner.start();
            Log.d("Noise", "start runner()");
        }
    }

    public void onResume()
    {
        super.onResume();
        startRecorder();
    }

    public void onPause()
    {
        super.onPause();
        stopRecorder();
    }

    public void startRecorder(){
        if (mRecorder == null)
        {
            mRecorder = new MediaRecorder();
            mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
            mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
            mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
            mRecorder.setOutputFile("/dev/null"); 
            try
            {           
                mRecorder.prepare();
            }catch (java.io.IOException ioe) {
                android.util.Log.e("[Monkey]", "IOException: " + android.util.Log.getStackTraceString(ioe));

            }catch (java.lang.SecurityException e) {
                android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
            }
            try
            {           
                mRecorder.start();
            }catch (java.lang.SecurityException e) {
                android.util.Log.e("[Monkey]", "SecurityException: " + android.util.Log.getStackTraceString(e));
            }

            //mEMA = 0.0;
        }

    }
    public void stopRecorder() {
        if (mRecorder != null) {
            mRecorder.stop();       
            mRecorder.release();
            mRecorder = null;
        }
    }

    public void updateTv(){
        mStatusView.setText(Double.toString((getAmplitudeEMA())) + " dB");
    }
    public double soundDb(double ampl){
        return  20 * Math.log10(getAmplitudeEMA() / ampl);
    }
    public double getAmplitude() {
        if (mRecorder != null)
            return  (mRecorder.getMaxAmplitude());
        else
            return 0;

    }
    public double getAmplitudeEMA() {
        double amp =  getAmplitude();
        mEMA = EMA_FILTER * amp + (1.0 - EMA_FILTER) * mEMA;
        return mEMA;
    }

}

Upvotes: 7

the_mandrill
the_mandrill

Reputation: 30862

I think you need to clarify what you mean by 'deciBel'. There are several different types of dB that mean quite different things. The example that Soham gives you calculates a peak dB relative to a reference amplitude, which the originating article suggests using the maximum digital value of 1.0. This means that the value you will get out will range between about -96dB and 0dB for a 16-bit audio capture.

I suspect though that what you want to do is measure a sound pressure level (the range where speech is about 50dB, jet overhead 120dB). This is actually called 'db (SPL)'. You won't be able to do this on your device unless you have some means of calibrating your device against particular power levels.

There are further considerations you need to make. One is whether you need peak or RMS power levels (peak for instantaneous events, RMS for continuous sound such as music). Also you need to know how to turn off any automatic gain control on the device, as that will make any measurements meaningless.

Upvotes: 6

Soham
Soham

Reputation: 4970

Taken from Android Media Player Decibel Reading

For native android/java based decibel calculation for a MediaRecorder:

mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/dev/null"); 
mRecorder.prepare();
mRecorder.start();
   public double getAmplitude() {
            if (mRecorder != null)
                    return  (mRecorder.getMaxAmplitude());
            else
                    return 0;

    }

To calculate Db value :

  powerDb = 20 * log10(getAmplitude() / referenceAmp);

Reference: http://en.wikipedia.org/wiki/Decibel#Field_quantities

Not sure if you could do this in HTML5 on android

Upvotes: 13

Related Questions