2012-11-21 5 views
8

Ich habe einige Probleme mit AudioRecord Klasse. Ich möchte aufgezeichnete Daten in einem Puffer speichern, aber ich bin mir nicht sicher, was der richtige Weg ist, um das zu erreichen. Ich habe eine große Anzahl von Beispielen durchgespielt, aber die meisten waren kompliziert und repräsentierten viele verschiedene Ansätze. Ich suche nach einer einfachen oder einfachen Erklärung.AudioRecord - Wie bekomme ich Daten in den Puffer?

Hier sind meine Audioeinstellungen für mein Projekt:

int audioSource = AudioSource.MIC; 
int sampleRateInHz = 8000; 
int channelConfig = AudioFormat.CHANNEL_IN_MONO; 
int audioFormat = AudioFormat.ENCODING_PCM_16BIT; 
int bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat); 

short[] buffer = new short[bufferSizeInBytes]; 

AudioRecord audioRecorder = new AudioRecord(audioSource, 
              sampleRateInHz, 
              channelConfig, 
              audioFormat, 
              bufferSizeInBytes); 

Ich bin versucht, eine Aufnahmefunktion zu erstellen:

public void Recording() { 
    audioRecorder.startRecording(); 
    ... 
    audioRecorder.stop(); 
    audioRecorder.release(); 
} 

Ich weiß, dass Ich soll (kurz verwenden .mehr [] Funktion audioData, int offsetInShorts, int sizeInShorts). Und hier fangen meine Probleme an. Ich bin mir nicht sicher, wie AudioData Buffer funktioniert - ich nehme an, Funktion legt aufgezeichnete Samples in die AudioData. Was passiert, wenn es vollständig mit Daten gefüllt ist? Es fängt an, von der frühesten Position neu zu schreiben? Wenn es das tut, glaube ich, dass ich alle gesammelten Samples irgendwo anders kopieren muss. Es wirft eine andere Frage auf - wie kann ich überprüfen, ob .read (...) Funktionspuffer bereits voll ist? Muss ich die Zeit messen und Pufferinhalte kopieren, oder gibt es eine andere Möglichkeit, das zu erreichen? Muss ich auch einen Thread für den gesamten Aufzeichnungsvorgang erstellen?

Sorry für so viele Fragen in einem Thema zu fragen :)

Antwort

3

Antwort auf Ihre Fragen ::

recorder.read (...) Lesen Sie nicht unbedingt alle Daten überhaupt. Sie sollten diese Schleife wahrscheinlich neu schreiben, um für kurze Zeit (z. B. 50 ms) zwischen zu lesenden Aufrufen zu pausieren. Es sollte den Puffer auch nicht in die Warteschlange stellen, bis der Puffer Daten enthält. Da der Puffer möglicherweise nicht voll ist, müssen Sie wahrscheinlich eine Datenstruktur verwenden, die die Anzahl der Bytes verwaltet. Ein ByteBuffer kommt mir als guter Kandidat in den Sinn. Sie können Bytes in die Read-Schleife stecken und wenn es voll genug ist, in die Warteschlange für die Übertragung und starten Sie eine andere.

natürlich müssen Sie einen Thread für das Schleifen erstellen. wie im folgenden Code gezeigt.

Hier ist eine modifizierte Version der Aufnahmeschleife, die eine ordnungsgemäße Fehlerprüfung durchführt. Es verwendet ein Queue<ByteBuffer> anstelle eines Queue<byte[]>:

private void startRecording() { 

    recorder.startRecording(); 
    isRecording = true; 
    recordingThread = new Thread(new Runnable() { 

     @Override 
     public void run() { 
      bData = ByteBuffer.allocate(BufferElements); 
      bbarray = new byte[bData.remaining()]; 
      bData.get(bbarray); 
      while (isRecording) { 

       int result = recorder.read(bbarray, 0, BufferElements); 
       System.out.println("READ DATA"); 
       if (result > 0) { 
        qArray.add(bData); 

        --your stuffs-- 
        bData = ByteBuffer.allocate(BufferElements); 
       } else if (result == AudioRecord.ERROR_INVALID_OPERATION) { 
        Log.e("Recording", "Invalid operation error"); 
        break; 
       } else if (result == AudioRecord.ERROR_BAD_VALUE) { 
        Log.e("Recording", "Bad value error"); 
        break; 
       } else if (result == AudioRecord.ERROR) { 
        Log.e("Recording", "Unknown error"); 
        break; 
       } 
       try { 
        Thread.sleep(10); 
       } catch (InterruptedException e) { 
        break; 
       } 
      } 
     } 
    }, "AudioRecorder Thread"); 
    recordingThread.start(); 
} 

Natürlich irgendwo müssen Sie recorder.startRecording() anrufen, oder Sie werden keine Daten erhalten.

zum Arbeiten Beispiel Aussehen at this example.

+0

Was ist ** qArray ** hier? – OnePunchMan

+0

könnte die Arraylist. Ich konnte mich nicht erinnern. Besser, dieses Beispiel zu verweisen http://stackoverflow.com/questions/8499042/android-audioorecord-example/13487250#13487250 –