1.3 Audio系统和上层接口
在Android中〃Audio系统自上而下由Java的Audio类、Audio本地框架类、
AudioFlinger和Audio的硬件抽象层几个部分组成。
1.3.1 Audio系统的各个层次
Audio本地框架类是libmedia.so的一个部分〃这些Audio接口对上层提供接口〃由下层的本地代码去实现。 AudioFlinger继承libmeida中的接口〃提供实现库libaudiofilnger.so。这部分内容没有自己的对外头文件〃上层调用的只是libmedia本部分的接口〃但实际调用的内容是libaudioflinger.so。 Audio使用JNI和Java对上层提供接口〃JNI部分通过调用libmedia库提供的接口来实现。 Audio的硬件抽象层提供到硬件的接口〃供AudioFlinger调用。Audio的硬件抽象层实际上是各个平台开发过程中需要主要关注和独立完成的部分。 表 1-1 Android Audio各个层次的对应关系 Audio管理环节 Audio输出 Audio输入 在各个层次之间具有对应关系〃如表1-1所示所示。 Java层 android.media.Audioandroid.media.Audandroid.media.AudioRSystem ioTrack ecorder 本地框架层 AudioSystem AudioTrack AudioRecorder AudioFlIAudioFlinger IAudioTrack IAudioRecorder
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 6 of 33
inger 硬件抽AudioHardwareInter象层 face AudioStreamOut AudioStreamIn 1.3.2 media库中的Audio框架部分
Android的Audio系统的核心框架在media库中提供〃对上面主要实现AudioSystem、AudioTrack和AudioRecorder三个类。
提供了IAudioFlinger类接口〃在这个类中〃可以获得IAudioTrack和IAudioRecorder两个接口〃分别用于声音的播放和录制。AudioTrack和AudioRecorder分别通过调用IAudioTrack和IAudioRecorder来实现。
Audio系统的头文件在frameworks/base/include/media/目录中〃主要的头文件如下: AudioSystem.h:media库的Audio部分对上层的总管接口; IAudioFlinger.h:需要下层实现的总管接口; AudioTrack.h:放音部分对上接口;
IAudioTrack.h:放音部分需要下层实现的接口; AudioRecorder.h:录音部分对上接口;
IaudioRecorder.h:录音部分需要下层实现的接口。
IAudioFlinger.h、IAudioTrack.h和IAudioRecorder.h这三个接口通过下层的继承来实现(即AudioFlinger)。AudioFlinger.h、AudioTrack.h和AudioRecorder.h是对上层提供的接口〃它们既供本地程序调用(例如声音的播放器、录制器等)〃也可以通过JNI向Java层提供接口。
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 7 of 33
meida库中Audio部分的结构如图1-2所示。
从功能上看〃AudioSystem负责的是Audio系统的综合管理功能〃而AudioTrack
和AudioRecorder分别负责音频数据的输出和输入〃即播放和录制。
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 8 of 33
AudioSystem.h中主要定义了一些枚举值和set/get等一系列接口;在Audio系统
的几个枚举值中〃audio_routes是由单独的位来表示的〃而不是由顺序的枚举值表示〃因此这个值在使用过程中可以使用\或\的方式。例如〃表示声音可以既从耳机(EARPIECE)输出〃也从扬声器(SPEAKER)输出〃这样是否能实现〃由下层提供支持。在这个类中〃set/get等接口控制的也是相关的内容〃例如Audio声音的大小、Audio的模式、路径等。 AudioTrack是Audio输出环节的类〃其中最重要的接口是write(); AudioRecord是Audio输入环节的类〃其中最重要的接口为read()
AudioTrack和AudioRecord的read/write函数的参数都是内存的指针及其大小〃
内存中的内容一般表示的是Audio的原始数据(PCM数据)。这两个类还涉及Auido数据格式、通道数、帧数目等参数〃可以在建立时指定〃也可以在建立之后使用set()函数进行设置。
在libmedia库中提供的只是一个Audio系统框架〃AudioSystem、AudioTrack和
AudioRecord分别调用下层的IAudioFlinger、IAudioTrack和IAudioRecord来实现。另外的一个接口是IAudioFlingerClient〃它作为向IAudioFlinger中注册的监听器〃相当于使用回调函数获取 IAudioFlinger运行时信息。
1.3.3 AudioFlinger本地代码
AudioFlinger是Audio系统的中间层〃在系统中起到服务作用〃它主要作为
libmedia提供的Audio部分接口的实现〃其代码路径为:frameworks/base/libs/audioflinger
AudioFlinger的核心文件是AudioFlinger.h和AudioFlinger.cpp〃提供了类
AudioFlinger〃这个类是一个IAudioFlinger的实现
AudioFlinger主要提供createTrack()创建音频的输出设备IAudioTrack〃
openRecord()创建音频的输入设备IAudioRecord。另外包含的就是一个get/set接口〃用于控制。
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 9 of 33
从工作的角度看〃AudioFlinger在初始化之后〃首先获得放音设备〃然后为混音器
(Mixer)建立线程〃接着建立放音设备线程〃在线程中获得放音设备。
在AudioFlinger的AudioResampler.h中定义了一个音频重取样器工具类〃这个音
频重取样工具包含3种质量:低等质量(LOW_QUALITY)将使用线性差值算法实现;中等质量(MED_QUALITY)将使用立方差值算法实现;高等质量(HIGH_ QUALITY)将使用FIR(有限阶滤波器)实现。AudioResampler中的AudioResamplerOrder1是线性实现〃AudioResamplerCubic.*文件提供立方实现方式〃AudioResamplerSinc.*提供FIR实现。
AudioMixer.h和AudioMixer.cpp中实现的是一个Audio系统混音器〃它被
AudioFlinger调用〃一般用于在声音输出之前的处理〃提供多通道处理、声音缩放、重取样。AudioMixer调用了AudioResampler。
1.3.4 Audio系统的JNI代码
Android的Audio部分通过JNI向Java层提供接口〃在Java层可以通过JNI接口完成Audio系统的大部分操作。Audio JNI部分的代码路径为:frameworks/base/core/jni。 其中〃主要实现的3个文件为:android_media_AudioSystem.cpp、
android_media_Audio Track.cpp和android_media_AudioRecord.cpp〃它们分别对应了Android Java框架中的3个类的支持:
android.media.AudioSystem:负责Audio系统的总体控制; android.media.AudioTrack:负责Audio系统的输出环节; android.media.AudioRecorder:负责Audio系统的输入环节。
在Android的Java层中〃可以对Audio系统进行控制和数据流操作〃对于控制操作〃和底层的处理基本一致;但是对于数据流操作〃由于Java不支持指针〃因此接口被封装成了另外的形式。
ArcherMind Inc. Proprietary – For Internal Use Only
CONFIDENTIAL Date
Page 10 of 33