2012-11-21 8 views
8

Sto riscontrando alcuni problemi con la classe AudioRecord. Voglio memorizzare i dati registrati in un buffer, ma non sono sicuro di quale sia il modo corretto per farlo. Ho passato un gran numero di esempi, ma la maggior parte di loro sono stati resi comici e rappresentano molti approcci diversi. Sto cercando una spiegazione semplice o semplice.AudioRecord - come ottenere i dati nel buffer?

Qui sono le mie impostazioni audio per il mio progetto:

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

Sto cercando di creare una funzione di registrazione:

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

So che ho 'm dovrei usare .read (brevi [] audioData, int offsetInShorts, int sizeInShorts). E qui iniziano i miei problemi. Non sono sicuro di come funzioni il buffer audioData - presumo che la funzione inserisca campioni registrati nei dati audio. Cosa succede se è completamente riempito con i dati? Inizia la riscrittura dalla prima posizione? Se lo fa, credo di dover copiare tutti i campioni raccolti altrove. Solleva un'altra domanda: come posso verificare se il buffer di funzione .read (...) è già pieno? Devo misurare il tempo e copiare il contenuto del buffer o c'è un altro modo per raggiungerlo? Devo anche creare un thread per l'intera operazione di registrazione?

Ci scusiamo per chiedere tante domande in un argomento :)

risposta

3

risposta alle vostre domande ::

recorder.read (...) non necessariamente leggere tutti i dati a tutti. Probabilmente dovresti riscrivere quel loop in pausa per un breve periodo (ad es. 50 ms) tra le chiamate da leggere. Inoltre, non dovrebbe accodare il buffer finché il buffer non ha dati. Inoltre, poiché il buffer potrebbe non essere pieno, probabilmente è necessario utilizzare una struttura dati che mantenga un conteggio del numero di byte. Un ByteBuffer mi viene in mente come un buon candidato. Puoi inserire dei byte nel ciclo di lettura e quando diventa abbastanza pieno, accodalo per la trasmissione e ne avvia un altro.

offcourse è necessario creare un thread per il suo ciclo. come mostrato nel codice sottostante.

Ecco una versione modificata del ciclo di registrazione che esegue il corretto controllo degli errori. Esso utilizza una Queue<ByteBuffer> invece di un 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(); 
} 

Naturalmente, da qualche parte è necessario chiamare recorder.startRecording() o non sarà possibile ottenere alcun dato.

per esempio campione di lavoro at this example.

+0

cosa è ** qArray ** qui? – OnePunchMan

+0

potrebbe l'arraylist. Non ricordavo ora. Meglio riferire questo esempio http://stackoverflow.com/questions/8499042/android-audiorecord-example/13487250#13487250 –

Problemi correlati