AudioMixer
每一个MixerThread在创建的时候都会创建一个AudioMixer赋值给mAudioMixer,也会创建一个mOutputSink。一个AudioMixer有一个mState,一个mState有最多32个track_t。而track_t是由track赋值的,在这里:在MixerThread的prepareTracks_l,对每一个mActiveTracks里的track,mAudioMixer通过setBufferProvider设置track给track_t的BufferProvider,同样,mAudioMixer调用setParameter给track_t的一系列参数赋值,包括VOLUME0,VOLUME1,AUXLEVEL,FORMAT,CHANNEL_MASK,MIXER_CHANNEL_MASK,RESAMPLE,MIXER_FORMAT,AUX_BUFFER,MAIN_BUFFER。在设置MAIN_BUFFER时,根据mMixerBufferEnabled把mMixBuffer或mSinkBuffer赋值给t.mainBuffer。这样,在ProcessXXX函数中,调用bufferProvider->getNextBuffer(&t.buffer,pts)即track->getNextBuffer, 调用mServerProxy->obtainBuffer(&buf)来给输出参数buf赋值。在process_validate中,判断应该使用哪种重采样和混音。然后在process_XXX中,调用到trackXXX,其中track_t里的in不停的赋值给outTemp,而outTmp是按照理论上最大的音频采样精度(32位)和channel数设置的局部变量。然后ConvertMixerFormat将所有采样精度转化为float和16bit,再通过memcpy,ditherAndClamp等把outTemp赋值给out,out就是t1.mainBuffer其实就是mMixBuffer或mSinkBuffer。所以,从App到AT,再从AT到AF都是一个共享内存。而AudioMixer使用了一块新内存来mix数据,就是mMixBuffer。在PlaybackThread::threadLoop_write中,通过mNormalSink->write(mMixBuffer+ offset, count)写入Sink。Mixer没有单独的混音线程,它运行在MixerThread线程。
mNormalSink->write在不使用FastMixer的时候,使用hardware\qcom\audio\hal\audio_hw.c中的out_write进行实际的写入。在播放mp3的时候,这种写入是阻塞的,耗时20ms。后来调用pcm_write来写入,最终调到tinyAlsa的pcm_write_mmap或pcm_write_nmmap。
当需要重采样时,调用的函数一般是
1. process
2. process__genericResampling
3. track__genericResample
4. virtual void resample(int32_t* out, size_toutFrameCount,
AudioBufferProvider* provider)
这个参数out其实是AudioMixer里面的outTemp,和别的需要或不需要重采样的track是叠加关系。
process__genericResampling里面,函数写的比较比较费解,但实际上就是:在所有enabled的track里,把mainBuffer相同的track分成组,就是e1,然后每组进行叠加,并最终复制到相同的mainBuffer里。里面用到了gcc的内嵌函数:
int __builtin_ffs (unsigned int x)
返回x的最后一位1的是从后向前第几位,比如7368(1110011001000)返回4。
int __builtin_clz(unsigned int x)
返回前导的0的个数。
int __builtin_ctz (unsigned int x)
返回后面的0个个数,和__builtin_clz相对。
int __builtin_popcount (unsigned int x)
返回二进制表示中1的个数。
int __builtin_parity (unsigned int x)
返回x的奇偶校验位,也就是x的1的个数模2的结果。
另外,也用到了CC_UNLIKELY
Android默认的Resampler都是软件实现的。系统根据所需Quality的不同来选择不同的resampler。在AudioMixer里面,每个track_t有一个Resampler,根据源采样率和目标采样率来确定不同的quality,从而创建不同的resampler。
如果觉得《android audiomixer Android多媒体:AudioMixer》对你有帮助,请点赞、收藏,并留下你的观点哦!