Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get the Microphone sound level ( Decibel level) in Android

Tags:

java

android

Im quite new to android and i have searched about this for quite a while. I would like to build an application that is something like a decibel meter. In realtime it shows the sound level. It there is much noise in the room, there will be something indicating that, if its quiet something will indicate that!.

I don't have any idea at all how to do this. Could anyone explain what the basics of the microphone-sound-level application? If its possible, maybe provide some code?

Thanks!

like image 559
Seb Avatar asked Aug 25 '11 22:08

Seb


2 Answers

You can use MediaRecorder.getMaxAmplitude().

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {

    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO},
            RECORD_AUDIO);
}
  1. Get the noise level using the 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");
    try {
        mRecorder.prepare();
    } catch (IllegalStateException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }
    mRecorder.start();
    
  2. Start the MediaRecorder,

    private Runnable mSleepTask = new Runnable() {
        public void run() {
            //Log.i("Noise", "runnable mSleepTask");
            mSensor.start();
            if (!mWakeLock.isHeld()) {
                 mWakeLock.acquire();
            }
            //Noise monitoring start
            // Runnable(mPollTask) will execute after POLL_INTERVAL
            mHandler.postDelayed(mPollTask, POLL_INTERVAL);
        }
    };
    
  3. Create Runnable Thread to check the noise level frequently,

    private Runnable mPollTask = new Runnable() {
        public void run() {
            double amp = mSensor.getAmplitude();
            //Log.i("Noise", "runnable mPollTask");
            // Runnable(mPollTask) will again execute after POLL_INTERVAL
            mHandler.postDelayed(mPollTask, POLL_INTERVAL);
        }
    };
    

Convert the Amplitude to decibel using the following formula,

return 20 * Math.log10(mRecorder.getMaxAmplitude() / 2700.0);
  1. Monitoring the Voice and Alert for the Louder Noise.

    // Create runnable thread to Monitor Voice
    private Runnable mPollTask = new Runnable() {
        public void run() {
            double amp = mSensor.getAmplitude();
            //Log.i("Noise", "runnable mPollTask");
            updateDisplay("Monitoring Voice...", amp);
    
            if ((amp > mThreshold)) {
                callForHelp(amp);
                //Log.i("Noise", "==== onCreate ===");
            }
            // Runnable(mPollTask) will again execute after POLL_INTERVAL
            mHandler.postDelayed(mPollTask, POLL_INTERVAL);
        }
    };
    
like image 191
Tung Duong Avatar answered Sep 19 '22 06:09

Tung Duong


This question has been addressed generally for Java, and the required classes are available in Android.

The basic idea is to sample the data line for the microphone, and calculate the level from the returned buffer.

How to calculate the level/amplitude/db of audio signal in java?

You can also have a look at the Visualizer class which does FFT frequency analysis, however the permissions for microphone may not be consistent across various devices. You may also have to connect it to the Equalizer class to access the mic.

https://developer.android.com/reference/android/media/audiofx/Visualizer.html

like image 44
Dominic Cerisano Avatar answered Sep 17 '22 06:09

Dominic Cerisano