1Audio系统的组成有哪些?
(1)AudioRcorder和AudioTrack:这两个类属于Audio系统对外提供的API类,通过它们可以完成Android平台上音频数据的采集和输出任务。
(2)AudioFlinger:它是Audio系统的工作引擎,管理着系统中的输入输出音频流,并承担音频数据的混音,以及读写Audio硬件以实现数据的输入输出等工作。
(3)AudioPolicyService,它是Audio系统的策略控制中心,具有掌管系统中声音设备的选择和切换、音量控制等功能。
2AudioTrack的数据加载模式
(1)MODE_STREAM:在这种模式下,通过write一次次把音频数据写到AudioTrack中。这和平时通过write系统调用往文件中写数据类似,但这种工作方式每次都需要把数据从用户提供的Buffer中拷贝到AudioTrack内部的Buffer中,这在一定程度上会使引入延时。为解决这一问题,AudioTrack就引入了第二种模式。
(2)MODE_STATIC:这种模式下,在play之前只需要把所有数据通过一次write调用传递到AudioTrack中的内部缓冲区,后续就不必再传递数据了。这种模式适用于像铃声这种内存占用量较小,延时要求较高的文件。但它也有一个缺点,就是一次write的数据不能太多,否则系统无法分配足够的内存来存储全部数据。
3音频流的类型
(1)STREAM_ALARM:警告声
(2)STREAM_MUSIC:音乐声,例如music等
(3)STREAM_RING:铃声
(4)STREAM_SYSTEM:系统声音,例如低电提示音,锁屏音等
(5)STREAM_VOCIE_CALL:通话声
4共享内存相关知识
(1)每个进程的内存空间是4GB,这个4GB是由指针长度决定的,如果指针长度为32位,那么地址的最大编号就是0xFFFFFFFF,为4GB。
(2)上面说的内存空间是进程的虚拟地址空间。换言之,在应用程序中使用的指针其实是指向虚拟空间地址的。那么,如何通过这个虚地址找到存储在真实物理内存中的数据呢?
5共享内存和内存映射的关系是什么?

6Linux平台如何创建和共享内存呢?
(1)进程A创建并打开一个文件,得到一个文件描述符fd。
(2)通过mmap调用将fd映射成内存映射文件。在mmap调用中指定特定参数表示要创建进程间共享内存。
(3)进程B打开同一个文件,也得到一个文件描述符,这样A和B就打开了同一个文件。
(4)进程B也要用mmap调用指定参数表示想使用共享内存,并传递打开的fd。这样A和B就通过打开同一个文件并构造内存映射,实现了进程间内存共享。
7AudioTrack与AudioFlinger的交互流程图

8AudioFlinger中有几种不同类型的工作线程

(1)PlaybackThread:回放线程,用于音频输出。它有一个成员变量mOutput,为AudioStreamOutput*类型,这表明PlaybackThread直接和Audio音频输出设备建立了联系。
(2)RecordThread:录音线程,用于音频输入,它的关系比较单纯。它有一个成员变量mInput为AudioStreamInput*类型,这表明RecordThread直接和Audio音频输入设备建立了联系。
9AudioFlinger对象
AudioFlinger的主要工作由其定义的许多内部类来完成。

10AudioFlinger中有几种不同类型的工作线程

说明:
(1)PlaybackThread:回放线程,用于音频输出。它有一个成员变量mOutput,为AudioStreamOutput*类型,这表明PlaybackThread直接和Audio音频输出设备建立了联系。
(2)RecordThread:录音线程,用于音频输入,它的关系比较单纯。它有一个成员变量mInput为AudioStreamInput*类型,这表明RecordThread直接和Audio音频输入设备建立了联系。
从PlaybackThread的派生关系上可看出,手机上的音频回放应该比较复杂,否则也不会派生出三个子类了。其中:
(1)MixerThread:混音线程,它将来自多个源的音频数据混音后再输出。
(2)DirectOutputThread:直接输出线程,它会选择一路音频流后将数据直接输出,由于没有混音的操作,这样可以减少很多延时。(3)DuplicatingThread:多路输出线程,它从MixerThread派生,意味着它也能够混音。它最终会把混音后的数据写到多个输出中,也就是一份数据会有多个接收者。这就是Duplicate的含义。目前在蓝牙A2DP设备输出中使用。
另外从图7-8中还可以看出:
(1)PlaybackThread维护两个Track数组,一个是mActiveTracks,表示当前活跃的Track,一个是mTracks,表示这个线程创建的所有Track。
(2)DuplicatingThread还维护了一个mOutputTracks,表示多路输出的目的端。后面分析DuplicatingThread时再对此进行讲解。
11Audio系统大家族

12