(一)Linux ALSA 音频系统:物理链路篇

article/2025/6/10 10:03:26

物理链路篇

转自:https://me.csdn.net/zyuanyun

Linux ALSA 音频系统:物理链路篇

Linux ALSA 音频系统:物理链路篇

1. Overview

硬件平台及软件版本:

  • Kernel - 3.4.5
  • SoC - Samsung exynos
  • CODEC - WM8994
  • Machine - goni_wm8994
  • Userspace - tinyalsa

Linux ALSA 音频系统架构大致如下:

              +--------+  +--------+  +--------+|tinyplay|  |tinycap |  |tinymix |+--------+  +--------+  +--------+|           ^           ^ V           |           V+--------------------------------+|        ALSA Library API        ||      (tinyalsa, alsa-lib)      |+--------------------------------+user space                   ^
-------------------------------|---------------------kernel space                 V+--------------------------------+|           ALSA CORE            || +-------+ +-------+ +------+   || |  PCM  | |CONTROL| | MIDI |...|| +-------+ +-------+ +------+   |+--------------------------------+|+--------------------------------+|           ASoC CORE            |+--------------------------------+|+--------------------------------+|        hardware driver         ||  +-------+ +--------+ +-----+  ||  |Machine| |Platform| |Codec|  ||  +-------+ +--------+ +-----+  |+--------------------------------+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • Native ALSA Application:tinyplay/tinycap/tinymix,这些用户程序直接调用 alsa 用户库接口来实现放音、录音、控制
  • ALSA Library API:alsa 用户库接口,常见有 tinyalsa、alsa-lib
  • ALSA CORE:alsa 核心层,向上提供逻辑设备(PCM/CTL/MIDI/TIMER/…)系统调用,向下驱动硬件设备(Machine/I2S/DMA/CODEC)
  • ASoC CORE:asoc 是建立在标准 alsa core 基础上,为了更好支持嵌入式系统和应用于移动设备的音频 codec 的一套软件体系
  • Hardware Driver:音频硬件设备驱动,由三大部分组成,分别是 Machine、Platform、Codec

本主题不遵循自顶而下的原则,而先从硬件设备驱动说起,毕竟这些是看得见摸得着听得到的东西,容易对其有着直观的理解。

//
// 声明:本文由 http://blog.csdn.net/zyuanyun 原创,转载请注明出处,谢谢!
//

ALSA/ASoC 中硬件设备关系:

+------------------------------------------+
|                 Machine                  |
|  +--------------+      +--------------+  |
|  |   Platform   |      |     Codec    |  |
|  |              | I2S  |              |  |
|  |       cpu_dai|<---->|codec_dai     |  |
|  |              |      |              |  |
|  +--------------+      +--------------+  |
+------------------------------------------+
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • Platform:指某款 SoC 平台的音频模块,如 exynos、omap、qcom 等等。Platform 又可细分两部分:

    • cpu dai:在嵌入式系统里面通常指 SoC 的 I2S、PCM 总线控制器,负责把音频数据从 I2S tx FIFO 搬运到 CODEC(这是回放的情形,录制则方向相反)。cpu_dai 通过 snd_soc_register_dai() 来注册。注:DAI 是 Digital Audio Interface 的简称,分为 cpu_dai 和 codec_dai,这两者通过 I2S/PCM 总线连接;AIF 是 Audio Interface 的简称,嵌入式系统中一般是 I2S 和 PCM 接口。
    • pcm dma:负责把 dma buffer 中的音频数据搬运到 I2S tx FIFO。值得留意的是:某些情形下是不需要 dma 操作的,比如 Modem 和 CODEC 直连,因为 Modem 本身已经把数据送到 FIFO 了,这时只需启动 codec_dai 接收数据即可;该情形下,Machine 驱动 dai_link 中需要设定 .platform_name = "snd-soc-dummy", 这是虚拟 dma 驱动,实现见 sound/soc/soc-utils.c。音频 dma 驱动通过 snd_soc_register_platform() 来注册,故也常用 platform 来指代音频 dma 驱动(这里的 platform 需要与 SoC Platform 区分开)。
  • Codec:对于回放来说,userspace 送过来的音频数据是经过采样量化的数字信号,在 codec 经过 DAC 转换成模拟信号然后输出到外放或耳机,这样我们就可以听到声音了。Codec 字面意思是编解码器,但芯片里面的功能部件很多,常见的有 AIF、DAC、ADC、Mixer、PGA、Line-in、Line-out,有些高端的 codec 芯片还有 EQ、DSP、SRC、DRC、AGC、Echo-Canceller、Noise-Suppression 等部件。

  • Machine:指某款机器,通过配置 dai_link 把 cpu_dai、codec_dai、modem_dai 各个音频接口给链结成一条条音频链路,然后注册 snd_soc_card。和上面两个不一样,Platform 和 CODEC 驱动一般是可以重用的,而 Machine 有它特定的硬件特性,几乎是不可重用的。所谓的硬件特性指:SoC Platform 与 Codec 的差异;DAIs 之间的链结方式;通过某个 GPIO 打开 Amplifier;通过某个 GPIO 检测耳机插拔;使用某个时钟如 MCLK/External-OSC 作为 I2S、CODEC 的时钟源等等。

从上面的描述来看,对于回放的情形,PCM 数据流向大致是:

        copy_from_user           DMA                 I2S           DAC^                   ^                   ^             ^
+---------+   |    +----------+   |   +-----------+   |   +-----+   |   +------+
|userspace+-------->DMA Buffer+------->I2S TX FIFO+------->CODEC+------->SPK/HP|
+---------+        +----------+       +-----------+       +-----+       +------+
  • 1
  • 2
  • 3
  • 4
  • 5

几个音频物理链路的概念:

dai_link:machine 驱动中定义的音频数据链路,它指定链路用到的 codec、codec_dai、cpu_dai、platform。比如对于 goni_wm8994 平台的 media 链路:codec="wm8994-codec"、codec_dai="wm8994-aif1"、cpu_dai="samsung-i2s"、platform="samsung-audio",这四者就构成了一条音频数据链路用于多媒体声音的回放和录制。一个系统可能有多个音频数据链路,比如 media 和 voice,因此可以定义多个 dai_link 。如 WM8994 的典型设计,有三个 dai_link,分别是 AP<>AIF1 的 “HIFI”(多媒体声音链路),BP<>AIF2 的 “Voice”(通话语音链路),以及 BT<>AIF3(蓝牙 SCO 语音链路)。

WM8994 Typical AIF Connections

代码如下:

static struct snd_soc_dai_link goni_dai[] = {
{.name = "WM8994",.stream_name = "WM8994 HiFi",.cpu_dai_name = "samsung-i2s.0",.codec_dai_name = "wm8994-aif1",.platform_name = "samsung-audio",.codec_name = "wm8994-codec.0-001a",.init = goni_wm8994_init,.ops = &goni_hifi_ops,
}, {.name = "WM8994 Voice",.stream_name = "Voice",.cpu_dai_name = "goni-voice-dai",.codec_dai_name = "wm8994-aif2",.codec_name = "wm8994-codec.0-001a",.ops = &goni_voice_ops,
},
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

hw constraints:指平台本身的硬件限制,如所能支持的通道数/采样率/数据格式、DMA 支持的数据周期大小(period size)、周期次数(period count)等,通过 snd_pcm_hardware 结构体描述:

static const struct snd_pcm_hardware dma_hardware = {.info           = SNDRV_PCM_INFO_INTERLEAVED |SNDRV_PCM_INFO_BLOCK_TRANSFER |SNDRV_PCM_INFO_MMAP |SNDRV_PCM_INFO_MMAP_VALID |SNDRV_PCM_INFO_PAUSE |SNDRV_PCM_INFO_RESUME,.formats        = SNDRV_PCM_FMTBIT_S16_LE |SNDRV_PCM_FMTBIT_U16_LE |SNDRV_PCM_FMTBIT_U8 |SNDRV_PCM_FMTBIT_S8,.channels_min       = 2,.channels_max       = 2,.buffer_bytes_max   = 128*1024,.period_bytes_min   = PAGE_SIZE,.period_bytes_max   = PAGE_SIZE*2,.periods_min        = 2,.periods_max        = 128,.fifo_size      = 32,
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

hw params:用户层设置的硬件参数,如 channels、sample rate、pcm format、period size、period count;这些参数受 hw constraints 约束。

sw params:用户层设置的软件参数,如 start threshold、stop threshold、silence threshold。

2. ASoC

ASoC:ALSA System on Chip,是建立在标准 ALSA 驱动之上,为了更好支持嵌入式系统和应用于移动设备的音频 codec 的一套软件体系,它依赖于标准 ALSA 驱动框架。内核文档 Documentation/alsa/soc/overview.txt 中详细介绍了 ASoC 的设计初衷,这里不一一引用,简单陈述如下:

  • 独立的 codec 驱动,标准的 ALSA 驱动框架里面 codec 驱动往往与 SoC/CPU 耦合过于紧密,不利于在多样化的平台/机器上移植复用
  • 方便 codec 与 SoC 通过 PCM/I2S 总线建立链接
  • 动态音频电源管理 DAPM,使得 codec 任何时候都工作在最低功耗状态,同时负责音频路由的创建
  • POPs 和 click 音抑制弱化处理,在 ASoC 中通过正确的音频部件上下电次序来实现
  • Machine 驱动的特定控制,比如耳机、麦克风的插拔检测,外放功放的开关

在概述中已经介绍了 ASoC 硬件设备驱动的三大构成:Codec、Platform 和 Machine,下面列举各驱动的功能构成:

ASoC Codec Driver

  • Codec DAI 和 PCM 的配置信息
  • Codec 的控制接口,如 I2C/SPI
  • Mixer 和其他音频控件
  • Codec 的音频接口函数,见 snd_soc_dai_ops 结构体定义
  • DAPM 描述信息
  • DAPM 事件处理句柄
  • DAC 数字静音控制

ASoC Platform Driver: 包括 dma 和 cpu_dai 两部分:

  • dma 驱动实现音频 dma 操作,具体见 snd_pcm_ops 结构体定义
  • cpu_dai 驱动实现音频数字接口控制器的描述和配置

ASoC Machine Driver

  • 作为链结 Platform 和 Codec 的载体,它必须配置 dai_link 为音频数据链路指定 Platform 和 Codec
  • 处理机器特有的音频控件和音频事件,例如回放时打开外放功放

硬件设备驱动相关结构体:

  • snd_soc_codec_driver:音频编解码芯片描述及操作函数,如控件/微件/音频路由的描述信息、时钟配置、IO 控制等
  • snd_soc_dai_driver:音频数据接口描述及操作函数,根据 codec 端和 soc 端,分为 codec_dai 和 cpu_dai
  • snd_soc_platform_driver:音频 dma 设备描述及操作函数
  • snd_soc_dai_link:音频链路描述及板级操作函数

下面是 goni_wm8994 类图,从这个类图中,我们可以大致了解 goni_wm8994 整个音频驱动组成:

ASoC_goni_wm8994

3. Codec

上一章提到 codec_drv 的几个组成部分,下面逐一介绍,基本是以内核文档 Documentation/sound/alsa/soc/codec.txt 中的内容为脉络来分析的。Codec 的作用,之前已有描述,本章主要罗列下 Codec driver 中重要的数据结构及注册流程。

我们先看看 Codec 的硬件框图,以 WM8994 为例:

WM8994 Block Diagram

其中有着各种功能部件,包括但不限于 :


http://chatgpt.dhexx.cn/article/fZekDRLA.shtml

相关文章

Android 中的混音器 AudioMixer 实现分析

Android framework 的音频处理模库 libaudioprocessing (位于 frameworks/av/media/libaudioprocessing) 提供了混音器组件 AudioMixer&#xff0c;它主要用在 audioflinger 里&#xff0c;用来将多路音频源数据混音&#xff0c;以方便送进音频设备播放出来。 音频混音操作本身…

JRTPLIB@Conference DIY视频会议系统

------------------------------------------------------------------------------------------------------------------------------ JRTPLIBConference DIY视频会议系统 一、开编 转自 http://wmnmtm.blog.163.com/blog/static/382457142011540719318/?suggestedreadin…

2003-2005上午试题分章别类(下)

第六章 多媒体基础知识 2005.11 ●___(57)___标准中定义了MP3音乐标准。供选择的答案&#xff1a;(57)A.JPEG     B.MPEG-1      C.MPEG-2     D.MPEG-3试题分析&#xff1a;MPEG-1&#xff1a;为数字存储媒体在1.5M比特/s的比特率对运动图象和关联的音频进行编码…

[转]AAC的各种规格

一、规格(profile)问题&#xff1a; wiki上说到&#xff0c;AAC共有9种规格&#xff0c;以适应不同的场合的需要&#xff1a; l MPEG-2 AAC LC 低复杂度规格&#xff08;Low Complexity&#xff09;--比较简单&#xff0c;没有增益控制&#xff0c;但提高了编码效率&am…

aac

Hi&#xff0c;又来写点儿小记录心得吧&#xff0c;这次是在准备AAC音频解码的规格中发现和总结出的一些问题&#xff0c;大概的情况在这里简要做一小记&#xff0c;为我们最后确立规格提供参考&#xff0c;当然我对AAC规格的了解还很稚嫩&#xff0c;有些表述不太确切的地方&a…

AAC的各种规格

Hi&#xff0c;又来写点儿小记录心得吧&#xff0c;这次是在准备AAC音频解码的规格中发现和总结出的一些问题&#xff0c;大概的情况在这里简要做一小记&#xff0c;为我们最后确立规格提供参考&#xff0c;当然我对AAC规格的了解还很稚嫩&#xff0c;有些表述不太确切的地方&a…

Android Audio混音实践篇

Android Audio混音实践篇 简介 本篇文章主要介绍Android Audio模块的MixerThread混音业务如何实现的&#xff1f;建议在阅读这篇文章之间先阅读混音理论基础篇&#xff0c;并且在分析源码之前&#xff1a;头脑里构想一个大致的混音过程&#xff0c;多路音频AudioTrack叠加在一…

6 FFmpeg从入门到精通-FFmpeg滤镜使用

1 FFmpeg从入门到精通-FFmpeg简介 2 FFmpeg从入门到精通-FFmpeg工具使用基础 3 FFmpeg从入门到精通-FFmpeg转封装 4 FFmpeg从入门到精通-FFmpeg转码 5 FFmpeg从入门到精通-FFmpeg流媒体 6 FFmpeg从入门到精通-FFmpeg滤镜使用 7 FFmpeg从入门到精通-FFmpeg中Linux设备操作 8 FFm…

量子计算--复习+量子信息--铺垫(学习笔记)

本次&#xff0c;我对前面所学的算符进行一定的拓展并对接下来的量子信息的学习做一些铺垫。 一.些概念的复习和拓展 在前面&#xff0c;我对量子计算的一些概念进行了简单的讲解&#xff0c;而且对一些概念描述的并不完整&#xff0c;所以此次我会完善一下厄米算符、幺正算符…

布尔定理及证明(完整版)

这篇文章的目的是以布尔代数公理证明定理。 对偶原理&#xff1a;0with1, with 互换以后&#xff0c;公理&#xff08;定理&#xff09;任然成立。 布尔代数的公理如下 单变量的布尔代数定理如下 单变量的布尔代数定理很容易用真值表证明。 多变量的布尔定理如下 交换律&…

欧拉函数、欧拉定理、费马小定理

生病了&#xff0c;耽搁了两天。明天开始继续和队友们一起奋战。。。 总结一下&#xff0c;自己以前学过的数论方面的知识。 今天小小的搜索一下&#xff0c;计算机数论真的是很庞大的一个领域。推荐一本书《计算数论》。准备买了、 这里先浅议下欧拉定理和欧拉函数。 很久…

Broekett定理):

设系统满足在邻域内连续可微&#xff0c;则该系统存在连续可微控制律使得被渐进稳定的必要条件是&#xff1a; 线性化之后的系统没有特征根为正实部的不可控模态&#xff1b; 存在的邻域&#xff0c;满足对任意&#xff0c;存在相应的定义在上的控制&#xff0c;使系统的解从…

海伯伦定理

谓词公式通过等价关系及推理规则化成相应的子句集 在谓词逻辑中&#xff0c;把原子谓词公式及其否定统称为文字。 定义3.5&#xff1a;任何文字的析取式称为子句。 例如&#xff1a; P(x)∨Q(x), P(x,f(x))∨Q(x,g(x)) 定义3.6&#xff1a;不包含任何文字的子句称为空子句…

费马小定理、欧拉定理与扩展欧拉定理(含证明)

这里就以自己做好的PPT图片的形式给出了&#xff1a;

量子笔记:单比特量子门、泡利矩阵

目录 0. 概要 1. 量子门基本性质 1.1 量子门与布洛赫球面的关系 1.2 量子门与幺正矩阵的关系 2. 泡利矩阵: 量子X,Y,Z,ID门 2.1 量子X门&#xff08;量子非门&#xff09; 2.2 量子Z门 2.3 量子Y门 2.4 量子ID门 6. 量子H门 7. 量子Z旋转门 7.1 量子S门 7.2 量子S…

图论之毕克定理证明

毕克定理是小学四年级奥赛内容&#xff0c;无意间从一本教材上看到&#xff0c;觉得定理蛮有意思&#xff0c;也和自己从事的工作有一些关联&#xff0c;就在网上找了一些证明资料&#xff0c;结合自己的思考&#xff0c;稍微挖掘了以下&#xff0c;聊以记录。 毕克定理是指一…

chapter 4 能带理论 energy band

继承自chapter 3 的自由电子模型&#xff1a; 4.1 单电子近似 One electron approximation 列出电子运动的薛定谔方程&#xff1a; E Ψ − ℏ 2 2 m ∇ 2 Ψ U Ψ E \Psi -\frac{\hbar^2}{2m} \nabla^2 \Psi U \Psi EΨ−2mℏ2​∇2ΨUΨ 根据电子在晶体中运动的实际情…

能带图最好的理解——克朗尼格-朋奈模型(Kronig-Penney模型)

布洛赫波函数 整体的思想还是基于建模&#xff0c;大家应该都知道在自由电子模型中&#xff0c;能量和波矢的关系 那么大家的第一个疑问首先是&#xff0c;空间结构的周期性应该反应在空间坐标上&#xff0c;为什么K空间也会满足周期性呢&#xff1f; 这里面就不得不说&…

固体物理-复习重点

晶体&#xff1a;是由离子&#xff0c;原子或分子&#xff08;统称为粒子&#xff09;有规律的排列而成的&#xff0c;具有周期性和对称性 非晶体&#xff1a;有序度仅限于几个原子&#xff0c;不具有长程有序性和对称性 点阵&#xff1a;格点的总体称为点阵 晶格&#xff1a;晶…