今天又看了看,终于有点头绪了。
status_t AudioTrack::getMinFrameCount( int* frameCount, int streamType, uint32_t sampleRate) { int afSampleRate; if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { return NO_INIT; } int afFrameCount; if (AudioSystem::getOutputFrameCount(&afFrameCount, streamType) != NO_ERROR) { return NO_INIT; } uint32_t afLatency; if (AudioSystem::getOutputLatency(&afLatency, streamType) != NO_ERROR) { return NO_INIT; } // Ensure that buffer depth covers at least audio hardware latency uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate); if (minBufCount < 2) minBufCount = 2; *frameCount = (sampleRate == 0) ? afFrameCount * minBufCount : afFrameCount * minBufCount * sampleRate / afSampleRate; return NO_ERROR; } 先看看下面这一段代码: int afSampleRate; if (AudioSystem::getOutputSamplingRate(&afSampleRate, streamType) != NO_ERROR) { return NO_INIT; } 从字面意思上,也基本上可以看出来,是去获取output 设备的sampling rate的。 如何获取到的呢? 一步一步来吧。 函数AudioSystem::getOutputSamplingRate中会首先根据stream type获取对应的output,然后尝试获取output的描述。 若获取成功,取output描述的samplerate: *samplingRate = outputDesc->samplingRate; 否则,取AudioFlinger的sample rate: *samplingRate = af->sampleRate(output); 先看audio flinger的sample rate是如何取得的。 函数AudioFlinger::sampleRate中,找到output对应的thread,取对应thread的sample rate。 函数AudioFlinger::ThreadBase::sampleRate中直接返回了成员变量mSampleRate。 mSampleRate是在函数AudioFlinger::PlaybackThread::readOutputParameters中被赋值: mSampleRate = mOutput->sampleRate(); mOutput->sampleRate,真正调用的是AudioStreamOutALSA对象的函数。 函数定义在其父类ALSAStreamOps中: uint32_t ALSAStreamOps::sampleRate() const { return mHandle->sampleRate; } mHandle的赋值在ALSAStreamOps的构造函数中。使用的是构造函数参数handle。 AudioStreamOutALSA对象中函数AudioHardwareALSA::openOutputStream被创建: out = new AudioStreamOutALSA(this, &(*it)); 其中it即为构造函数参数handle。 it的赋值: ALSAHandleList::iterator it = mDeviceList.begin(); mDeviceList的赋值在AudioHardwareALSA的构造函数中: mALSADevice->init(mALSADevice, mDeviceList); init函数其实就是s_init函数: static status_t s_init(alsa_device_t *module, ALSAHandleList &list) { LOGD("Initializing devices for IMX51 ALSA module"); list.clear(); for (size_t i = 0; i < ARRAY_SIZE(_defaults); i++) { _defaults[i].module = module; list.push_back(_defaults[i]); } return NO_ERROR; } _defaults的定义: static alsa_handle_t _defaults[] = { { module : 0, devices : IMX51_OUT_DEFAULT, curDev : 0, curMode : 0, handle : 0, format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT channels : 2, sampleRate : DEFAULT_SAMPLE_RATE, latency : 200000, // Desired Delay in usec bufferSize : 6144, // Desired Number of samples modPrivate : (void *)&setDefaultControls, }, { module : 0, devices : IMX51_IN_DEFAULT, curDev : 0, curMode : 0, handle : 0, format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT channels : 2, sampleRate : DEFAULT_SAMPLE_RATE, latency : 250000, // Desired Delay in usec bufferSize : 6144, // Desired Number of samples modPrivate : (void *)&setDefaultControls, }, }; sampleRate原来是在这儿指定的: sampleRate : DEFAULT_SAMPLE_RATE, DEFAULT_SAMPLE_RATE的定义为44100. 所以,afSampleRate的值其实就是44100. 回头看看,若是在函数AudioSystem::getOutputSamplingRate中找到了output的描述,情况又是怎样的呢? output描述是在AudioPolicyManagerBase的构造函数中被创建。 其中,latency是通过调用函数mpClientInterface->openOutput取得: mHardwareOutput = mpClientInterface->openOutput(&outputDesc->mDevice, &outputDesc->mSamplingRate, &outputDesc->mFormat, &outputDesc->mChannels, &outputDesc->mLatency, outputDesc->mFlags); 其实就是调用了函数AudioFlinger::openOutput。 其中对SamplingRate的赋值: if (pSamplingRate) *pSamplingRate = samplingRate; samplingRate的来历: AudioStreamOut *output = mAudioHardware->openOutputStream(*pDevices, (int *)&format, &channels, &samplingRate, &status); 函数AudioHardwareALSA::openOutputStream中对samplingRate的赋值: err = out->set(format, channels, sampleRate); 函数ALSAStreamOps::set中对sampleRate的处理: if (rate && *rate > 0) { if (mHandle->sampleRate != *rate) return BAD_VALUE; } else if (rate) *rate = mHandle->sampleRate; 与前面的那条河流汇合了。 FrameCount与sampleRate的流程类似,下面只说是其中不同的地方。 AudioFlinger::PlaybackThread::readOutputParameters函数中: mFrameSize = (uint16_t)mOutput->frameSize(); mFrameCount = mOutput->bufferSize() / mFrameSize; 函数frameSize来自于类AudioStreamOut: /** * return the frame size (number of bytes per sample). */ uint32_t frameSize() const { return AudioSystem::popCount(channels())*((format()==AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); } 函数ALSAStreamOps::channels的实现: uint32_t ALSAStreamOps::channels() const { unsigned int count = mHandle->channels; uint32_t channels = 0; if (mHandle->curDev & AudioSystem::DEVICE_OUT_ALL) switch(count) { case 4: channels |= AudioSystem::CHANNEL_OUT_BACK_LEFT; channels |= AudioSystem::CHANNEL_OUT_BACK_RIGHT; // Fall through... default: case 2: channels |= AudioSystem::CHANNEL_OUT_FRONT_RIGHT; // Fall through... case 1: channels |= AudioSystem::CHANNEL_OUT_FRONT_LEFT; break; } else switch(count) { default: case 2: channels |= AudioSystem::CHANNEL_IN_RIGHT; // Fall through... case 1: channels |= AudioSystem::CHANNEL_IN_LEFT; break; } return channels; } 看看channels在_defaults中的定义: channels : 2, 函数ALSAStreamOps::format实现: int ALSAStreamOps::format() const { int pcmFormatBitWidth; int audioSystemFormat; snd_pcm_format_t ALSAFormat = mHandle->format; pcmFormatBitWidth = snd_pcm_format_physical_width(ALSAFormat); switch(pcmFormatBitWidth) { case 8: audioSystemFormat = AudioSystem::PCM_8_BIT; break; default: LOG_FATAL("Unknown AudioSystem bit width %i!", pcmFormatBitWidth); case 16: audioSystemFormat = AudioSystem::PCM_16_BIT; break; } return audioSystemFormat; } 看看format在_defaults中的定义: format : SND_PCM_FORMAT_S16_LE, // AudioSystem::PCM_16_BIT PCM_8_BIT与PCM_16_BIT的定义: // Audio sub formats (see AudioSystem::audio_format). enum pcm_sub_format { PCM_SUB_16_BIT = 0x1, // must be 1 for backward compatibility PCM_SUB_8_BIT = 0x2, // must be 2 for backward compatibility }; 所以, mFrameSize = (uint16_t)mOutput->frameSize(); 的结果其实就是4.函数ALSAStreamOps::bufferSize的实现:
size_t ALSAStreamOps::bufferSize() const { snd_pcm_uframes_t bufferSize = mHandle->bufferSize; snd_pcm_uframes_t periodSize; // 掉进了难缠的alsa lib,先不去看了。 snd_pcm_get_params(mHandle->handle, &bufferSize, &periodSize); size_t bytes = static_cast<size_t>(snd_pcm_frames_to_bytes(mHandle->handle, bufferSize)); // Not sure when this happened, but unfortunately it now // appears that the bufferSize must be reported as a // power of 2. This might be for OSS compatibility. for (size_t i = 1; (bytes & ~i) != 0; i<<=1) bytes &= ~i; return bytes; }
看看bufferSize在_defaults中的定义:bufferSize : 6144, // Desired Number of samples
所以,不考虑alsa lib,下面:mFrameCount = mOutput->bufferSize() / mFrameSize;
的运算结果为:6144 / 4 = 1536 即afFrameCount为1536. 关于latency的流程就不再看了。 在_defaults中,latency的定义为:latency : 200000, // Desired Delay in usec
根据以下计算公式:#define USEC_TO_MSEC(x) ((x + 999) / 1000)
可以算得,afLatency的结果其实就是200. 变量的值都知道了,所以minBufCount也就可以算出来了:// Ensure that buffer depth covers at least audio hardware latency uint32_t minBufCount = afLatency / ((1000 * afFrameCount) / afSampleRate);
minBufCount = 200 / ((1000×1536)/44100) = 5. 消化消化。 afFrameCount的意思是硬件buffer里能放多少frame,afFrameCount/afSampleRate的意思是,播放一次硬件buffer中的数据需要多少时间,算出来的单位是秒。 再乘以个1000,即将秒转为了毫秒。 这样就与afLatency的单位一致了。 这样算出来的结果,就是说,为了满足硬件延迟,软件侧的buffer大小只是要是硬件侧buffer大小的多少倍。 感觉还是没消化彻底。 什么是硬件延迟?为什么软件侧的buffer size需要这个倍数呢? 硬件延迟,就是说,硬件侧可能会延迟这么久,也就是说硬件可能有这么长的时间都没有从软件侧取数据。 而软件侧还在不停地写数据,为了保证软件侧的数据不被丢失,就需要软件侧的buffer足够大。 多大才是足够大呢? 就是在硬件允许的最大时间,不取数据的情况下,软件侧的buffer也不至于爆仓。 这样基本上消化彻底了。 frameCount的计算与传入参数sampleRate有关:*frameCount = (sampleRate == 0) ? afFrameCount * minBufCount : afFrameCount * minBufCount * sampleRate / afSampleRate;
如果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即可。