java - Android: ¿micrófono de muestra sin grabar para obtener amplitud/nivel en vivo?
media record (4)
La solución de Toumal funciona, sin embargo, no pude obtener una frecuencia de actualización lo suficientemente alta para mis necesidades. Así que terminé usando la clase SoundMeter.java que Toumal vinculó, pero la modifiqué para usar el código de esta answer
Aquí está el código que usé, que proporciona una tasa de actualización mucho mejor:
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;
}
}
Estaba tratando de obtener el nivel de amplitud de un micrófono en Android así:
MediaRecorder recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new RecorderTask(recorder), 0, 1000);
private class RecorderTask extends TimerTask {
private MediaRecorder recorder;
public RecorderTask(MediaRecorder recorder) {
this.recorder = recorder;
}
public void run() {
Log.v("MicInfoService", "amplitude: " + recorder.getMaxAmplitude());
}
}
Desafortunadamente, esto solo devuelve 0 todo el tiempo.
Parece que para que esto funcione tengo que empezar a grabar. ¿Es eso correcto?
Si es así, ¿necesito grabar durante 500 ms, obtener amplitud, detener la grabación y repetir?
Por último, ¿tengo que grabar en un archivo? No necesito guardar este archivo de audio, ¿no puedo obtener la amplitud actual o la amplitud más alta desde la última llamada de la entrada actual del micrófono en vivo sin grabar?
Cualquier ayuda es apreciada, gracias.
Sí, primero tiene que llamar a recorder.start (), ¡y no debe olvidar llamar a recorder.stop () al final también!
Consulte http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/ para ver una aplicación de ejemplo, es posible que desee echar un vistazo a SoundMeter. java y NoiseAlert.java
También puede usar la clase mediaRecoder, para mostrar datos en tiempo real en la IU que necesita para usar 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();
}
}
Esta parte muestra datos en la interfaz de usuario:
private Runnable pollTask = new Runnable() {
@Override
public void run() {
double amplitude = soundMeter.getAmplitude();
amplitudeTextView.setText("Amplitude: " + amplitude);
handler.postDelayed(pollTask, 500);
}
};
No olvides llamar al manejador en el método onCreate:
handler.postDelayed(pollTask, 500);
500 es el retraso en milisegundos que la interfaz de usuario se actualizará
Como puede ver aquí, no necesita guardar la salida en el archivo si configura el destino de salida como se muestra a continuación, no se guardará en ninguna parte:
mediaRecorder.setOutputFile("/dev/null");
Use AudioRecord Class en lugar de MediaRecorder
Echa un vistazo a este sitio: http://www.doepiccoding.com/blog/?p=195 , te da una buena explicación y un código de trabajo :)