AudioRecord - how to get data to the buffer?

I'm having trouble using the AudioRecord class. I want to store the recorded data in a buffer, but I'm not sure if this is the right way to achieve this. I went through many examples, but most of them were complex and presented many different approaches. I am looking for a simple or simple explanation.

Here are my sound settings for my project:

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

I am trying to create a write function:

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

I know that I should use the .read function (short [] audioData, int offsetInShorts, int sizeInShorts). And here my problems begin. I am not sure how the audioData buffer works. I assume that the function places the recorded samples in audio data. What happens if it is completely filled with data? Does he start rewriting from an early position? If so, I believe that I need to copy all the collected samples somewhere else. Another question arises: how can I check if the buffer of the .read (...) function is full? Do I need to measure the time and contents of the copy buffer, or is there another way to achieve this? Also do I need to create a stream for the entire write operation?

Sorry to ask so many questions in one topic :)

+8
android buffer
source share
1 answer

Answer your questions ::

recorder.read (...) does not necessarily read data at all. You should probably rewrite this loop to pause for a short time (e.g. 50 ms) between calls to read. It also should not queue until the buffer has data. Also, since the buffer may not be full, you probably need to use a data structure that supports counting bytes. ByteBuffer comes to mind as a good candidate. You can insert bytes into it in a read cycle, and when it becomes sufficiently complete, put it in a queue for transmission and run another one.

you need to create a thread to loop it. as shown below.

Here's a modified version of the write loop that does the correct error checking. It uses Queue<ByteBuffer> instead of 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(); } 

Of course, somewhere you need to call recorder.startRecording() or you will not receive any data.

for a working sample, look in this example .

+3
source share

All Articles