最近在看android audio部分代碼時,對getMinBufferSize有了一點新體會,之前的疙瘩終於解開了。
也要感謝ldh_123456兄弟的回複,協助我對此進行了理解。
詳細的調用過程就不說了,簡單說一下下面幾行代碼的理解。
// Ensure that buffer depth covers at least audio hardware latency
// 下面這行代碼的功能,就是上面英文注釋。afFrameCount是硬體緩衝區的大小,單位是frame。
// 為什麼單位是frame呢,因為採樣率指的是1秒鐘有多少個採樣點,一個採樣點其實就是一個frame,其大小為:聲道數×採樣深度。
// 例如,雙聲道,格式即採樣深度為16bit的資料,其frame size為:2×2=4.
// afSampleRate是硬體播放時真正的採樣率。
// 解釋到這兒,下面這行代碼的意思基本明了了。
// afFrameCount / afSampleRate得出來是一個硬體緩衝區能播放多長時間,單位是 frame / (frame / s),也就是秒了。
// afLatency是硬體要求的延遲,單位是ms,所以,afFrameCount / afSampleRate的結果為了與afLatency單位一致,就乘了個1000.
// ((1000 * afFrameCount) / afSampleRate)如果能寫成(1000×(afFrameCount / afSampleRate))就好理解多了。
// 這行代碼得出的結果就是為了滿足硬體延遲,軟體上至少要建立幾個buffer。注意這兒只是算出來個數,還沒涉及每個buffer的size。
uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate);
// 這行代碼的意思是軟體層至少應該有兩塊buffer
if (minBufCount < 2) minBufCount = 2;
// 上面計算出了buffer的個數,下面就該計算每個buffer的大小了。
// 每個buffer應該多大呢,應該與硬體buffer對應,這樣剛好一個軟體buffer的資料塞給一個硬體buffer。
// 這樣說的話,是不是軟體buffer的大小和硬體buffer一樣,為afFrameCount就OK了?
// 當然不是那麼簡單,因為中間會涉及採樣率轉換的問題,硬體的採樣率是固定的(一般如此),而播放的音樂的採樣率各種各樣,這樣就需要進行採樣率轉換。
// 軟體buffer儲存的是轉換之前的資料,硬體buffer儲存的是轉換後的資料。
// 為了保證軟體buffer與硬體buffer中資料播放時間長度對應,需要:(單個軟體buffersize / sampleRate) = (afFrameCount / afSampleRate)。
// 也就是單個軟體buffersize = (afFrameCount * sampleRate) / afSampleRate。
// 總的軟體buffer size(單位為frame)為:minBufCount * (afFrameCount * sampleRate) / afSampleRate。
// google寫成下面這個樣子,是不是故意迷惑人的???
*frameCount = (sampleRate == 0) ? afFrameCount * minBufCount :
afFrameCount * minBufCount * sampleRate / afSampleRate;
// 知道了以frame為單位的buffer size,又知道frame的定義,求以byte為單位的buffer size自然不是什麼難事。