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.
Bah, actually the problem was no fault of Android’s — it was caused by the software I was using to convert the raw PCM data to WAV format. There is evidently some error in endian conversion, since the ARM chips are big endian and WAV is little endian. When we tried opening the raw PCM files in Audacity, they looked fine.