一、Kernel层
音频由于其特殊的工作,使得它的结构特别的复杂,而且在自己的结构基础上还引入了ALSA架构,不过在android系统上所引入的并非完整的ALSA架构而是精简版的tinyalsa,但是就算精简版也是内容相当丰厚。
除此,音频还拥有自己的单独的处理器ADSP以及独立的电源管理系统DAPM(便携式动态音频电源管理),使得音频在任何时候都是以最低功耗运行,降低了便携设备的功耗。
在某些播放场景甚至不需要CPU的介入,比如接打电话的通过音频,如果手机处于休眠可以不需要唤醒CPU直接传递语音数据。要想知道整个过程中音频数据的流转需要一步步去了解,音频架构中所涉及到的各个部分,缺一环则不可,先看看ALSA架构。
二、 ALSA
Advanced Linux Sound Architecture 高级Linux音频架构,对于android系统来说其实用的只是一个精简版的ALSA架构,有一部分ALSA的接口是放在用户空间,供上层调用来接通kernel
根据音频数据的流向再把音频内核分为以下三个层次:
- tinyAlsa
- ALSA Core
- ASoC
2.1 Tinyalsa
ALSA lib的源码地址在:external/tinyalsa目录下,其中包含:tinyplay/tinycap/tinymix,这些是供用户空间之间调用的alsa接口,用来播放、录音及控制。并且它们的代码非常的简单,其主要功能是解耦,方便调试,这里不做过多赘述。
2.2 ALSA CORE
ASLA核心他的主要代码是在kernel/msm-x.xx/sound/core,alsa 核心层,向上提供逻辑设备(PCM / CTL / MIDI / TIMER /…)系统调用,向下驱动硬件设备( Machine / I2S / DMA / CODEC )
2.3 ASoc
ASoc(ALSA system on chip) 是建立在标准 alsa core 基础上,为了更好支持嵌入式系统和应用于移动设备的音频 codec 的一套软件体系。主要代码存在于:vendor/qcom/opensource/audio-kernel,kernel/msm-x.xx/sound
ASoC被分为Machine、Platform和Codec三大部分。
其中的Machine驱动负责Platform和Codec之间的耦合和设备或板子特定的代码。
Platform驱动 的主要作用是完成音频数据的管理,最终通过CPU的数字音频接口(DAI)把音频数据传送给Codec进行处理,最终由Codec输出驱动耳机或者是喇叭的音信信号。
-
Machine
-
用于描述设备组件信息和特定的控制如耳机/外放等。
-
Machine是指某一款机器,可以是某款设备,某款开发板,又或者是某款智能手机,由此可以看出Machine几乎是不可重用的,每个Machine上的硬件实现可能都不一样,CPU不一样,Codec不一样,音频的输入、输出设备也不一样,Machine为CPU、Codec、输入输出设备提供了一个载体。
-
Machine 这一部分将平台驱动和 Codec 驱动绑定在一起,描述了板级的硬件特征。
主要负责 Platform 和 Codec 之间的耦合以及部分和设备或板子特定的代码。
Machine驱动负责处理机器特有的一些控件和音频事件(例如,当播放音频时,需要先行打开一个放大器); -
单独的 Platform 和 Codec 驱动是不能工作的,它必须由 Machine 驱动把它们结合在一起才能完成整个设备的音频处理工作。
-
ASoC 的一切都从 Machine 驱动开始,包括声卡的注册,绑定 Platform 和 Codec 驱动等等。
-
-
Platform
-
用于实现平台相关的DMA驱动和音频接口等。
-
Platform 一般是指某一个SoC平台,比如 pxaxxx,s3cxxxx,omapxxx 等等,与音频相关的通常包含该 SoC 中的时钟、DMA、I2S、PCM等等,只要指定了 SoC,那么我们可以认为它会有一个对应的 Platform,它只与 SoC 相关,与 Machine 无关,这样我们就可以把 Platform 抽象出来,使得同一款 SoC 不用做任何的改动,就可以用在不同的 Machine 中。实际上,把 Platform 认为是某个 SoC 更好理解。
-
这一部分只关心CPU本身,不关心Codec。
-
主要处理两个问题:DMA引擎 和 SoC集成的PCM、I2S或AC ‘97数字接口控制。
主要作用是完成音频数据的管理,最终通过CPU的数字音频接口(DAI)把音频数据传送给Codec进行处理,最终由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进行交互。
-
-
Codec
-
用于实现平台无关的功能,如寄存器读写接口,音频接口,各widgets的控制接口和DAPM的实现等。
-
字面上的意思就是编解码器,Codec里面包含了I2S接口、D/A、A/D、Mixer、PA(功放),通常包含多种输入(Mic、Line-in、I2S、PCM)和 多个输出(耳机、喇叭、听筒,Line-out),Codec和Platform一样,是可重用的部件,同一个 Codec 可以被不同的Machine使用。嵌入式 Codec 通常通过I2C对内部的寄存器进行控制。
-
这一部分只关心 Codec 本身,与 CPU 平台相关的特性不由此部分操作。
-
在移动设备中,Codec 的作用可以归结为4种,分别是:
- 对 PCM 等信号进行 D/A 转换,把数字的音频信号转换为模拟信号。
- 对Mic、Linein或者其他输入源的模拟信号进行A/D转换,把模拟的声音信号转变CPU能够处理的数字信号。
- 对音频通路进行控制,比如播放音乐,收听调频收音机,又或者接听电话时,音频信号在codec内的流通路线是不一样的。
- 对音频信号做出相应的处理,例如音量控制,功率放大,EQ控制等等。
- ASoC 对 Codec 的这些功能都定义好了一些列相应的接口,以方便地对Codec进行控制。
ASoC 对 Codec 驱动的一个基本要求是:驱动程序的代码必须要做到平台无关性,以方便同一个 Codec 的代码不经修改即可用在不同的平台上。
-
-
DAPM
-
DAPM是Dynamic Audio Power Management的缩写,直译过来就是动态音频电源管理的意思,
-
DAPM是为了使基于linux的移动设备上的音频子系统,在任何时候都工作在最小功耗状态下。
DAPM对用户空间的应用程序来说是透明的,所有与电源相关的开关都在ASoc core中完成。
用户空间的应用程序无需对代码做出修改,也无需重新编译,DAPM根据当前激活的音频流(playback/capture)和声卡中的mixer等的配置来决定那些音频控件的电源开关被打开或关闭。 -
DPCM :Dynamic PCM
-
ASoC对于Alsa来说,就是分别注册PCM/CONTROL类型的snd_device设备,并实现相应的操作方法集。
图中DAI是数字音频接口,用于配置音频数据格式等。
- ☁ Codec 驱动 向 ASoC 注册 snd_soc_codec 和 snd_soc_dai 设备。
- ☁ Platform 驱动 向 ASoC 注册 snd_soc_platform 和 snd_soc_dai 设备。
- ☁ Machine 驱动通过 snd_soc_dai_link 绑定 codec / dai / platform 。
Widget是各个组件内部的小单元。处在活动通路上电,不在活动通路下电。ASoC的DAPM正是通过控制这些Widget的上下电达到动态电源管理的效果。
- ☁ path描述与其它widget的连接关系。
- ☁ event用于通知该widget的上下电状态。
- ☁ power指示当前的上电状态。
- ☁ control实现空间用户接口用于控制widget的音量/通路切换等。
以上的内容可以对ALSA有个简单的了解,如果想要更深入的了解需要自行查找相关资料学习。那么我们知道了音频内核的组成,众所周知一台机器要想发出声音需要有声卡才行,声卡是我们音频中的核心,既然如此重要那么声卡和上面说的machine、platform和codec它们几者的关系如何呢?它们又是怎样开始工作的呢?接下来就来探究一下声卡的注册流程
只是好奇了解一下这个框架,具体详细的内容,大家可以访问原文链接:https://blog.csdn.net/wh2526422/article/details/126247382