我在使用 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仍然没有返回任何音频(我自己仍然没有,所以我无法从其中获得正确的调试信息) (即使有些人比其他人更迟钝)。
我在这里做错了什么吗?