非 HTC 设备的 AudioRecord 问题

Posted

技术标签:

【中文标题】非 HTC 设备的 AudioRecord 问题【英文标题】:AudioRecord problems with non-HTC devices 【发布时间】:2011-03-02 08:16:51 【问题描述】:

我在使用 AudioRecord 时遇到问题。

使用源自splmeter 项目的一些代码的示例:

private static final int FREQUENCY = 8000;
private static final int CHANNEL = AudioFormat.CHANNEL_CONFIGURATION_MONO;
private static final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private int BUFFSIZE = 50;
private AudioRecord recordInstance = null;

...

android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);
recordInstance = new AudioRecord(MediaRecorder.Audiosource.MIC, FREQUENCY, CHANNEL, ENCODING, 8000);
recordInstance.startRecording();
short[] tempBuffer = new short[BUFFSIZE];
int retval = 0;

while (this.isRunning) 
   for (int i = 0; i < BUFFSIZE - 1; i++) 
      tempBuffer[i] = 0;
   

   retval = recordInstance.read(tempBuffer, 0, BUFFSIZE);
   ... // process the data

这在 HTC Dream 和 HTC Magic 上完美运行,没有任何日志警告/错误,但会导致模拟器和 Nexus One 设备出现问题。

在 Nexus 上,它根本不会返回有用的数据。由于我有一个远程朋友进行测试,因此我无法提供任何其他有用的信息。

在模拟器(Android 1.5、2.1 和 2.2)上,我从 AudioFlinger 和 AudioRecordThread 的缓冲区溢出中收到奇怪的错误。我的 UI 响应速度也大幅下降(即使录制发生在与 UI 不同的线程中)。

有什么明显的我做错了吗?我需要为 Nexus One 硬件做一些特别的事情吗?

编辑

我已经部分解决了这个问题... AudioRecord 的文档说:

public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)

返回最小缓冲区大小 成功创建所需 AudioRecord 对象。注意 这个尺寸不能保证平滑 在负载下录制,以及更高 值应根据选择 预期的频率 AudioRecord 实例将被轮询 新数据。新数据。

所以我将缓冲区长度更改为

private static final int BUFFSIZE = AudioRecord.getMinBufferSize(FREQUENCY, CHANNEL, ENCODING);

现在模拟器运行良好。

但是

硬件没有。虽然模拟器基于 8khz 从该调用返回 640 值(每秒进行 12.5 次轮询),但 HTC 硬件返回 4096!这意味着大约每秒 2 次轮询和半秒的音频延迟! 此外,在 Nexus One 上的相同调用返回 8192!所以延迟了整整一秒!

我希望它就这样结束了,但是 nexus one 仍然不返回任何音频(我自己仍然没有,所以我无法从其中获得正确的调试信息),即使 HTC 设备和所有模拟器现在都可以工作(即使有些比其他的更滞后)。

我在这里做错了什么吗?

【问题讨论】:

【参考方案1】:

我解决了!

我(错误地)假设 AudioRecord 类的构造函数中使用的神奇数字 8000 是频率变量的副本。它实际上应该是您将使用的缓冲区大小。

不幸的是,这不仅与 splmeter 的缓冲区长度不同(默认 320 - 我在第一个代码块中修改为 50),而且 Nexus One 可接受的最小缓冲区大小为 8192,因此 AudioRecord 实例不得已正确创建。

因此,当我修改了缓冲区长度(来自 getMinBufferSize),用它替换了神奇的 8000,并将我的频率变量增加到建议的 44100 时,一切都在所有平台/模拟器上完美运行。

因此,如果您计划在修补之前使用 splmeter 代码库,请考虑这三件事。

说实话,splmeter 代码甚至不应该在 HTC 设备上运行。我想这就是为什么我的开发设备被命名为 HTC Magic =P

【讨论】:

您是如何得知这个 8000 号码的?建议的 44100 和 22050 采样率不起作用,但 8000 可以! 我不确定我是否理解您的问题? 8000 数字在我在 splmeter 项目 (code.google.com/p/splmeter) 中链接到的原始代码中。然后,在原始代码中使用了两次 8000;一次作为采样频率,一次作为缓冲区大小。对于缓冲区大小,我建议使用函数调用 getMinBufferSize 而不是设置魔法变量。对于采样频率,如果不支持 44100,我不确定如何检查支持的频率。 AudioRecord 的文档说“费率示例是(但不限于)44100、22050 和 11025。”

以上是关于非 HTC 设备的 AudioRecord 问题的主要内容,如果未能解决你的问题,请参考以下文章

AudioRecord一个设备只创建一个线程

AudioRecord一个设备只创建一个线程

为我的 HTC 设备构建 AOSP

htc vr 为啥没有头戴显示器没有画面

Android 音视频开发:使用AudioRecord采集音频PCM并保存

Eclipse 无法识别我对 HTC 的渴望