UAC(零)UAC Topology
UAC 拓扑结构
UAC
规范描述了以下类型的标准单元和终端,这些单元和终端被认为足以代表当前和近期可用的大多数视频功能:
输入终端 - Input Terminal (IT)
输出终端 - Output Terminal (OT)
混音器单元 - Mixer Unit (MU)
选择器单元 - Selector Unit (SU)
特性单元 - Feature Unit (FU)
采样速率转换单元 - Sampling Rate Converter Unit (RU)
特效单元 - Effect Unit (EU)
处理单元 (PU) - Processing Unit (PU)
扩展单元 (XU) - Extension Unit (XU)
除了单元和终端外,还引入了时钟实体的概念。定义了三种类型的时钟实体
时钟源 - Clock Source (CS)
时钟选择器 - Clock Selector (CX)
时钟倍频器 - Clock Multiplier (CM)
UAC 设备拓扑结构
控件通常提供对特定的音频或时钟属性。每个控件都有一组可以操作或显示的属性。
有关 ...
Linux 驱动之 ALSA(九)虚拟声卡 Latency
测试方法
两块板子之间通过 I2S 通信,其中一块板子配置为 Slave 另一块板子为
Master
Master 板端执行 arecord | aplay 或者 gstream 命令
12arecord -Dhw:2,0 -r 44100 -c 8 -f S32_LE | aplay -Dhw:2,0 -c 8 -r 44100 -f S32_LEgst-launch-1.0 alsasrc device=device_input_split ! alsasink device=device_output sync=false
Slave 通过 aplay 播放一段 wav 文件
通过示波器抓取 Master 板的 I2S
输入和输出端的波形间隔来测量虚拟声卡的 Latency
DataStream
上图就是 arecord | aplay(没有使用插件)
整个虚拟声卡的数据流,其中延迟最大的部分就是红色框中的缓存。
走 USB 通路的 latency:
增大 Buffer Size
为什么会增大 latency?
aplay 通过调用 snd_pcm_write 写数据给 ...
Linux 内核调试(三)VM 参数调试
vm 参数说明
Currently, these files are in /proc/sys/vm:
admin_reserve_kbytes:系统中应为用户保留的可用内存量。
默认 (3% of free pages, 8MB)。这应该足以让 admin
登录并终止进程。这个值的设置,最好保证系统足够运行 sshd or login + bash
(or some other shell) + top (or ps, kill, etc.)
block_dump:当设置为非零值时,block_dump 启用块 I/O
调试。
compact_memory:压缩内存。
仅当设置 CONFIG_COMPACTION 时可用。 当写入 1
时,所有区域都会被压缩,以便可以更好的提供连续内存。
这在分配大页面时可能很重要,尽管进程也会根据需要直接压缩内存。
compact_unevictable_allowed:压缩时检查 lru。
dirty_background_bytes:如果 dirty
页大于这个值,内核后台线程开始工作,将 dirty 内存写回到 flash。
dirty ...
Linux 驱动之 ALSA(八)Alsa Plugin
PCM (digital audio) plugins
PCM plugins extends functionality and features of PCM devices. The
plugins take care about various sample conversions, sample copying among
channels and so on.
Plugin: hw
This plugin communicates directly with the ALSA kernel driver. It is
a raw communication without any conversions. The emulation of mmap
access can be optionally enabled, but expect worse latency in the
case.
The nonblock option specifies whether the device is opened in a
non-blocking manner. Note th ...
Linux 驱动之 ALSA(六)声卡创建流程
数据结构
原图
snd_card: 是最顶层数据结构,通过链表挂载该 sound card 的所有设备
snd_device。
snd_pcm: 挂在 snd_card 下面的一个 snd_device。
snd_pcm_str: 代表 playback stream 和 capture stream。
snd_pcm_substream: 是 pcm 中间层的核心,绝大部分任务都是在 substream
中处理,尤其是他的 ops(snd_pcm_ops)字段,许多 user 空间的应用程序通过
alsa-lib 对驱动程序的请求都是由该结构中的函数处理。它的 runtime
字段则指向 snd_pcm_runtime 结构,snd_pcm_runtime 记录这 substream
的一些重要的软件和硬件运行环境和参数。
snd_pcm_ops: 创建声卡需要提供的回调。
snd_pcm_runtime: 运行时参数,包括 sample rate、channel、format
等参数,以及 buffer 相关信息。
snd_pcm_harward: 硬件相关参数,创建声卡需要 ...
Linux 驱动之 ALSA(七)XRUN
XRUN 是缓冲区不足或溢出,X
代表不足或溢出。在这两种情况下,都表明系统速度不够快,未能及时处理来自
ALSA
音频缓冲区的数据,因此丢失了一些数据。当我们以非常小的缓冲区大小运行时,声卡应该非常快地处理传入缓冲区的数据,否则就溢出
overrun
了。有些芯片无法适应较小的缓冲区大小,因此我们必须增加缓冲区长度以减轻声音芯片的工作量。通常,xruns
可以听到爆裂声或爆裂声。
在录音例子中,如果应用程序读取数据不够快,循环缓存区将会被新的数据覆盖。这种数据的丢失被称为"over
run"
在回放例子中,如果应用程序写入数据到缓存区中的速度不够快,缓存区将会"饿死"。这样的错误被称为"under
run"
/Proc
ALSA 提供了一种通过 proc 记录和调试 xrun 的方法:
123Device Drivers ---> <*> Sound card support ---> <*> Advanced Linux Sound Architecture ---> [*] Sound Proc FS Suppor ...
Linux 驱动之 ALSA(五)Machine 驱动
ASoC
架构的设计方式是平台和编解码器类驱动程序必须绑定在一起才能构建音频设备。这种绑定可以在所谓的机器驱动程序或设备树中完成,每一个机器驱动程序和设备树都是与特定机器相关的。也就是说,机器驱动程序针对特定系统,并且不同的板卡需要不同的机器驱动程序。
Machine 驱动程序开发流程
一般来说,机器驱动程序的职责包括以下内容
使用适当的 CPU 和编解码器 DAI 填充 struct snd_soc_dai_link
结构体
物理编解码器时钟设置(如果有的话)和编解码器初始化主/从配置(如果有的话)
定义 DAPM widget 以路由物理编解码器内部并根据需要完成 DAPM 路径
根据需要将运行时采样频率传播到各个编解码器驱动程序
鉴于此,机器类驱动程序的开发可执行以下流程。
编解码器驱动程序注册组件驱动程序、DAI
驱动程序以及它们的操作函数
平台驱动程序注册组件驱动程序、PCM 驱动程序、CPU DAI
驱动程序和它们的操作函数,并根据需要设置回放和采集操作
机器层在编解码器和 CPU 之间创建 DAI 链接并注册声卡和 PCM 设备
现在我们已经了解了机器类驱动程序 ...
Linux 驱动之 ALSA(四)Platform 驱动
平台驱动程序可以注册 PCM 驱动程序、CPU DAI 驱动程序及其操作函数,为
PCM
组件预分配缓冲区,并根据需要设置回放和采集操作。换言之,平台驱动程序包含该平台的音频引擎和音频接口驱动程序(如
I2S、AC97 和 PCM)。
平台驱动程序以构成平台的 SoC 为目标。它涉及平台的 DMA(即音频数据在
SoC 中的每个块之间如何传输)和 CPU DAI(即 CPU
向编解码器发送音频数据的路径或 CPU 从编解码器获得音频数据的路径)。
平台驱动程序有两个重要的数据结构体:structsnd_soc_component_driver 和
structsnd_soc_dai_driver。前者负责 DMA 数据管理,后者负责 DAI
的参数配置。当然,前文在讨论编解码器类驱动程序时已经描述过这两种数据结构体,因此,本节将仅介绍与平台代码相关的附加概念。
CPU DAI 驱动程序
在平台侧,大部分工作都可以由 core 完成,尤其是与 DMA
相关的工作。因此,CPU DAI
驱动程序通常只提供组件驱动程序结构中的接口名称,而让 core
完成其余的工作。以下是 STM SPD ...
Linux 驱动之 ALSA(三)编解码器类驱动实例
这里以 Wolfson 公司的编解码芯片 WM8960 为例来说明上篇介绍的相关内容。
定义 widget 所需的 DAPM
Kcontrol
1234567891011121314static const struct snd_kcontrol_new wm8960_loutput_mixer[] = { SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_LOUTMIX, 8, 1, 0), SOC_DAPM_SINGLE("LINPUT3 Switch", WM8960_LOUTMIX, 7, 1, 0), SOC_DAPM_SINGLE("Boost Bypass Switch", WM8960_BYPASS1, 7, 1, 0),};static const struct snd_kcontrol_new wm8960_routput_mixer[] = { SOC_DAPM_SINGLE("PCM Playback Switch", WM8960_ROUTMIX, 8, 1, 0), SOC_DAP ...
Linux 驱动之 ALSA(二)编解码器类驱动相关概念
编解码器类驱动程序是最基本的,他实现的代码应该利用编解码器设备并公开其硬件属性,以便
amixer 等用户空间工具可以使用它。
由于驱动程序针对特定的编解码器,因此它应该包含音频控制、音频接口功能、编解码器
DAPM 定义和 I/O 功能,每个编解码器必须满足:
通过定义 DAI 和 PCM 配置来提供与其他模块的接口
提供编解码器控制 I/O hook(使用 I2C、SPI 的 API)
根据用户空间的需要,公开其他内核控件(Kernel
control,Kcontrol)以动态控制模块行为
定义 DAPM widget,为动态电源切换建立 DAPM 路由,并提供 DAC
数字静音控制(option)
Component
包含编解码器的路由、widget、控件金额一组编解码器相关函数回调指针,以及一个或多个
dai 驱动。
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869 ...