2011-01-23 5 views
12

starałem się uzyskać poziom amplitudy mikrofonem na Androida tak:Android: przykładowy mikrofon bez nagrywania, aby uzyskać amplitudę/poziom na żywo?

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, ta funkcja zwraca 0 cały czas.

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

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

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

Każda pomoc jest doceniana, dzięki.

Odpowiedz

6

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

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

+1

pozornie można użyć zamiast AudioRecord, nie ma potrzeby, aby nagrać plik – Tom

+1

można przekierować wyjście audio/media do/dev/null i uniemożliwić w ten sposób faktyczne nagrywanie. Upewnij się również, że używasz recorder.prepare(), to nie zadziała inaczej. – kpax

10

Rozwiązanie z Toumal działa, jednak nie był w stanie uzyskać wystarczająco wysoka częstotliwość odświeżania moje potrzeby. Więc skończyło się przy użyciu klasy SoundMeter.java że Toumal połączoną ale zmodyfikowano go użyć kodu z tego answer

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

} 
0

Yo u można również użyć klasy mediaRecoder, do wyświetlania danych w czasie rzeczywistym na interfejsie trzeba użyć 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(); 
} 
} 

Ta część pokazują dane dotyczące Ui:

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

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

Nie zapomnij zadzwonić obsługi w onCreate metoda:

handler.postDelayed(pollTask, 500); 

500 jest opóźnienie w milisekundach, który będzie aktualizowany UI

jak ca n zobacz tutaj nie trzeba się zapisywać dane wyjściowe do pliku, jeśli ustawisz docelowego wyjścia jak poniżej nie uratuje wszędzie:

mediaRecorder.setOutputFile("/dev/null"); 
Powiązane problemy