我的应用是从手机麦克风录制音频并对其进行实时处理。它在物理设备上工作正常,但在模拟器中表现得很“有趣”。它记录了一些东西,但我不太确定它的录音是什么。
在仿真器上看来,音频样本的读取速度是实际设备的两倍。在应用程序中我有一个可视进度小部件(一个水平移动的记录头),它移动在模拟器中大约快两倍。
以下是录制循环:
int FREQUENCY = 44100;
int BLOCKSIZE = 110;
int bufferSize = AudioRecord.getMinBufferSize(FREQUENCY,
AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT) * 10;
AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.CAMCORDER,
FREQUENCY, AudioFormat.CHANNEL_IN_STEREO, AudioFormat.ENCODING_PCM_16BIT,
bufferSize);
short[] signal = new short[BLOCKSIZE * 2]; // Times two for stereo
audioRecord.startRecording();
while (!isCancelled()) {
int bufferReadResult = audioRecord.read(signal, 0, BLOCKSIZE * 2);
if (bufferReadResult != BLOCKSIZE * 2)
throw new RuntimeException("Recorded less than BLOCKSIZE x 2 samples:"
+ bufferReadResult);
// process the `signal` array here
}
audioRecord.stop();
audioRecord.release();
音频源设置为“CAMCORDER”并以立体声录制。这个想法是,如果手机有多个麦克风,应用程序将处理来自两者的数据并使用具有更好SNR的任何一个。但是如果从AudioSource.MIC
录制单声道,我也有同样的问题。它在while
循环中读取音频数据,我假设audioRecord.read()
是一个阻塞调用,不会让我读两次相同的数据。
记录的数据看起来正常 - 记录缓冲区包含两个通道的16位PCM样本。循环似乎运行速度是真实设备的两倍。这让我觉得仿真器可能使用比指定的44100Hz更高的采样率。如果我使用audioRecord.getSampleRate()
查询采样率,则返回正确的值。
录制时,logcat中还有一些有趣的音频相关消息:
07-13 12:22:02.282 1187 1531 D AudioFlinger: mixer(0xf44c0000) throttle end: throttle time(154)
(...)
07-13 12:22:02.373 1187 1817 E audio_hw_generic: Error opening input stream format 1, channel_mask 0010, sample_rate 16000
07-13 12:22:02.373 1187 3036 I AudioFlinger: AudioFlinger's thread 0xf3bc0000 ready to run
07-13 12:22:02.403 1187 3036 W AudioFlinger: RecordThread: buffer overflow
(...)
07-13 12:22:24.792 1187 3036 W AudioFlinger: RecordThread: buffer overflow
07-13 12:22:30.677 1187 3036 W AudioFlinger: RecordThread: buffer overflow
07-13 12:22:37.722 1187 3036 W AudioFlinger: RecordThread: buffer overflow
我正在使用最新的Android Studio和Android SDK,我尝试过运行API级别21-24的模拟器图像。我的开发环境是Ubuntu 16.04
有没有人经历过类似的事情? 我在录音循环中做错了吗?
答案 0 :(得分:10)
我怀疑它是由AudioFormat.CHANNEL_IN_STEREO
引起的。设备上的麦克风通常是单声道音频源。如果由于某种原因,仿真器支持立体声,您将在仿真器上接收两倍的数据(对于两个通道)。要验证这一点,请尝试切换到AudioFormat.CHANNEL_IN_MONO
guarantied to work on all devices,然后查看您是否在模拟器上收到相同数量的数据。