我遇到了使用AudioRecord的麻煩。非HTC設備的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的夢想與宏達魔術沒有任何日誌警告/錯誤,而導致的仿真器和Nexus問題一臺設備。
在Nexus上,它永遠不會返回有用的數據。我不能提供任何其他有用的信息,因爲我有一個遠程的朋友做測試。
在模擬器(Android 1.5,2.1和2.2)上,我從AudioFlinger和AudioRecordThread的Buffer overflows中得到奇怪的錯誤。我的UI響應速度也有所下降(即使記錄發生在與UI不同的線程中)。
有什麼明顯的表明我做錯了嗎?我需要爲Nexus One硬件做什麼特別的事嗎?
編輯
我已經部分地解決了這個問題... 爲AudioRecord文檔說:
public static int getMinBufferSize (int sampleRateInHz, int channelConfig, int audioFormat)
返回的成功創建 所需的最小緩衝區大小 一個AudioRecord對象。需要注意的是 這個尺寸並不能保證在負載下的平滑 記錄,和更高的 值應根據 在該 AudioRecord實例將新data.for新數據被輪詢 預期頻率來選擇。
所以我改變了緩衝區長度
private static final int BUFFSIZE = AudioRecord.getMinBufferSize(FREQUENCY, CHANNEL, ENCODING);
而且現在的仿真器運行良好。
但是
硬件沒有。當仿真器返回基於8khz的呼叫值(每秒12.5次輪詢)時,HTC硬件返回4096!意味着大約每秒2次民意調查,並且音頻延遲半秒鐘! 此外,Nexus One上的相同呼叫將返回8192!那麼完整的第二個延遲!
我希望它結束在那,但是一個仍然不返回任何音頻(仍然沒有一個我自己,所以我不能從一個得到適當的調試信息),即使HTC設備和所有仿真器現在都可以工作(即使有些設備比其他設備更具遲滯性)。
我在這裏做了什麼可怕的錯誤?
你是如何知道這個8000號碼的?建議的44100和22050採樣率不起作用,但是8000! – 2010-12-17 21:46:11
我不是很確定我明白你的問題嗎? 這個8000號碼是我在splmeter項目中鏈接到的原始代碼(http://code.google.com/p/splmeter/)。然後,8000在原始代碼中使用兩次;一次作爲採樣頻率,一次作爲緩衝區大小。對於緩衝區大小,我建議使用函數調用getMinBufferSize而不是設置一個魔術變量。對於採樣頻率,如果不支持44100,我不確定如何檢查支持的頻率。 AudioRecord的文檔說「價格的例子是(但不限於)44100,22050和11025」。 – Marc 2010-12-29 21:30:23