一、Android 13音频代码结构
1、framework:
android/frameworks/base
1.AudioManager.java :音频管理器,音量调节、音量UI、设置和获取参数等控制流的对外API
2.AudioService.java :音频系统服务(java层),音量调节、音量UI、音频设备插拔等控制流的具体实现
3.AudioSystem.java :音频控制的入口,是native层对上服务的接口
android/frameworks/av
1.AudioFlinger.cpp :音频系统的核心一,承担音频数据流AudioTrack和AudioRecord的混音、重采、输送等责任
2.AudioPolicyService.cpp :音频系统的核心二,负责音频策略,包含Audio HAL的加载,音频路由的选择等
2、HAL
android/hardware/aw/audio/ :AudioFlinger与音频驱动之间的对接层,匹配android系统与硬件的关键层
3、整体框图
其中运行在AudioServer进程中的AudioFlinger和AudioPolicyService,以及运行在SystemServer进程中的AudioService这三个模块是Android音频子系统的核心
(1)播放
通过C++类AudioTrack将音频数据写入AudioTrack和AudioFlinger都能访问的共享内存中,该共享内存由audio_track_cblk_t管理。AudioFlinger在接收到数据后,调过自己的播放线程输出
(2)录音:
硬件设备采集PCM数据,AudioFlinger使用AudioStreamIn将数据读取到共享内存,AudioRecord则从共享内存中在读取这些数据。
HAL----->AudioFlinger------->共享内存------>AudioRecord
二、ASoC音频驱动构成
1、ASoC音频驱动由三部分构成:platform,codec,machine
(1)Machine :
单独的 Platform 和 Codec 驱动是不能工作的,它必须由 Machine 驱动把它们结合在一起才能完成整个设备的音频处理工作。
Machine :可以理解为对开发板的抽象,开发板可能包括多个声卡,对应Machine部分包含多个link。
dai_link:machine驱动中定义的音频数据链路,它指定用到的cpu_dai、codec_dai
(2)Platform:
它包含了该 SoC 平台的音频 DMA 和音频接口的配置和控制(I2S,PCM 等等);一般不包含与板子或 codec 相关的代码。
在具体实现上,ASoC又把Platform驱动分为两个部分:snd_soc_platform_driver和snd_soc_dai_driver。其中,platform_driver负责管理音频数据,把音频数据通过dma或其他操作传送至cpu dai中,dai_driver则主要完成cpu一侧的dai的参数配置,同时也会通过一定的途径把必要的dma等参数与snd_soc_platform_driver进行交互。
cpu dai:在嵌入式系统里面通常指CPU的I2S、PCM总线控制器,负责将音频数据从I2S tx FIFO搬运到CODEC(回放的情形,录制则方向相反)。cpu_dai通过snd_soc_register_dai()来注册。
(3)Codec:
它包含了一些音频的控件 (Controls),音频接口,DAMP(动态音频电源管理)的定义和某些 Codec IO 功能。为了 保证硬件无关性,任何特定于平台和机器的代码都要移到 Platform 和 Machine 驱动中。
2、PCM数据流
回放
录音
3、ASoC音频驱动注册流程
主要步骤为下述部分:
4、 ALSA设备文件结构
contro1C0 ------> 用于声卡的控制,例如通道选择,混音,麦克风的控制等。pcmC0D0c ------> 用于录音的pcm设备pcmC0D0p ------> 用于播放的pcm设备seq ------> 音序器timer ------> 定时器
其中,C0D0代表的是声卡0中的设备0,pcmC0D0c最后一个c代表capture,pcmC0D0p最后一个p代表playback,这些都是alsa-driver中的命名规则。