在系统启动时MediaSever加载了两个服务:AudioPolicyService和AudioFlinger。
1.3.1 AudioPolicyService
AudioPolicyService主要完成以下任务
JAVA应用层通过JNI,经由IAudioPolicyService接口,访问AudioPolicyService提供的服务
输入输出设备的连接状态
系统的音频策略(strategy)的切换
音量/音频参数的设置
1.3.2 AudioFlinger
AudioFlinger向下访问AudioHardware,实现输出音频数据,控制音频参数。同时,AudioFlinger向上通过IAudioFinger接口提供服务。所以,AudioFlinger在Android的音频系统框架中起着承上启下的作用
1.3.3 how towork
AudioTrack:Android的音频子系统中,每一个音频流对应着一个AudioTrack类的一个实例,每个AudioTrack会在创建时注册到AudioFlinger中,由AudioFlinger把所有的AudioTrack进行混合(Mixer),然后输送到AudioHardware中进行播放,目前Android的Froyo版本设定了同时最多可以创建32个音频流,开辟的空间是1M,每个音轨32K,也就是说,Mixer最多会同时处理32个AudioTrack的数据流。
binder:AudioTrack和AudioFlinger并不在同一个进程中,它们通过android中的binder机制建立联系。
audio_track_cblk_t实现了一个环形FIFO;
AudioTrack是FIFO的数据生产者;
AudioFlinger是FIFO的数据消费者。
建立联系的过程
Java层通过JNI,new AudioTrack();
根据StreamType等参数,通过一系列的调用getOutput();
如有必要,AudioFlinger根据StreamType打开不同硬件设备;
AudioFlinger为该输出设备创建混音线程:MixerThread(),并把该线程的id作为getOutput()的返回值返回给AudioTrack;
AudioTrack通过binder机制调用AudioFlinger的createTrack();
AudioFlinger注册该AudioTrack到MixerThread中;
AudioFlinger创建一个用于控制的TrackHandle,并以IAudioTrack这一接口作为createTrack()的返回值;
AudioTrack通过IAudioTrack接口,得到在AudioFlinger中创建的FIFO(audio_track_cblk_t);
AudioTrack创建自己的监控线程:AudioTrackThread;
自此,AudioTrack建立了和AudioFlinger的全部联系工作,接下来,AudioTrack可以:通过IAudioTrack接口控制该音轨的状态,例如start,stop,pause等等;通过对FIFO的写入,实现连续的音频播放;监控线程监控事件的发生,并通过audioCallback回调函数与用户程序进行交互;
FIFO的管理
audio_track_cblk_t结构是FIFO实现的关键,该结构是在createTrack的时候,由AudioFlinger申请相应的内存,然后通过IMemory接口返回AudioTrack的,这样AudioTrack和AudioFlinger管理着同一个 audio_track_cblk_t,通过它实现了环形FIFO,AudioTrack向FIFO中写入音频数据,AudioFlinger从FIFO 中读取音频数据,经Mixer后送给AudioHardware进行播放。
audio_track_cblk_t的主要数据成员:
user -- AudioTrack当前的写位置的偏移
userBase -- AudioTrack写偏移的基准位置,结合user的值方可确定FIFO地址指针
server -- AudioFlinger当前的读位置的偏移
serverBase -- AudioFlinger读偏移的基准位置,结合server的值方可确定FIFO地址指针
frameCount -- FIFO的大小,以音频数据的帧为单位,16bit的音频每帧的大小是2字节
buffers -- 指向FIFO的起始地址
out -- 音频流的方向,对于AudioTrack,out=1,对于AudioRecord,out=0
audio_track_cblk_t的主要成员函数:
framesAvailable_l()和framesAvailable()用于获取FIFO中可写的空闲空间的大小,只是加锁和不加锁的区别。