2011-01-23 7 views
12

Stavo cercando di ottenere il livello di ampiezza di un microfono su Android in questo modo:Android: microfono di esempio senza registrazione per ottenere l'ampiezza/livello live?

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

Purtroppo, questo solo restituisce 0 per tutto il tempo.

Sembra che per questo funzioni devo effettivamente iniziare la registrazione. È corretto?

In tal caso, devo registrare per 500 ms, ottenere l'ampiezza, interrompere la registrazione e ripetere?

Infine, devo registrare su un file? Non è necessario salvare questo file audio, non è possibile ottenere l'ampiezza corrente o l'ampiezza massima dall'ultima chiamata dell'attuale ingresso microfono live senza registrazione?

Qualsiasi aiuto è apprezzato, grazie.

risposta

6

Sì, devi prima chiamare recorder.start() e non dimenticare di chiamare anche recorder.stop() alla fine!

Vedi http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/ per un'applicazione di esempio, si può decidere di dare un'occhiata a SoundMeter.java e NoiseAlert.java

+1

a quanto pare si può usare AudioRecord invece, non c'è bisogno di registrare un file – Tom

+1

È possibile reindirizzare uscita audio/multimediale su/dev/null e impedire che qualsiasi registrazione effettiva accada in questo modo. Assicurati anche di usare recorder.prepare(), altrimenti non funzionerà. – kpax

10

La soluzione da Toumal funziona, però non ero in grado di ottenere un alto abbastanza frequenza di aggiornamento per i miei bisogni. Così ho finito per usare la classe SoundMeter.java che Toumal legata ma modificato in modo da utilizzare il codice da questa answer

Ecco il codice che ho usato, che fornisce una migliore frequenza di aggiornamento:

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 può anche utilizzare la classe mediaRecoder, per visualizzare i dati in tempo reale su interfaccia utente è necessario utilizzare 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(); 
} 
} 

Questa parte mostrano i dati relativi UI:

private Runnable pollTask = new Runnable() { 
    @Override 
    public void run() { 
     double amplitude = soundMeter.getAmplitude(); 
     amplitudeTextView.setText("Amplitude: " + amplitude); 

     handler.postDelayed(pollTask, 500); 
    } 
}; 

Non dimenticare di chiamare gestore in onCreate metodo:

handler.postDelayed(pollTask, 500); 

500 è il ritardo in millisecondi, che sarà aggiornato UI

come si ca n vedete qui non è necessario per salvare l'output su file se si imposta come destinazione di uscita sotto di esso non salverà nessuna parte:

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