web-dev-qa-db-fra.com

Android: exemple de microphone sans enregistrement pour obtenir l'amplitude/le niveau en direct?

J'essayais d'obtenir le niveau d'amplitude d'un microphone sur Android comme suit:

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 que 0 tout le temps.

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

Si oui, dois-je enregistrer pendant 500 ms, obtenir l’amplitude, arrêter l’enregistrement et recommencer?

Enfin, dois-je enregistrer dans un fichier? Je n'ai pas besoin de sauvegarder ce fichier audio. Ne puis-je pas obtenir l'amplitude actuelle ou la plus haute amplitude depuis le dernier appel de l'entrée du microphone en direct sans enregistrer?

Toute aide est appréciée, merci.

16
Tom

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

Voir http://code.google.com/p/Android-labs/source/browse/trunk/NoiseAlert/src/com/google/Android/noisealert/ pour un exemple d'application, vous pouvez choisir un Regardez SoundMeter.Java et NoiseAlert.Java

6
Toumal

La solution de Toumal fonctionne, mais je n’ai pas pu obtenir un taux de rafraîchissement suffisant pour répondre à mes besoins. J'ai donc fini par utiliser la classe SoundMeter.Java que Toumal a liée, mais l'a modifiée pour utiliser le code de cette answer

Voici le code que j'ai utilisé, qui fournit un taux de rafraîchissement bien meilleur:

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

}
14
Benjamin Kaiser

Utilise la classe AudioRecord au lieu de MediaRecorder

Consultez ce site: http://www.doepiccoding.com/blog/?p=195 , cela donne une bonne explication et un code de travail :)

2
H. Bharatvaj

Vous pouvez également utiliser la classe mediaRecoder pour afficher des données en temps réel sur l'interface utilisateur dont vous avez besoin pour utiliser le gestionnaire:

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

N'oubliez pas d'appeler le gestionnaire dans la méthode onCreate:

handler.postDelayed(pollTask, 500);

500 est le délai en millisecondes que l'interface utilisateur mettra à jour

comme vous pouvez le voir ici, vous n'avez pas besoin de sauvegarder la sortie dans un fichier si vous définissez la destination de sortie comme ci-dessous, cela ne sauvegardera nulle part:

mediaRecorder.setOutputFile("/dev/null");
0
Mohammad Moradi