【发布时间】: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 设备和所有模拟器现在都可以工作(即使有些比其他的更滞后)。
我在这里做错了什么吗?
【问题讨论】:
标签: android android-emulator buffer-overflow nexus-one android-audiorecord