2011-01-23 20 views
12

yo estaba tratando de obtener el nivel de amplitud de un micrófono en Android de este modo:Android: micrófono de muestra sin grabación para obtener amplitud/nivel en vivo?

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()); 
    } 
} 

Por desgracia, esto sólo devuelve 0 todo el tiempo.

Parece que para que esto funcione tengo que empezar a grabar. ¿Es eso correcto?

Si es así, ¿debo grabar durante 500ms, obtener amplitud, detener la grabación y repetir?

Finalmente, ¿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?

Se agradece cualquier ayuda, gracias.

Respuesta

6

¡Sí, primero tiene que llamar a recorder.start() y no debe olvidar llamar también a recorder.stop() al final!

Ver http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/ para una aplicación de ejemplo, es posible que desee echar un vistazo a SoundMeter.java y NoiseAlert.java

+1

parecer, uno puede usar AudioRecord lugar, no hay necesidad de grabar un archivo – Tom

+1

Puede redirigir la salida de audio/medios a/dev/null y evita que ocurra una grabación real de esa manera. También asegúrese de usar grabador.prepare(), de lo contrario no funcionará. – kpax

10

La solución de Toumal funciona, sin embargo, no fue capaz de conseguir un alto suficiente frecuencia de actualización mis necesidades. Así que acabé utilizando la clase SoundMeter.java que Toumal vinculado pero modificado para utilizar el código de este answer

Aquí está el código que utilicé, que proporciona una mejor frecuencia de actualización:

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; 
    } 

} 
0

Yo u también puede utilizar la clase mediaRecoder, para mostrar datos en tiempo real en la interfaz de usuario necesita utilizar 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 muestran los 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 se olvide de llamar manejador en onCreate método:

handler.postDelayed(pollTask, 500); 

500 es el retraso en milisegundos, que la interfaz de usuario será actualizada

a medida que ca n ve aquí que no es necesario guardar el resultado a presentar si se establece como destino de salida por debajo de ella no va a guardar en cualquier lugar:

mediaRecorder.setOutputFile("/dev/null"); 
Cuestiones relacionadas