我有一个应用程序可以记录麦克风的音频,然后实时对音频进行一些后处理,所以我必须使用AudioRecord
类而不是标准的MediaRecorder
. 我的录制代码是这样的:
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();
上面的代码工作正常,我实际上可以从设备录制音频,我听到我的声音等等。问题是,几秒钟后,一种非常奇怪的失真模式开始出现,直到整个信号被淹没。这是我通过将一些磁带放在麦克风上并让应用程序录制一分钟左右来制作的静音录音的屏幕截图:
原始波形文件可以在这里下载。
问题绝对不是由于我的效果处理代码,因为我尝试将其注释掉并在两种情况下得到相同的结果。我在网上搜索了其他代码或可能遇到类似问题的人,但没有找到任何东西。