Android 14音频系统之音频框架分析
一、资料快车
1、Android音频系统
1)https://blog.csdn.net/xuesen_lin/article/details/8796492
2)https://blog.csdn.net/yangwen123/article/details/39502689
2、书籍 - Android系统源代码情景分析
二、Perface
1、参考:
2、系统程序分析方法
1)加入log,并跟着log一步步分析 -logcat;
2)利用ChatGPT提供基础概念解析 & 代码解析 & 设计原理;
3、目标
1)提供查阅代码的线索、思路;
2)能够根据日志进行快读的代码分析;
3)区分代码层次,为定制系统提供思路;
4)站在前人的肩膀上进一步探究;
4、action
务必根据本文提供的线索 去看源代码。
带着疑问去了解
1、音频系统的数据如何处理,编解码需要了解认识?
2、结合当前的调试和对Android系统的了解,以音频系统作为实践;
1)编译结构如何?
2)各种结构体如何梳理?
3)如何处理实际问题?
4)将各个新的知识点一一记录!
4、面对如此庞大的代码,如何消化?
1)如果一直停留在框架,过一会就忘,实际操作起来也很困难;
2)掌握宏观(学习目标),微观慢慢填充积累(调试)
1、基本术语、物理架构
2、应该掌握各层级代码目录、生成物(编译) 、每一个层级掌握入口和出口、层级间的跳转过程-> 可以帮助在项目中快速锁定工作层级;-> 此时再定位在某个文件/逻辑链路上(再去了解细节也不迟,如何加快?在平时阅读代码,尽可能地熟悉语句 扫盲);
三、代码目录
所在层次 | 名称 | 代码路径 |
---|---|---|
Application | 应用(调用系统库,实现用户逻辑) | 实现android中对应的类及方法MediaPlayer、MediaRecorder、AudioTrack、AudioRecorder |
framework | android (此部分链接到应用) | Framework.jar //import android.media.* android/frameworks/base/media/java/android/media |
service (系统服务) | Framework java服务 android/frameworks/base/services/java/com/android/server/SystemServer.java android/frameworks/base/services/core/java/com/android/server/audio | |
JNI(过渡到native) | Android层的JNI,Audio的JNI是其中的一个部分 android/frameworks/base/core/jni //libandroid_runtime.so | |
NDK | android/frameworks/av/media 一、libmedia //java层通过此lib调用native层的audioserver进程 android/frameworks/av/media/libmedia 二、audioserver进程 android/frameworks/av/media/audioserver android/frameworks/av/services/audioflinger //libaudioflinger.so android/frameworks/av/services/audiopolicy/service //libaudiopolicyservice.so | |
hal | android\hardware\libhardware_legacy | |
kernel | Sound子系统(alsa) | android\kernel\fusion\4.19\sound* |
四、系统框架
1、术语概念
1、
音频格式三要素:rate(48khz)、channel(5.1)、bit(8/16bit)
设备种类:蓝牙、喇叭、带麦克风耳机、耳机等等
厂商一般都封装音频驱动,不开放!2、
retention 保留接口
glitch 故障
benchmark : 基准测试程序
2、整体框架图
1)粗略框图
左边是传统linux视图,右图Android将User这一层再细分成4层(目的是实现向上提供便利,向下保持兼容)
2)详细框图
1、关键点说明
1、framework层的MediaPlayer/MediaPlayerService内部实现依赖 AudioTrack(播放)、AudioRecorder(录音),这些类的设计都是framework为便利上层应用开发所设计的,以AudioTrack/AudioRecorder为主线进行分析即可
2、Native层的AudioFlinger管理着系统中的输入输出音频流,并承担着音频数据的混合,通过读写Audio硬件实现音频数据的输入输出功能;AudioPolicyService是Audio系统的策略控制中心,掌管系统中声音设备的选择和切换、音量控制等。AudioFlinger和AudioPolicyService是系统层最重要的逻辑实现。
3、音频系统的HAL层,相较于其它子系统,需要考虑更多
1)对接Tinyalsa(早期是ALSA-lib);
2)音频设备存在很大的差异;
3)由于Android更新相当频繁,需要设计统一的接口(audio_hw_device、audio_stream_out、audio_stream_in);
3、tinyalsa是linux开源库,目的是方便开发者操作Audio driver
4、Tinyalsa->Audio driver ->Audio devices 为 linux簇系统统一的音频通路;
3)从类的角度来看音频框架
层级调用关系:
后续分析对应层级时再体现细节
4)从文件分布上来看音频框架
Android的硬件抽象层
1)厂商提供的hal库
是各个平台开发过程中主要关注和独立完成的部分,框架类的由Android google团队来维护和迭代
厂商提供的HAL库:audio.a2dp.default.so、audio.primary.default.so、audio.usb.default.so
,分别驱动蓝牙a2dp设备、主音频系统、usb音频设备,对应的配置文件为audio_policy.conf
2)audio_policy.conf
audio_policy.conf
一个简单的例子如下
a2dp { //称为Module 或 HwModuleoutputs {a2dp {sampling_rates 44100|48000channel_masks AUDIO_CHANNEL_OUT_STEREOformats AUDIO_FORMAT_PCM_16_BITdevices AUDIO_DEVICE_OUT_ALL_A2DP}}# a2dp sinkinputs {a2dp {sampling_rates 44100channel_masks AUDIO_CHANNEL_IN_STEREOformats AUDIO_FORMAT_PCM_16_BITdevices AUDIO_DEVICE_IN_BLUETOOTH_A2DP}}
}module 一般指一个厂商提供的一个库(可以理解为一个音频系统下的子系统!),AudiopolicyService会根据这个字段找到对应的库(格式audio."module".default.so,比如audio.a2dp.default.so,那还不如直接写库的名称更为直接!),module一般包含一个output和input,也就是这个库所驱动的外设,output/input设备就比较多种多样了。
为何这样分类设计?从产品端理解设计初衷:
5)notes
1、java层很少算法操作,大多数都是逻辑(if-else)处理,封装native的操作,方便上层调用;
2、调用/回调 的含义:比如java->cpp、cpp->java (接口名一般为 callback、notify);
3、Android系统更新十分频繁!