I've got an application which records audio from the microphone and then performs some post-processing on the audio in realtime, so I must use the AudioRecord
class instead of the standard MediaRecorder
. My code for recording is as such:
DataOutputStream dataOutputStreamInstance = new DataOutputStream(bufferedStreamInstance);
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
int bufferSize = AudioRecord.getMinBufferSize((int)sampleRate, channelConfiguration, DEFAULT_AUDIO_ENCODING) * 2;
short[] microphoneBuffer = new short[bufferSize];
float[] processingBuffer = new float[bufferSize];
short[] outputBuffer = new short[bufferSize];
AudioRecord microphoneRecorder = new AudioRecord(MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_CONFIGURATION_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize);
microphoneRecorder.startRecording();
while(isRecording) {
synchronized(mutex) { ... check for pause condition, wait, etc. ... }
int numSamplesRead = microphoneRecorder.read(microphoneBuffer, 0, bufferSize);
// Convert 16-bit short data to floating point
getFloatingPointBufferFromPcmData(microphoneBuffer, processingBuffer, bufferSize);
doProcessingStuff(processingBuffer, bufferSize);
if(numSamplesRead == AudioRecord.ERROR_INVALID_OPERATION) {
throw new IllegalStateException("read() returned AudioRecord.ERROR_INVALID_OPERATION");
}
else if(numSamplesRead == AudioRecord.ERROR_BAD_VALUE) {
throw new IllegalStateException("read() returned AudioRecord.ERROR_BAD_VALUE");
}
try {
// Dump the output to the target file in 16-bit short format
getShortPcmBufferFromFloatingPointData(processingBuffer, outputBuffer, bufferSize);
for(int bufferIndex = 0; bufferIndex < numSamplesRead; bufferIndex++) {
dataOutputStreamInstance.writeShort(outputBuffer[bufferIndex]);
}
}
catch(Exception e) {
Log.e("MyApp", "Error while writing audio data to file: " + e.getMessage());
e.getStackTrace();
}
}
microphoneRecorder.stop();
The above code works fine, and I can actually record audio from the device, and I hear my voice and such. The problem is that after some seconds, a very strange pattern of distortion starts to emerge until the entire signal is drowned out. Here's a screenshot of a recording of silence which I made by putting some tape over the mic and let the app record for a minute or so:
The original wave file can be downloaded here.
The problem is definitely not due to my effect processing code, as I have tried commenting it out and get the same results in both cases. I have scoured the web for other code or people who might be experiencing similar problems, but haven't found anything.