Get amplitude from user's voice [closed] - android

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
How to detect amplitude from user's voice?
Just detect if user speak or not.
What is the different between AudioRecorder, MediaRecorder, Audio Capture?
Please give me a full explanation and code please
i tried this class from tutorial but it has error in "mRecorder.prepare():"
import android.media.MediaRecorder;
public class SoundMeter {
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.prepare();
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mRecorder.setOutputFile("/dev/null");
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;
}
}
update my second try
public class MainActivity extends Activity {
static final private double EMA_FILTER = 0.6;
private MediaRecorder mRecorder = null;
private double mEMA = 0.0;
TextView tv;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.start();
mEMA = 0.0;
tv = (TextView) findViewById(R.id.textView1);
double a = getAmplitude();
tv.setText(String.valueOf(a));
new Timer().schedule(new TimerTask() {
#Override
public void run() {
// TODO Auto-generated method stub
down();
}
}, 500, 10);
}
public void down() {
this.runOnUiThread(Update);
}
private Runnable Update=new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
double a = getAmplitude();
tv.setText(String.valueOf(a));
}
};
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
public double getAmplitude() {
if (mRecorder != null)
return (mRecorder.getMaxAmplitude());
else
return 0;
}
}

A couple of things:
You need to set Output Format before the prepare() statement. From the documentation for prepare(): Throws IllegalStateException if it is called after start() or before setOutputFormat()
MediaRecorder.prepare() also throws IOException. You may want to surround the prepare() with a try/catch construct.
try:
if (mRecorder == null) {
try {
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();
mEMA = 0.0;
}
catch (IOException e) {
//do something with e
}
}

Related

Decibel Meter using Media Recorder

I was referring to a code that I found previously and tried it myself. It works perfectly however the decibel measured from the code is extremely high even in a quiet room. The value ranged from 0 to 30000. I was expecting the decibel be around 30 ~ 40 when I am in a quiet room. Can someone please tell me what's wrong with the code? Maybe the algorithm in the code is wrong because "soundDB()" is not used. The decibel shown is the app is from "getAmplitudeEMA()" instead.
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;
}
}
The problem is the following line:
mStatusView.setText(Double.toString((getAmplitudeEMA())) + " dB");
You are setting as text the value returned from getAmplitudeEMA() but this is not a dB value, it's the amplitude returned by mRecorder.getMaxAmplitude() which is then modified by getAmplitudeEMA().
To "convert" amplitude to dB you need to include your soundDb(double ampl) method in this way:
public void updateTv(){
mStatusView.setText(Double.toString(soundDb(getAmplitudeEMA()))+ "dB");
}
You have to call the function soundDb, which transforms the amplitude into dB FS.
mStatusView.setText(soundDb(32767.0) + " dB");

getAmplitude isn't working

When I try to work it's show on textviev "0.0" value.
I get codes from this web site mostly
I get permissions to
<uses-permission android:name="android.permission.RECORD_AUDIO" />
ı give permission on setting-applications-mic
it's returned value "0.0"
how really works getAmplitude();
can some one explain
static final private double EMA_FILTER = 0.6;
TextView text;
Button buton;
Handler handler;
boolean state = false;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_karpuz_sec);
text = (TextView) findViewById(R.id.text);
buton = (Button) findViewById(R.id.button);
handler = new Handler();
buton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(!state){
try {
start();
} catch (IOException e) {
e.printStackTrace();
}
}
else
stop();
}
});
}
Runnable runnable = new Runnable() {
#Override
public void run() {
while (!state){
text.setText(Double.toString(getAmplitudeEMA()));;
handler.postDelayed(this,100);
}
}
};
private MediaRecorder mRecorder = null;
private double mEMA = 0.0;
public void start() throws IOException {
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");
mRecorder.prepare();
mRecorder.start();
mEMA = 0.0;
state = true;
Toast.makeText(getApplicationContext(),"Ses Ölçümü Başladı",Toast.LENGTH_SHORT).show();
buton.setText("DURDUR");
text.setText(Double.toString(getAmplitudeEMA()));
}
}
public void stop() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
state = false;
Toast.makeText(getApplicationContext(),"Ses Ölçümü Durdu",Toast.LENGTH_SHORT).show();
buton.setText("BAŞLAT");
}
}
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;
}
}
From MediaRecorder documentation, getMaxAmplitude() depicts :
Returns the maximum absolute amplitude that was sampled since the last call to this method. Call this only after the setAudioSource().
Returns : the maximum absolute amplitude measured since the last call, or 0 when called for the first time
This is why you get 0 the first time you call it in your onCreate().
Request it on a regular basis if you want as this is what suggests the presence of your Runnable, here is an example scheduling your getAmplitudeEMA() every 500ms :
private Timer mTimer = new Timer();
.....
mTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
text.setText(Double.toString(getAmplitudeEMA()));
}
});
}
}, 0, 500);
And in stop() / onPause() :
mTimer.cancel();
mTimer.purge();

android - How to know when user speaks into mic during a phone call

My goal is to be able to get a callback/hook when a user speaks into the mic during a phone call. I cant use RecognizerIntent.ACTION_RECOGNIZE_SPEECH because during a phone call this gets queued until the call ends then the prompt appears. I need something that while the user is on the phone i can determine if they speak into the mic. If there is no native way to do this, can you recommend a 3rd party ?
Right now im using android noiseAlert sample code and it looks like this:
public class SoundMeter {
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 (IOException e) {
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;
}
}
What is a good measurement i can use to know that the user is speaking into the mic using this approach ? for Example can i do the following:
SoundMeter soundMeter = new SoundMeter();
soundMeter.start();
if(soundMeter.getAmplitude>1.0)
//users is talking into the mic

MediaPlayer get max aplitude

I want to implement a VU meter in my recording app when recording AND playing. I know how to do it when recording, but the problem appears when playing. How can I grab the max amplitude at a given point in time from android MediaPlayer? I know there is a way because I saw some widget that do the same when playing some music on my device. I don't want to use android Visualizer for rendering, I want to make my own VU meter to work for devices with OS 2.3+. Basically, I need getMaxAmplitude for MediaPlayer.
//first of all import this library
import android.media.MediaRecorder;
private MediaRecorder mRecorder = null;
public double getAmplitude() {
if (mRecorder != null)
return (mRecorder.getMaxAmplitude()/2700.0);
else
return 0;
}
//if you need further detail here is my class which is doing same thing
package com.spaidevelopers.noisealert;
import java.io.IOException;
import android.media.MediaRecorder;
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;
}
}

Get microphone soundlevel in android

Im trying to get the sound level by getting live-input from the microphone.
As apps such as ,Sound meter and deciBel. I found this sample code from the link:
http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/SoundMeter.java
I'm also pasting it here.
package com.google.android.noisealert;
import android.media.MediaRecorder;
public class SoundMeter {
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");
mRecorder.prepare();
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;
}
}
Does this code do what im trying to do?
Thanks!
it will once you:
instantiate the class
call its start() method
poll its getAmplitude() function from your main class (just as they did it in that sample code). Be aware that you need to do the polling in a Runnable() so that the UI is not affected. (Call the getAmplitude function every 100ms to detect a change in the input volume)
I have used it for that too and the code does the job.

Categories

Resources