0

我在使用 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!所以延迟了整整一秒!

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

我在这里做错了什么吗?

4

1 回答 1

2

我解决了!

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

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

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

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

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

于 2010-06-16T15:57:36.807 回答