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" />
Comments
Post a Comment