以前看这个函数的时候,对min frame是如何计算得来的,并不是很了解。
今天又看了看,终于有点头绪了。
先看看下面这一段代码:
从字面意思上,也基本上可以看出来,是去获取output 设备的sampling rate的。
如何获取到的呢?
一步一步来吧。
函数AudioSystem::getOutputSamplingRate中会首先根据stream type获取对应的output,然后尝试获取output的描述。
若获取成功,取output描述的samplerate:
否则,取AudioFlinger的sample rate:
先看audio flinger的sample rate是如何取得的。
函数AudioFlinger::sampleRate中,找到output对应的thread,取对应thread的sample rate。
函数AudioFlinger::ThreadBase::sampleRate中直接返回了成员变量mSampleRate。
mSampleRate是在函数AudioFlinger::PlaybackThread::readOutputParameters中被赋值:
mOutput->sampleRate,真正调用的是AudioStreamOutALSA对象的函数。
函数定义在其父类ALSAStreamOps中:
mHandle的赋值在ALSAStreamOps的构造函数中。使用的是构造函数参数handle。
AudioStreamOutALSA对象中函数AudioHardwareALSA::openOutputStream被创建:
其中it即为构造函数参数handle。
it的赋值:
mDeviceList的赋值在AudioHardwareALSA的构造函数中:
init函数其实就是s_init函数:
_defaults的定义:
sampleRate原来是在这儿指定的:
DEFAULT_SAMPLE_RATE的定义为44100.
所以,afSampleRate的值其实就是44100.
回头看看,若是在函数AudioSystem::getOutputSamplingRate中找到了output的描述,情况又是怎样的呢?
output描述是在AudioPolicyManagerBase的构造函数中被创建。
其中,latency是通过调用函数mpClientInterface->openOutput取得:
其实就是调用了函数AudioFlinger::openOutput。
其中对SamplingRate的赋值:
samplingRate的来历:
函数AudioHardwareALSA::openOutputStream中对samplingRate的赋值:
函数ALSAStreamOps::set中对sampleRate的处理:
与前面的那条河流汇合了。
FrameCount与sampleRate的流程类似,下面只说是其中不同的地方。
AudioFlinger::PlaybackThread::readOutputParameters函数中:
函数frameSize来自于类AudioStreamOut:
函数ALSAStreamOps::channels的实现:
看看channels在_defaults中的定义:
函数ALSAStreamOps::format实现:
看看format在_defaults中的定义:
PCM_8_BIT与PCM_16_BIT的定义:
所以,
的结果其实就是4.
函数ALSAStreamOps::bufferSize的实现:
看看bufferSize在_defaults中的定义:
所以,不考虑alsa lib,下面:
的运算结果为:6144 / 4 = 1536
即afFrameCount为1536.
关于latency的流程就不再看了。
在_defaults中,latency的定义为:
根据以下计算公式:
可以算得,afLatency的结果其实就是200.
变量的值都知道了,所以minBufCount也就可以算出来了:
minBufCount = 200 / ((1000×1536)/44100) = 5.
消化消化。
afFrameCount的意思是硬件buffer里能放多少frame,afFrameCount/afSampleRate的意思是,播放一次硬件buffer中的数据需要多少时间,算出来的单位是秒。
再乘以个1000,即将秒转为了毫秒。
这样就与afLatency的单位一致了。
这样算出来的结果,就是说,为了满足硬件延迟,软件侧的buffer大小只是要是硬件侧buffer大小的多少倍。
感觉还是没消化彻底。
什么是硬件延迟?为什么软件侧的buffer size需要这个倍数呢?
硬件延迟,就是说,硬件侧可能会延迟这么久,也就是说硬件可能有这么长的时间都没有从软件侧取数据。
而软件侧还在不停地写数据,为了保证软件侧的数据不被丢失,就需要软件侧的buffer足够大。
多大才是足够大呢?
就是在硬件允许的最大时间,不取数据的情况下,软件侧的buffer也不至于爆仓。
这样基本上消化彻底了。
frameCount的计算与传入参数sampleRate有关:
如果sampleRate为0,frameCount为 7680.
如果sampleRate不为0,frameCount为7680×sampleRate/44100.
消化一下。
既然上面已经算出来了软件buffer 大小只是要是硬件的多少倍,而硬件buffer中包含的frame个数已经知道为afFrameCount,
算出软件buffer中包含多少frame也没什么困难了。
如果软件侧过来的数据与硬件侧的sampling rate未指定,或者与硬件侧的一样,软件侧的buffer能装的frame个数即为afFrameCount * minBufCount。
如果软件侧的sampling rate与硬件侧不一致,就拿上面的结果再乘以个sampleRate / afSampleRate即可。