我在使用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设备和所有仿真器现在都能正常工作(即使有些设备比其他设备更滞后)。
我在这里做了一些可怕的错误吗?
答案 0 :(得分:2)
我解决了!
我(错误地)假设AudioRecord类的构造函数中使用的magic 8000数字是频率变量的副本。它实际上应该是你将要使用的缓冲区大小。
不幸的是,这不仅与splmeter的缓冲区长度不同(默认为320 - 我在第一个代码块中修改为50),但Nexus One可接受的最小缓冲区大小为8192,因此AudioRecord实例不能已经正确创建。
所以,当我修改了缓冲区长度(来自getMinBufferSize)时,用它取代了magic 8000,并将我的Frequency变量增加到建议的44100,所有平台/模拟器都可以正常工作。
因此,如果您计划在修补之前使用splmeter代码库,请考虑以下三点。
老实说,splmeter代码甚至不能在HTC设备上运行。我猜这就是为什么我的开发设备被命名为HTC Magic = P