2011-01-23 3 views
12

je tentais d'obtenir le niveau d'amplitude d'un microphone sur Android comme ceci:Android: échantillonner un microphone sans enregistrer pour obtenir une amplitude/un niveau en direct?

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

Malheureusement, cela ne renvoie 0 tout le temps.

Il semble que pour que cela fonctionne, je dois commencer à enregistrer. Est-ce exact?

Si oui, ai-je besoin d'enregistrer pendant 500ms, obtenir de l'amplitude, arrêter l'enregistrement et répéter?

Enfin, dois-je enregistrer dans un fichier? Je n'ai pas besoin de sauvegarder ce fichier audio, est-ce que je ne peux pas obtenir l'amplitude actuelle ou l'amplitude la plus élevée depuis le dernier appel de l'entrée actuelle du micro en direct sans enregistrement?

Toute aide est appréciée, merci.

Répondre

6

Yep vous devez d'abord appeler recorder.start(), et vous ne devez pas oublier d'appeler recorder.stop() à la fin aussi!

Voir http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/ pour une application par exemple, vous pouvez jeter un oeil à SoundMeter.java et NoiseAlert.java

+1

apparemment on peut utiliser audiorecord à la place, pas besoin d'enregistrer un fichier – Tom

+1

Vous pouvez rediriger sortie audio/média vers/dev/null et empêche tout enregistrement réel de se produire de cette façon. Assurez-vous également d'utiliser recorder.prepare(), cela ne fonctionnera pas autrement. – kpax

10

La solution de travaux Toumal, mais je ne suis pas en mesure d'obtenir un taux élevé de rafraîchissement suffisant pour mes besoins. Donc, je me suis retrouvé à l'aide de la classe SoundMeter.java qui Toumal lié, mais modifié pour utiliser le code de cette answer

Voici le code que j'utilisé, ce qui donne un meilleur taux de rafraîchissement:

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 peut également utiliser la classe mediaRecoder, pour afficher les données en temps réel sur l'interface utilisateur, vous devez utiliser 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(); 
} 
} 

Cette partie affiche les données sur l'interface utilisateur:

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

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

Ne pas oublier d'appeler gestionnaire dans onCreate méthode:

handler.postDelayed(pollTask, 500); 

500 est retard en millisecondes qui sera mis à jour l'interface utilisateur

que vous ca n voyez ici vous n'avez pas besoin d'enregistrer la sortie de fichier si vous définissez la destination de sortie en dessous ne sauvera pas partout:

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