0

我遇到了使用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設備和所有仿真器現在都可以工作(即使有些設備比其他設備更具遲滯性)。

我在這裏做了什麼可怕的錯誤?

回答

2

我解決了!

我(錯誤地)認爲在AudioRecord類的構造函數中使用的magic 8000數字是頻率變量的副本。它實際上應該是你將要使用的緩衝區大小。不幸的是,這不僅與splmeter的緩衝區長度不同(默認320--我在第一個代碼塊中將其修改爲50),但Nexus One可接受的最小緩衝區大小爲8192,因此AudioRecord實例必須沒有被正確創建。因此,當我修改了緩衝區長度(來自getMinBufferSize),用它替換了magic 8000,並將我的Frequency變量增加到建議的44100時,所有平臺/仿真器中的所有工作都完美無缺。

因此,如果您打算在修補代碼之前使用splmeter代碼庫,請考慮以下三點。

說實話,splmeter代碼甚至不應該在HTC設備上工作。我想這就是爲什麼我的開發設備被命名爲HTC Magic = P

+0

你是如何知道這個8000號碼的?建議的44100和22050採樣率不起作用,但是8000! – 2010-12-17 21:46:11

+0

我不是很確定我明白你的問題嗎? 這個8000號碼是我在splmeter項目中鏈接到的原始代碼(http://code.google.com/p/splmeter/)。然後,8000在原始代碼中使用兩次;一次作爲採樣頻率,一次作爲緩衝區大小。對於緩衝區大小,我建議使用函數調用getMinBufferSize而不是設置一個魔術變量。對於採樣頻率,如果不支持44100,我不確定如何檢查支持的頻率。 AudioRecord的文檔說「價格的例子是(但不限於)44100,22050和11025」。 – Marc 2010-12-29 21:30:23