8.4.3Android音频系统详解_所涉及文件形象讲解

上小节我们讲解了:stream type, strategy, device, output, profile, module : policy,out flag的基本概念,理解了这些概念之后,我们就比较容易去分析代码了。

那么我们需要去分析那些代码呢?这些代码都在那些文件呢?该小节我们讲解以下所涉及的文件:
 

所涉及文件形象讲解
系统服务APP:
frameworks/av/media/mediaserver/main_mediaserver.cpp

AudioFlinger : 
AudioFlinger.cpp  (frameworks/av/services/audioflinger/AudioFlinger.cpp)
Threads.cpp       (frameworks/av/services/audioflinger/Threads.cpp)
Tracks.cpp        (frameworks/av/services/audioflinger/Tracks.cpp)
audio_hw_hal.cpp  (hardware/libhardware_legacy/audio/Audio_hw_hal.cpp)
AudioHardware.cpp (device/friendly-arm/common/libaudio/AudioHardware.cpp)

AudioPolicyService: 
AudioPolicyService.cpp    (frameworks/av/services/audiopolicy/AudioPolicyService.cpp)
AudioPolicyClientImpl.cpp (frameworks/av/services/audiopolicy/AudioPolicyClientImpl.cpp)
AudioPolicyInterfaceImpl.cpp(frameworks/av/services/audiopolicy/AudioPolicyInterfaceImpl.cpp)

AudioPolicyManager.cpp (device/friendly-arm/common/libaudio/AudioPolicyManager.cpp)
AudioPolicyManager.h   (device/friendly-arm/common/libaudio/AudioPolicyManager.h)

AudioPolicyManagerBase.cpp (hardware/libhardware_legacy/audio/AudioPolicyManagerBase.cpp)

堪误: 上面3个文件被以下文件替代
AudioPolicyManager.cpp (frameworks/av/services/audiopolicy/AudioPolicyManager.cpp)

我们想象一个场景,编写一个应用程序播放声音:
1.那么这个声音从哪个设备播放出来呢?这个设备的选择,是由音频的策略服务(AudioPolicyService: )提供的。
2.在其选择某个设备之后,我们需要把声音写给这个设备,那么谁把这些声音写给这个设备?由AudioFlinger实现。
3.所以在andriod系统中会涉及两个服务,AudioFlinger与AudioPolicyService服务。
4.那么谁去启动,或者向系统添加这两个服务呢?由系统服务APP:
frameworks/av/media/mediaserver/main_mediaserver.cpp

我们先来分析一下AudioFlinger这个服务所涉及的文件:

AudioFlinger既然是一个服务,在android系统中,都会使用类把他抽象,这个类被放在文件AudioFlinger.cpp之中,这个这个类给谁用呢?给其他的APP应用程序,其他的APP应用程序通过binder与其AudioFlinger服务进行通信。

AudioFlinger.cpp中包含了如下函数:
1.Ontransact(当APP通过binder发送请求时,AudioFlinger接收到,就会调用该函数)
2.各种函数(如:openInput,openOutput等等),这些函数都是AudioFlinger对外提供的接口。

假设我们的系统上,有两个声卡(图上最下角的两个矩形),其上是linux驱动(driver),为了我们方便使用,有一个tinyalsa库。

AudioFlinger提供的接口函数,最终要访问到硬件,其访问硬件的代码肯定由厂家编写,但是厂家编写的这些代码,必须符合AudioFlinger规范,即audio_hw_hal.cpp文件,在这个文件之中,他定义了一些接口,你必须提供哪些接口函数,如图,在audio_hw_hal的下面就是厂家提供的函数了。

厂家编写的代码也会使用一个类去编写,这个类在AudioHardWare.cpp实现,其定义的符合audio_hw_hal提供的接口。

我们知道,对于每一个硬件,在AudioFlinger中都存在一个硬件与其对应,这个线程所涉及的类的代码,都是在Threads.cpp之中实现的。

现在我们回到应用程序,APP当然可以通过binder与AudioFlinger进行通信,但是这样太麻烦了,为了方便,在android系统中,其又封装了一个类(AudioTracks.cpp),这个类专门给应用程序使用。如果APP程序是直接使用C++编写的,可以直接通过AudioTracks类访问音频系统。对于java应用程序,其也是使用Tracks.java进行访问,AudioTracks.java会通过jni(adroid_media_AudroidTrack.cpp)转化为AudioTracks.cpp,进而访问音频系统。

在上小节我们提到,AudioFlinger之中存在一个成员mTracks,其对应给他提供数据的,每一个应用程序的AudioTracks。mTracks是一个链表,其中包含很多Tracks(在Tracks.cpp中被实现)。

其上就是AudioFlinger所涉及的文件:

下面我们看看AudioPolicyService:
这个服务也被一个类封装,即AudioPolicyService,其使用3个文件进行实现:AudioPolicyService.cpp,AudioPolicyClientImpl.cpp,AudioPolicyInterfaceImpl。

其为什么要分为3个文件,我们看看其有什么差别。操作硬件的是AudioFlinger服务,AudioPolicyService与AudioFlinger需要进行通信,他们是通过binder进行通信。在前面提到,APP与AudioFlinger的binder被封装成了Tracks。在AudioPolicyService中,他和AudioFlinger的通信,被封装成了AudioPolicyClientImpl.cpp。所以在AudioPolicyClientImpl.cpp中封装了对AudioFlinger的使用,表示其为AudioFlinger的一个客户端。

从名字上看,AudioPolicyService也也是一个服务,那么他肯定需要对外提供接口,这些接口就是在AudioPolicyInterfaceImpl中实现,其中肯定存在OnTransact函数,以及其他各类函数,这些函数就是AudioPolicyInterfaceImpl对外提供的接口。

AudioPolicyService中实现的,都是内部需要使用的函数,其并不对外提供。

AudioPolicyService通过的是策略,如需要播放声音,这个声音怎么才能通过硬件播放,那么这些文件都是系统提供的,那么厂家有没有办法提供策略呢?

其实是可以的,但是他不需要遵守一定规范,于规定其提供哪些函数,其必须提供该些函数。这个规范就是一个类AudioPolicyManagerBase.cpp。其是一个基类,厂家需要提供策略时,需要从该基类,派生出自己的类。AudioPolicyManager.cpp文件就是厂家提供的。

在tinyalsa涉及的为:alsa_mixer.c,alsa_pcm.c

到目前为止,音频系统涉及的文件基本讲解完成了,当然和忽略了一些不太重要的文件。
 

发布了241 篇原创文章 · 获赞 28 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_34738528/article/details/104989648