最近在看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自然不是什么难事。