Android Audio system 

1.基于ALSA的Andorid音频系统拥有一个比较标准和健全的架构,自上而下由Audio应用程序、Audio Java框架层、Audio本地框架层、AudioFlinger、Audio硬件抽象层、alsa-lib和底层Audio驱动几个部分组成。本文研究基于ALSA的Android音频系统的总体设计,分析其架构各个层次的功能

2.Audio硬件抽象层是AudioFlinger和底层Audio驱动的接口,需要根据具体平台进行移植,可以有多种实现方式。本文介绍基于ALSA的Audio硬件抽象层的具体实现。

3、采用ASoC(ALSA System on Chip)架构实现Audio驱动。ASoC中,Audio驱动包括codec驱动,platform驱动和machine驱动三部分。本文研究ALC5625驱动和I2S驱动的具体实现,以及machine驱动如何将两者整合起来

 

 

AudioService setMode源码分析 audio system_Java

 

1、Audio 应用程序

与 Audio 相关的应用程序非常多,主要有录音器、音乐播放器、视频播放器等。这些应用程序通过调用下层提供的 Audio 相关接口实现各种音频功能, 它们位于最顶层直接与用户进行交互,承担为用户提供良好音频体验的责任。 该部分在本文中不做具体介绍。

2、Audio Java 框架层

代码路径:frameworks/base/media/java/android/media

与 Audio 相关的 Java 包是 android.media,主要包含的类有 AudioManager、AudioService、MediaPlayer、MediaRecorder、AudioTrack、AudioRecord 等等。这部分主要给上层应用程序提供 Audio 相关接口。

3、Audio 本地框架层

头文件路径:frameworks/base/include/media 

代码路径:frameworks/base/media/libmedia

Audio 本地框架是 media 库的一部分,本部分的内容被编译成库 libmedia.so,主要包含的类有 AudioTrack, AudioRecord, AudioSystem 等等。这部分使用 C/C++语言编写,上层 Java 代码调用 libmedia.so 提供的各种接口需要经过 JNI(Java Native Interface) 。JNI 使得在 Java 虚拟机内部运行的 Java 代码能够与用其它编程语言(如 C、C++和汇编语言)编写的应用程序和库进行交互操作。

4、AudioFlinger

代码路径:frameworks/base/services/audioflinger

这部分内容被编译成库 libaudioflinger.so。AudioFlinger 的功能是管理音频输入输出流,管理各种工作线程和音轨。 AudioFlinger 向下访问 Audio 硬件抽象层,向上通过 IAudioFinger 接口提供服务。所以,AudioFlinger 在 Android 的音频系统框架中起着承上启下的作用,地位相当重要。

5、Audio 硬件抽象层

头文件路径:hardware/libhardware_legacy/include/hardware_legacy

代码路径:hardware/alsa_sound

Audio 硬件抽象层,简称 AudioHAL,是 AudioFlinger 和 Audio 驱动的接口。它的实现在各个平台中可能不同,需要继承 AudioHardwareInterface.h 等头文件中定义的各种类并实现它们。本设计采用基于 ALSA 实现 Audio 硬件抽象层,Audio 硬件抽象层并不直接操作底层驱动程序提供的设备节点,而是调用 alsa-lib提供的 API。

6、alsa-lib

代码路径:external/alsa-lib

默认情况下,Android4.0 不再使用原始的 alsa-lib,取而代之的是 tinyalsa。Tinyalsa 只提供基本的接口,比 alsa-lib 更加小巧而简单,但是 tinyalsa 无法完全替代 alsa-lib,相反 alsa-lib 可以完全替代 tinyalsa。本设计没有使用 tinyalsa,而是延用原来的 alsa-lib。Alsa-lib 是用户空间的函数库,提供了 libasound.so 给应用程序使用,应用程序应包含头文件 asoundlib.h 。这个库通过提供封装函数(ALSA-API)使 ALSA 应用程序不需要涉及具体硬件,编写起来更容易。 Alsa-lib中有 kcontrol  、timer、dmix、pcm 等,都是以插件(plugin)的形式存在的,asound.conf 中可对这些插件进行配置。 Alsa-lib 通过使用系统调用的接口 (open、ioctl、write、read 等)实现与底层驱动的对接。

7、Audio 驱动

代码路径:sound/soc

声卡驱动核心代码:sound/soc/soc-core.c

Codec 驱动代码路径:sound/soc/codecs

ASoC platform 驱动和 machine 驱动代码路径:sound/soc/rk29

Audio 驱动运行在 Linux 内核空间,为用户空间提供音频系统的控制接口和数据接口。本设计采用 ASoC 架构实现 Audio 驱动,使用标准的 alsa-driver 作为声卡驱动程序。

AudioService setMode源码分析 audio system_应用程序_02

 

 Audio 关键类详解 

1.AudioManage class

a.设置系统音量

b.控制系统的铃声模式

c.设置系统的音频模式

2.AudioTrack

AudioTrack 实 现音频系统回放功能 。 C++ 类 AudioTrack 的代码在frameworks\base\media\libmedia\AudioTrack.cpp 中,Java  类 AudioTrack  的代码在 framework\base\media\java\android\media\AudioTrack.java 中

 

AudioService setMode源码分析 audio system_应用程序_03

 

 

结构体 audio_track_cblk_t[10][11]管理共享内存,在 AudioTrackShared.h 中定义,在 AudioTrack.cpp 中实现。audio_track_cblk_t 管理的共享内存由 AudioFlinger:: ThreadBase::TrackBase::TrackBase()申请分配,其作用是实现 C++类 AudioTrack与 AudioFlinger,C++类 AudioRecord 与 AudioFlinger 之间的音频数据传输,如图 5-3 所示。回放时, C++类 AudioTrack 将音频数据写入该共享内存, AudioFlinger接收到音频数据后,回放线程调用 AudioStreamOut 接口再将音频数据输出给Audio 硬件。录音时,Audio 硬件采集音频数据,AudioFlinger 的录音线程调用AudioStreamIn 接口将数据读取到共享内存, C++类 AudioRecord 再从共享内存中读取音频数据

 

AudioService setMode源码分析 audio system_Java_04

 

3.AudioRecord

AudioRecord 实现 音频系统 录音 功能 。 C++ 类 AudioRecord 的代码在frameworks\base\media\libmedia\  AudioRecord.cpp 中, Java 类 AudioRecord 的代码在 framework\base\media\java\android\media\AudioRecord.java 中

Java 类 AudioRecord 使用流程如下:首先创建一个 AudioRecord 实例和一个录音缓冲区;接下来就可以调用 startRecording()开始录音,然后调用 read()不停地读取音频数据到缓冲区;最后, 调用  stop()停止录音, 调用 release()释放资源。

录音时,Java 应用程序调用 Java 类 AudioRecord 提供接口, Java 类AudioRecord 本身并不直接处理音频数据,而是通过 JNI 调用本地框架层中 C++类 AudioRecord 提供的接口,然后再通过 Binder 机制跨进程进一步调用AudioFlinger。具体调用流程如图 5-4 所示: 

4.AudioFlinger

AudioFlinger 是 Android 音频系统的一个重量级服务,向下访问 Audio 硬件抽象层,向上通过 IAudioFlinger 接口提供服务,起着承上启下的重要作用。AudioFlinger 在 frameworks/base/media/mediaserver/main_mediaserver.cpp 中被创建实例化,相关代码在 frameworks/base/libs/audioflinger 中。其中, AudioFlinger.h和 AudioFlinger.cpp 是 AudioFlinger 的核心文件,提供了类 AudioFlinger,这个类是一个 IAudioFlinger 的具体实现。

AudioFlinger 实现音频的统一管理,主要提供 createTrack ,openRecord,openOutput,openInput 等方法。createTrack()创建回放音轨 Track,openRecord()创建录音音轨 RecordTrack , openOutput() 打 开 Audio 硬件输出流并创建MixerThread 或 DirectoutputThread,openInput()打开 Audio 硬件输入流并创建RecordThread。

 

 

AudioService setMode源码分析 audio system_Audio_05

5.AudioPolicyService和AudioPolicyManager

AudioPolicyService 是 Android 音频系统的另一个重量级服务,在frameworks/base/media/mediaserver/main_mediaserver.cpp 中 被创建 实例 化 。AudioPolicyService 继承了 IAudioPolicyService 接口,Java 应用层可通过 JNI 并经由 IAudioPolicyService 接口,访问 AudioPolicyService 提供的服务。

AudioPolicyService 主要提供以下服务:

1、输入输出设备的连接状态的获取和设置。

2、音频策略(strategy)的获取。

3、音量调节,音频参数设置。

4、音频模式设置,铃声模式设置。