Skip to main content

Detect Noise Or Blow Sound - Set Sound Frequency Threshold - Android Tutorial

This tutorial explains how to detecting noise and setting a noise threshold , when this noise/sound frequency cross threshold ,example will show an alert.

 

                             

In this example broadcasting screen wake / sleep event with a service.

Now follow the coding to develop this simple application 

1.main.xml

<?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="fill_parent" 
 android:layout_height="fill_parent"     
 android:background="@color/black"     
 android:orientation="vertical" >

 <TextView 
 android:id="@+id/status" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_centerInParent="true" 
 android:text="Stopped" 
 android:textColor="@color/lime" 
 android:textSize="25sp" 
 android:textStyle="bold" />

 <RelativeLayout 
 android:layout_width="fill_parent"         
 android:layout_height="fill_parent" >

 <LinearLayout 
 android:layout_width="wrap_content"             
 android:layout_height="wrap_content" 
 android:layout_centerInParent="true" 
 android:orientation="vertical" >
 
 <TextView 
 android:id="@+id/status2" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_marginBottom="100dp" 
 android:layout_gravity="center" 
 android:text="Make a noise!" 
 android:textColor="@color/colorAccent" 
 android:textSize="25sp" 
 android:textStyle="bold" /> 
 
<com.example.arnold.noisedetection.SoundLevelView 
 android:id="@+id/volume" 
 android:layout_width="230sp"                 
 android:layout_height="60sp" />
 
 </LinearLayout>
 
 </RelativeLayout>

 </LinearLayout>
 
 
2.Do changes in your main activity (NoiseAlert.java)

public class NoiseAlert extends Activity {

    /* constants */     
private static final int POLL_INTERVAL = 300;

    /** running state **/     
private boolean mRunning = false;

    /** config state **/ 
private int mThreshold;

private PowerManager.WakeLock mWakeLock;

private Handler mHandler = new Handler();

    /* References to view elements */ 
private TextView mStatusView;
    private SoundLevelView mDisplay;

    /* sound data source */ 
private SoundMeter mSensor;

    /****************** Define runnable thread again and again detect noise *********/
private Runnable mSleepTask = new Runnable() {
        public void run() {
            //Log.i("Noise", "runnable mSleepTask");
            start();
        }
    };

    // 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();
                //Log.i("Noise", "==== onCreate ===");
            }

            // Runnable(mPollTask) will again execute after POLL_INTERVAL 
            mHandler.postDelayed(mPollTask, POLL_INTERVAL);

        }
    };


    @Override 
 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mStatusView = (TextView) findViewById(R.id.status);

        // Used to record voice        mSensor = new SoundMeter();
        mDisplay = (SoundLevelView) findViewById(R.id.volume);

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "NoiseAlert");
    }

    @Override 
 public void onResume() {
        super.onResume();
        //Log.i("Noise", "==== onResume ===");
        initializeApplicationConstants();
        mDisplay.setLevel(0, mThreshold);

        if (!mRunning) {
            mRunning = true;
            start();
        }
    }

    @Override     
public void onStop() {
        super.onStop();
        // Log.i("Noise", "==== onStop ===");
        //Stop noise monitoring         
        stop();

    }

    private void start() {
        //Log.i("Noise", "==== start ===");
        mSensor.start();
 
 if (!mWakeLock.isHeld()) {
            mWakeLock.acquire();
        }

        //Noise monitoring start 
 // Runnable(mPollTask) will execute after POLL_INTERVAL 
         mHandler.postDelayed(mPollTask, POLL_INTERVAL);
    }

    private void stop() {
        Log.i("Noise", "==== Stop Noise Monitoring===");
        if (mWakeLock.isHeld()) {
            mWakeLock.release();
        }
        mHandler.removeCallbacks(mSleepTask);
        mHandler.removeCallbacks(mPollTask);
        mSensor.stop();
        mDisplay.setLevel(0,0);
        updateDisplay("stopped...", 0.0);
        mRunning = false;
    }

    private void initializeApplicationConstants() {
        // Set Noise Threshold        mThreshold = 8;
    }

    private void updateDisplay(String status, double signalEMA) {
        mStatusView.setText(status);
        //        mDisplay.setLevel((int)signalEMA, mThreshold);
    }

    private void callForHelp() {
        //stop();
        // Show alert when noise thersold crossed 
 Toast.makeText(getApplicationContext(), "Noise Threshold Crossed, do here your stuff.",
                Toast.LENGTH_LONG).show();
    }
}

 

3. New class SoundLevelView.java

SoundLevelView class is used to draw a sound meter in view (Called in main.xml file)

 
public SoundLevelView(Context context, AttributeSet attrs) {
        super(context, attrs);

        mGreen     = context.getResources().getDrawable(
                R.drawable.greenbar);
        mRed   = context.getResources().getDrawable(
                R.drawable.redbar);

        mWidth  = mGreen.getIntrinsicWidth();
        setMinimumWidth(mWidth*10);

        mHeight = mGreen.getIntrinsicHeight();
        setMinimumHeight(mHeight);

        //Used to paint canvas background color 
        mBackgroundPaint = new Paint();
        mBackgroundPaint.setColor(Color.BLACK);

    }

    public void setLevel(int volume, int threshold) {
        if (volume == mVol && threshold == mThreshold) return;
        mVol = volume;
        mThreshold = threshold;

        // invalidate Call onDraw method and draw voice points 
 
         invalidate();
    }

    @Override    public void onDraw(Canvas canvas) {

        canvas.drawPaint(mBackgroundPaint);

        for (int i=0; i<= mVol; i++) {
            Drawable bar;
            if (i<mThreshold)
                bar = mGreen;
            else                bar = mRed;

            bar.setBounds((10-i)*mWidth, 0, (10-i+1)*mWidth, mHeight); // 
            bar.draw(canvas);
        }
    }
  }
 

4. New class SoundMeter.java

Create SoundMeter class to record noise/sound


public class SoundMeter {

    // This file is used to record voice 
 static final private double EMA_FILTER = 0.6;

    private MediaRecorder mRecorder = null;
    private double mEMA = 0.0;

    public void start() {

        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 (IllegalStateException e) {
                // TODO Auto-generated catch block 
           e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block 
           e.printStackTrace();
            }

            mRecorder.start();
            mEMA = 0.0;
        }
    }

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

    public double getAmplitude() {
        if (mRecorder != null)
            return  (mRecorder.getMaxAmplitude()/2700.0);
        else            return 0;

    }

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

}



5. AndroidManifest.xml

 Define RECORD_AUDIO and WAKE_LOCK permission.

Add two permissions 

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WAKE_LOCK" />

  

Output Screen shots...



 

___________________________________________________

 
Source code for this application NoiseDetection.zip

                                Happy Coding...

Comments

Popular posts from this blog

Zoom Image - Android Tutorial

Here we are going to see how to zoom an image in Imageview Will see it through a sample 1. Create xml with an ImageView <? xml version="1.0" encoding="utf-8" ?> < androidx.constraintlayout.widget.ConstraintLayout       xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:app="http://schemas.android.com/apk/res-auto"     xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"     android:layout_height="match_parent"     tools:context=".MainActivity" >     < LinearLayout         android:layout_width="200dp"         android:layout_height="200dp"         app:layout_constraintBottom_toBottomOf="parent"         app:layout_constraintLeft_toLeftOf="parent"         app:layout_constraintRight_toRightOf="parent"    ...

Spinner with Search on DropDown - Android Tutorial

If you have more values on Dropdown of Spinner its hard to select the last item by making a long scroll. To overcome this issue Android introduced a component called  AutoCompleteTextView Yes it is!!! Then why Spinner with Search? There may be some requirement even though gave much knowledge about it. There is a simple and good library that helps us to achieve this -  SearchableSpinner Gradle dependencies {     ...     implementation 'com.toptoche.searchablespinner:searchablespinnerlibrary:1.3.1' } Usage Now replace your Normal Android Spinner on XML with the following < com.toptoche.searchablespinnerlibrary.SearchableSpinner     android:id="@+id/id_city"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:background="@android:color/transparent"     android:padding="5dp" /> ______________________________________...

Bluetooth Chat Application - Android Tutorial

In this tutorial, we will see about how to design an Android layout for chat application using Chat Bubbles  and the main part is chat via Bluetooth . Main objective of this post is to give an idea about how to allow two-way text chat over Bluetooth in android. Bubbles: Chat bubbles are background image that expands horizontally and vertically as required based on the message posted. Bubbles are Nine-patch Images. Image Nine-patch Image In creating Android chat bubbles, nine-patch image plays a crucial role.  Nine-patch image  is a bitmap which stretches to fit the content posted in the View where it is applied as a background. A NinePatch drawable is a standard PNG image that includes an extra 1-pixel-wide border. It must be saved with the extension  .9.png , and saved into the  res/drawable/  directory of your project. The border is used to define the stretchable and static areas of the image. You indicate a stretchable section ...