How to sample microphone on Android without recording to get live amplitude/level?
The solution from Toumal works, however I wasn't able to get a high enough refresh rate for my needs. So I ended up using the SoundMeter.java class that Toumal linked but modified it to use the code from this answer
Here is the code I used, which provides a much better refresh rate:
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
public class SoundMeter {
private AudioRecord ar = null;
private int minSize;
public void start() {
minSize= AudioRecord.getMinBufferSize(8000, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT);
ar = new AudioRecord(MediaRecorder.AudioSource.MIC, 8000,AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT,minSize);
ar.startRecording();
}
public void stop() {
if (ar != null) {
ar.stop();
}
}
public double getAmplitude() {
short[] buffer = new short[minSize];
ar.read(buffer, 0, minSize);
int max = 0;
for (short s : buffer)
{
if (Math.abs(s) > max)
{
max = Math.abs(s);
}
}
return max;
}
}
Yep you have to call recorder.start() first, and you must not forget to call recorder.stop() at the end too!
See http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/ for an example application, you may want to take a look at SoundMeter.java and NoiseAlert.java
Use AudioRecord Class Instead of MediaRecorder
Check out this site: http://www.doepiccoding.com/blog/?p=195 , it gives a nice explanation and a working code :)
You can also use mediaRecoder class, to display real time data on UI you need to use Handler:
public class SoundMeter {
private MediaRecorder mediaRecorder;
public void start(){
if(started){
return;
}
if (mediaRecorder == null){
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(
MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(
MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setAudioEncoder(
MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setOutputFile("/dev/null");
try{
mediaRecorder.prepare();
}catch (IllegalStateException e){
e.printStackTrace();
}catch (IOException e){
e.printStackTrace();
}
mediaRecorder.start();
started = true;
}
}
}
public double getAmplitude(){
return mediaRecorder.getMaxAmplitude();
}
}
This part show data on UI:
private Runnable pollTask = new Runnable() {
@Override
public void run() {
double amplitude = soundMeter.getAmplitude();
amplitudeTextView.setText("Amplitude: " + amplitude);
handler.postDelayed(pollTask, 500);
}
};
Don't forget to call handler in onCreate method:
handler.postDelayed(pollTask, 500);
500 is delay in milliseconds which UI will updated
as you can see here you don't need to save output to file if you set output destination as below it won't save anywhere:
mediaRecorder.setOutputFile("/dev/null");