Reputation:
I am processing audio recorded by AudioRecord in a thread, but if I run the processing in the recorder thread, some frames get dropped. According to android, AudioRecord.read() --> bufferoverflow, how to handle the buffer?, I need to run the processing in a separate thread, but how? Do I need to create a new thread for every single frame (2-3 per second)?
Here is my current solution but I am wondering if there is a better way to do this?
//in the AudioRecord thread
while (!break_condition) {
int num_read = recorder.read(buffer, 0, buffer.length);
HeavyProcessingRunnable myRunnable = new HeavyProcessingRunnable(buffer);
Thread t = new Thread(myRunnable)
t.start();
}
The runnable for the heavy processing
public class HeavyProcessingRunnable implements Runnable {
private byte[] var;
public HeavyProcessingRunnable(byte[] var) {
this.var = var;
}
public void run() {
//if this is executed in audio recorder thread, frames get dropped
someHeavyProcessing(var);
}
}
Upvotes: 2
Views: 1113
Reputation: 3852
Creating a new thread everytime is somewhat expensive (discussion). It would be better to create the heavy processing thread only once and feed it with audio samples. Here's an example:
// Do it only once.
HandlerThread myHandlerThread = new HandlerThread("my-handler-thread");
myHandlerThread.start();
Handler myHandler = new Handler(myHandlerThread.getLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
someHeavyProcessing((byte[]) msg.obj, msg.arg1);
return true;
}
});
// In audio recorder thread.
// Mind the handler reference.
while (!break_condition) {
int num_read = recorder.read(buffer, 0, buffer.length);
Message message = myHandler.obtainMessage();
message.obj = buffer;
message.arg1 = num_read;
message.sendToTarget();
}
By the way, it's important to provide num_read
along with the audio samples.
Upvotes: 1