Android: przykładowy mikrofon bez nagrywania, aby uzyskać amplitudę/poziom NA ŻYWO?

Próbowałem uzyskać poziom amplitudy mikrofonu na Androidzie tak:

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

Niestety, cały czas zwraca tylko 0.

Wygląda na to, że aby to zadziałało, muszę zacząć nagrywać. Zgadza się?

Jeśli tak, czy muszę nagrywać na 500ms, uzyskać amplitudę,zatrzymać nagrywanie i powtórzyć?

Wreszcie, czy muszę nagrywać do pliku? Nie muszę zapisywać tego pliku audio, nie mogę po prostu uzyskać bieżącej amplitudy lub najwyższej amplitudy od ostatnie wywołanie bieżącego wejścia mikrofonu na żywo bez nagrywania?

Każda pomoc jest mile widziana, dzięki.
Author: Tom, 2011-01-24

4 answers

Tak, musisz zadzwonić recorder.najpierw start () i nie wolno zapomnieć o wywołaniu recorder.stop() na końcu też!

Zobacz http://code.google.com/p/android-labs/source/browse/trunk/NoiseAlert/src/com/google/android/noisealert/ dla przykładowej aplikacji, możesz spojrzeć na SoundMeter.java i NoiseAlert.java

 6
Author: Toumal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-05 15:30:20

Rozwiązanie z Toumal działa, jednak nie byłem w stanie uzyskać wystarczająco wysokiej częstotliwości odświeżania dla moich potrzeb. Więc skończyło się na użyciu Soundmetru .Klasa java , która połączyła się, ale zmodyfikowała, aby użyć kodu z tej odpowiedzi

Oto kod, którego użyłem, który zapewnia znacznie lepszą częstotliwość odświeżania:

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

}
 13
Author: Benjamin Kaiser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:15

Użyj klasy AudioRecord zamiast MediaRecorder

Sprawdź tę stronę: http://www.doepiccoding.com/blog/?p=195 , daje ładne wyjaśnienie i działający kod:)

 2
Author: H. Bharatvaj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-31 10:46:40

Możesz również użyć klasy mediaRecoder, aby wyświetlać dane w czasie rzeczywistym w interfejsie użytkownika, musisz użyć Handlera:

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

Ta część pokazuje dane dotyczące interfejsu użytkownika:

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

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

Nie zapomnij wywołać obsługi w metodzie onCreate:

handler.postDelayed(pollTask, 500);

500 to opóźnienie w milisekundach, które zostanie zaktualizowane

Jak widać tutaj, nie musisz zapisywać wyjścia do pliku, jeśli ustawisz miejsce docelowe wyjścia, jak poniżej, nie będzie zapisywać nigdzie:

mediaRecorder.setOutputFile("/dev/null");
 0
Author: Mohammad Moradi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-10 05:49:35