音频数据流程

在系统启动时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中可写的空闲空间的大小,只是加锁和不加锁的区别。

你可能感兴趣的:(java,android,server,jni,user,audio)