Android: AudioRecord Class Problem: Callback wird nie aufgerufen

Meine Android Java-Anwendung muss Audiodaten im RAM aufzeichnen und verarbeiten. Deshalb benutze ich die Klasse "AudioRecord" und nicht den "MediaRecorder" (nur in Datei aufnehmen).

Bisher habe ich eine Busy-Loop-Abfrage mit "read ()" für die Audiodaten verwendet. Dies hat bisher funktioniert, aber es hängt die CPU zu sehr an. Zwischen zwei Umfragen habe ich den Thread in den Ruhezustand versetzt, um eine 100% ige CPU-Auslastung zu vermeiden. Dies ist jedoch keine wirklich saubere Lösung, da die Zeit des Schlafens nicht garantiert ist und Sie eine Sicherheitszeit subtrahieren müssen, um keine Audio-Schnipsel zu verlieren. Dies ist keine optimale CPU. Ich benötige so viele freie CPU-Zyklen wie möglich für einen parallel laufenden Thread.

Jetzt habe ich die Aufnahme mit dem "OnRecordPositionUpdateListener" implementiert. Dies sieht sehr vielversprechend aus und ist laut SDK Docs die richtige Vorgehensweise. Alles scheint zu funktionieren (Öffnen des Audiogeräts, Lesen () der Daten usw.), aber der Listner wird nie aufgerufen.

Weiß jemand warum?

Info: Ich arbeite mit einem echten Gerät, nicht unter dem Emulator. Die Aufnahme mit einem Busy Loop funktioniert grundsätzlich (jedoch nicht zufriedenstellend). Nur der Callback Listener wird nie angerufen.

Hier ist ein Ausschnitt aus meinem Sourcecode:

public class myApplication extends Activity {

  /* audio recording */
  private static final int AUDIO_SAMPLE_FREQ = 16000;
  private static final int AUDIO_BUFFER_BYTESIZE = AUDIO_SAMPLE_FREQ * 2 * 3; // = 3000ms
  private static final int AUDIO_BUFFER_SAMPLEREAD_SIZE = AUDIO_SAMPLE_FREQ  / 10 * 2; // = 200ms

  private short[] mAudioBuffer = null; // audio buffer
  private int mSamplesRead; // how many samples are recently read
  private AudioRecord mAudioRecorder; // Audio Recorder

  ...

  private OnRecordPositionUpdateListener mRecordListener = new OnRecordPositionUpdateListener() {

    public void onPeriodicNotification(AudioRecord recorder) {
      mSamplesRead = recorder.read(mAudioBuffer, 0, AUDIO_BUFFER_SAMPLEREAD_SIZE);
      if (mSamplesRead > 0) {

        // do something here...

      }
    }

    public void onMarkerReached(AudioRecord recorder) {
      Error("What? Hu!? Where am I?");
    }
  };

  ...

  public void onCreate(Bundle savedInstanceState) {

  try {
      mAudioRecorder = new AudioRecord(
          android.media.MediaRecorder.AudioSource.MIC, 
          AUDIO_SAMPLE_FREQ,
          AudioFormat.CHANNEL_CONFIGURATION_MONO,
          AudioFormat.ENCODING_PCM_16BIT,  
          AUDIO_BUFFER_BYTESIZE);
    } catch (Exception e) {
      Error("Unable to init audio recording!");
    }

    mAudioBuffer = new short[AUDIO_BUFFER_SAMPLEREAD_SIZE];
    mAudioRecorder.setPositionNotificationPeriod(AUDIO_BUFFER_SAMPLEREAD_SIZE);
    mAudioRecorder.setRecordPositionUpdateListener(mRecordListener);
    mAudioRecorder.startRecording();

    /* test if I can read anything at all... (and yes, this here works!) */
    mSamplesRead = mAudioRecorder.read(mAudioBuffer, 0, AUDIO_BUFFER_SAMPLEREAD_SIZE);

  }
}

Antworten auf die Frage(4)

Ihre Antwort auf die Frage