Android 模拟器似乎以 96khz 录制音频

Posted

技术标签:

【中文标题】Android 模拟器似乎以 96khz 录制音频【英文标题】:Android Emulator Seems to Record Audio at 96khz 【发布时间】:2016-07-13 09:28:55 【问题描述】:

我的应用正在从手机的麦克风录制音频并对其进行一些实时处理。它在物理设备上运行良好,但在模拟器中表现“有趣”。它记录了一些东西,但我不太确定它在记录什么。

在模拟器上,音频样本的读取速度似乎是实际设备上的两倍。在应用程序中,我有一个视觉进度小部件(水平移动的录音头),它会移动在模拟器中大约快两倍。

这是录音循环:

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();

音频源设置为“CAMC​​ORDER”并以立体声录制。这个想法是,如果手机有多个麦克风,该应用程序将处理来自这两个麦克风的数据并使用具有更好 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

有没有人经历过类似的事情? 我在录音循环中做错了吗?

【问题讨论】:

您的开发环境的采样率是多少? 【参考方案1】:

我怀疑它是由AudioFormat.CHANNEL_IN_STEREO 引起的。设备上的麦克风通常是单声道音频源。如果由于某种原因模拟器支持立体声,您将在模拟器上接收两倍的数据(对于两个通道)。要验证这一点,请尝试切换到AudioFormat.CHANNEL_IN_MONO,即guarantied to work on all devices,然后看看您是否在模拟器上收到相同数量的数据。

【讨论】:

切换到CHANNEL_IN_MONO 并遇到了同样的问题。我认为应用程序代码没有问题,问题出在模拟器或我的操作系统上。我从 Play 商店安装了一个不相关的“录音机”应用程序,它还记录了垃圾。然后我尝试在 Genymotion 中运行我的应用,并且录音效果很好。

以上是关于Android 模拟器似乎以 96khz 录制音频的主要内容,如果未能解决你的问题,请参考以下文章

在 HTC One 上以 16khz 单声道 PCM (WAV) 录制时出现断断续续的音频

录制音频时如何将音频录制设置更改为 16Khz 和 16 位?

一个 DSP 可以结合两个 48khz 的音频流来创建一个 96khz 的输出吗

如何将 8 kHz 音频采样率提高到 16 kHz STM32

android:在模拟器上使用 MediaPlayer 录制音频

将实时音频与 Android 中录制的音频进行比较