Linux音频问题——codec寄存器配置
一、Linux音频简介
1、Linux音频的历史
起初,在1992年推出了OSS框架,用于在Unix操作系统中处理音频信号。直至于1998年Gravis Ultrasound所开发的ALSA驱动,ALSA此时一直作为一个单独的软件包开发,LINUX内核一直使用的OSS框架。直到2002年开始,Linux内核2.5版本引进,2.6版本成为Linux内核中默认的标准音频驱动程序集,OSS则被标记为废弃。
2、Linux音频常见问题
- 音频输入输出设备缺失
- 音频输入输出无响应
- 耳机mic无响应
- 音频输入噪音
二、Linux音频框架
首先我们来了解下当前Linux音频在使用的主流音频框架,也就是ALSA。
1、ALSA(Advanced Linux Sound Architecture ,高级 Linux 音频架构)
- Alsa application: 是alsa alsa-tools中提供的上层调试工具,用户可以直接将其移植到自己所需要的平台,这些应用可以用来实现playback、capture、controls等,例如声卡问题常见的调试工具aplay、arecord、amixer等。
- Alsa library API: alsa用户库接口,常见有alsa-lib。(alsa-tools中的应用程序基于alsa-lib提供的api来实现)
- Alsa core: alsa核心层,向上提供逻辑设备(pcm/ctl/midi/timer/..)系统调用,向下驱动硬件设备(Machine/i2s/dma/codec)
2、PCM
PCM就是把声音从模拟信号(人耳能识别的信号)转换为数字信号的一种技术,它利用一个固定的频率对模拟信号进行采样,采样后对信号进行处理,并将处理后的信号数据输出或记录到存储介质中,从而产生数字音频。
- AC97: 通常用于PC声卡, 为5线接口, 每个AC97帧为21uS长, 被分为13个时隙
- BCLK: 由AC97驱动, 为12.288 MHz
- SYNC: 同步信号, 由Controler驱动, 为48 kHz
- SDATDIN: 用于capture, AC97->Controler
- SDATAOUT: 用于playback, Controler->AC97
- RESET: 由Controler生成, 用于唤醒AC97
I2S是HiFi、STB和便携式设备中常用的4线DAI
- SCLK: 串行时钟
- LRCK: 也称WS, 声道选择线
- Tx: 用于传输音频数据
- Rx: 用于接收音频数据
PCM是另一种4线接口, 与I2S非常相似, 可以支持更灵活的协议
- BCLK: 位时钟, 根据采样率而变化
- SYNC: 同步信号
- Tx: 用于传输音频数据
- Rx: 用于接收音频数据
3、CONTROL
Control接口主要让用户空间的应用程序可以访问和控制音频codec芯片中的多路开关,滑动控件等,进行音量控制、静音等。
4、MIDI
是为了连接舞台上的synthesizer、键盘、道具、灯光控制器的一种串行接口
5、ASOC
ALSA存在的问题:
- Codec驱动与SOC中断CPU耦合严重,这将导致代码重复,一个Codec驱动每个cpu上会出现不同的版本。
- 当音频事件发生时(插拔耳机,音箱)没有标准的方法通知用户,尤其在移动端此事件非常常见。
- 当播放/录制音频时,驱动会让整个codec处于上电状态,这样会在移动端非常浪费电量。同时也不支持改变采样频率/配置电流来节约功耗。
针对以上问题,提出了ASOC来力争解决上述问题。解决方法如下:
- Codec代码独立,不再耦合于CPU,这样可以增加Codec代码重复利用。
- 在Codec和Soc之间通过简单的I2S/PCM音频接口通信,这样SOC和Codec只需要注册自己相关的接口到ASOC code即可。
- 动态的电源管理(Dynamic Audio Power Management)DAPM。DAPM始终将Codec自动设置在最低功耗状态运行。
- 消除pop音。控制各个widget上下电的顺序消除pop音。
- 添加平台相关的控制,运行平台添加控制设备到声卡
6、Machine
Machine可以理解为是一个桥梁,用于在Codec和Platform之间建立联系。此Machine指定了该机器使用那个Platform,那个Codec,最终会通过Machine建立两者之间的联系
7、Platform
可以理解为某款SOC平台,平台驱动中包括音频DMA引擎驱动,数字接口驱动(I2S, AC97, PCM)以及该平台相关的任何音频DSP驱动。同样此Platform也可以重用,在不同的Machine中可以直接重复使用。
8、Codec
Codec即编解码芯片的驱动,此Codec驱动是和平台无关,包含的功能有: 音频的控制接口,音频读写IO接口,以及DAPM的定义等
三、Linux音频之HDA
HDA(High Definition Audio,高清晰音效技术)
- 由Intel于2004年所提出的音效技术,能够展现高清晰度的音质效果,且能够进行多声道的播放,在音质上超越过去的其他整合型音效编解码器,如Audio Codec 97。
- 当前HDA技术已经普遍被各大芯片厂商采用,诸如intel、realtek、各类HDMI和conexant等都使用了这项技术,除了realtek、intel等厂商修复,我们这些外部任务目前能够对音频问题进行修复的内容也大都在ALSA的pci/hda框架之下。
- High Definition Audio Controller:是一种总线主控 I/O 外设,它通过 PCI 或其他典型的 PC 外设连接主机接口连接到系统内存。它包含一个或多个 DMA 引擎,每个DMA引擎都可以设置为将单个音频“流”从编解码器传输到内存,或从内存传输到编解码器,具体取决于 DMA 类型。
- High Definition Audio Link:High Definition Audio Controller通过 High Definition Audio Link 物理连接到一个或多个编解码器。
- High Definition Audio Codec:一个或多个Codec连接到link。Codec从时间复用link协议中提取一个或多个音频流,并通过一个或多个转换器(标记为“C”)将它们转换为输出流。
每一个激活的Stream都必须连接到一个DMA引擎上,DMA类型随设备类型被决定。
- Port Connectivity:表示 Pin Complex 的外部连接性。软件可以使用此值来了解哪些引脚复合体连接到插孔、内部设备或根本未连接。
- Location:表明所连接的插孔或设备的物理位置。例如,这该设备连接的是“前面板耳机插孔”,而不是后面板插孔。
- 位置字段分为两部分,高位 [5:4] 和低位 [3:0]。高位 [5:4] 提供总位置,例如“外部”(在主系统机箱上,用户可以访问),“内部”(在主板上,不打开盒子就无法访问),在单独的底盘(如移动箱)或其他。
- 低位 [3:0] 提供几何位置,例如“前”、“左”等,或提供特殊编码来指示位置,例如安装在移动盖上的麦克风。左表中的“x”表示软件应支持的组合。虽然所有组合都是允许的,但它们并非都是可能的或预期的。
- Default Device:表示插孔或设备的预期用途。这可以指示插孔上的标签或硬连线到端口的设备,如集成扬声器等。
- Connection Type:指示物理连接的类型,例如 1/8 英寸立体声插孔或光纤数字连接器等。软件可以使用此信息向用户提供有用的用户界面描述,或根据设备的功能修改报告的编解码器功能编解码器外部的物理传输。
- Color:指示软件使用的物理插孔的颜色。
- Misc:是一个位字段,用于指示有关插孔的其他信息。目前,仅定义了位 0。如果设置了位 0,则表明该插孔没有存在检测功能,因此即使 Pin Complex 指示编解码器硬件支持该插孔上的存在检测功能,外部电路也无法支持该功能。
- Default Association:软件一起使用Default Association和Sequence,将引脚复合体(以及插孔)组合成功能块,以支持多通道操作。对于处理节点或输入和输出转换器等资源,较低的默认关联值将具有较高的优先级。
- Sequence:Sequence表示关联组中插孔的顺序。关联组中编号最低的插孔应分配流中编号最低的通道等。编号在组内不必是连续的,只有顺序很重要。一组默认关联中的序列号必须是唯一的。
配置引脚寄存器需要配合声卡芯片的datasheet中的Pin Assignments和Pin Descriptions详细进行配置。 例如ALC256:
配置引脚寄存器能够修复诸如系统无输入输出设备、耳机插入不识别、耳机/话筒无法录音、耳机/扬声器输出无响应。但是噪音问题很难或很少能够通过配置Pin解决。
四、Linux中的音频codec的配置
在Linux中,系统的/dev/snd/目录记录着当前系统正在使用的音频设备的设备文件,如下:
HDA实现中,在系统中预留了系统配置接口,即/sys/class/sound/hwCxDy,如下:
其中各个接口的说明参考下表:
序号 |
接口 |
说明 |
1 |
name |
codec的名称,可以直接写入新字符串进行修改 |
2 |
init_verbs |
初始化时需要额外执行的verbs,添加需要的verbs到这个文件,可以在 初始化时被执行。 |
3 |
hints |
给codec的暗示,例如写入jack_detect = no 就会禁止掉codec的jack dectection功能。 |
4 |
init_pin_configs |
记录BIOS设置的initial pin default config。 |
5 |
driver_pin_configs |
记录codec修改掉pin default config值的部分。 |
6 |
usr_pin_configs |
写入自己设定的配置可以覆盖掉BIOS启动时的设置。 |
7 |
reconfig |
触发codec重新配置,一旦往这个文件写入任意值,驱动就会re-initialize the codec tree again |
而我们音频中大多数的修复补丁,都是在修改driver_pin_configs这个配置,以此来让我们的机器搭载的音频设备表现的更好。例如,以下这个修复提交,就是将 driver_pin_configs值配置为0x18, 0x01a110f0
这个修复补丁的配置的主要有两种方法:
一、确认自己当前机器搭载的声卡型号,看根据当前社区主线代码中是否已经修复,或者有没有相同的机器或者芯片型号的配置修改,如果有,我们可以试一试已经有的配置程序是否在我们的环境中也表现良好,如下示例,就是用已有的修复配置,修复本地机器的音频问题:
二、当自己的机器搭载的声卡,当前社区主线代码中已经修复,或者相同的机器或者芯片型号的配置修改,我们尝试已经有的配置程序在我们的环境中也表现不佳,那我们就要自己去配置适合自己本地机器的声卡的修复程序。
而如何配置就需要配合第三章节中提及的HDA配置说明进行配置,我们可以借助alsa-tools-gui提供的hdajackretask命令进行可视化的配置修改验证。
直至我们找到了可以使用的配置,然后根HDA配置项最终写入driver_pin_configs中。
三、此外,系统层也可以进行配置,最终影响usr_pin_configs的配置,优先级高于init_pin_configs和driver_pin_configs。而当前alsa推出和持续优化的alsa-ucm-conf包,也是集中在优化在系统层进行音频配置优化。
当前GitHub - alsa-project/alsa-ucm-conf: ALSA Use Case Manager configuration这个社区也十分活跃,它是使用了json语法来进行配置相关音频设备的配置的,感兴趣的可以研究一下
五、Linux音频之噪音
除了音频输入输出设备缺失、音频输入输出无响应、耳机mic无响应等直接影响使用的致命问题外,其实音频的输入噪音问题也很常见,但是音频的噪音问题往往要么是硬件或者环境影响,或者即使是能够通过软件优化进行修复,但是不了解声卡芯片的内核设计和主板电路情况,一般的开发者很难修复。下面让我们了解下,噪音问题的主要表现和可能的原因:
1.嗡声:即所谓的变压器声,来源复杂
- 器件工艺设计不合理
- 连接线缆的屏蔽能力不足
- 供电电压过低导致的内部电路工作不正常
2.噗声:所谓的火花声
- 器件内部积累灰尘过多
- 元器件损耗,超过使用寿命
3.流水声:高频自激现象
- 电路设计不良,属于质量问题
4.啸叫声、汽船声:低频自激现象
- 关闭电源,检查器件之间的连接性是否完好
5.偶尔的杂声:交流供电线路的串扰
6.广播声:容易引起高频自激,严重时导致喇叭或者耳机烧毁
- 电路设计不良
- 放大器的开环频响很差
- 非线性失真严重
- 没有进行适当的处理
音频噪音问题最常见的是电流噪音,而电流噪音问题的出现,除了硬件本身设计缺陷外,通常是由于音频滤波器没有处理好音频输入的频率范围,导致将一些本不该被拾音或放大的音频信号录入或放大导致,而电流处理往往需要搭配滤波器进行拾音频率范围调整来分析调制(这需要熟悉滤波器原理,并搭配声卡芯片电路图,对内核开发者而言是一个新的领域和调试手段,因此此类问题往往很难解决)
参考链接:
https://www.intel.com/content/dam/www/public/us/en/documents/product-specifications/high-definition-audio-specification.pdf
Linux音频问题——codec寄存器配置相关推荐
- Linux 音频驱动(三) ASoC音频驱动之Codec驱动
目录 1. 简介 2. 源码分析 2.1. Codec 2.1.1. 数据结构struct snd_soc_codec_driver 2.1.2. 注册Codec 2.2. Codec DAI 2.2 ...
- linux 音频驱动的流程,Intel平台下Linux音频驱动流程分析
[软件框架] 在对要做的事情一无所知的时候,从全局看看系统的拓扑图对我们认识新事物有很大的帮助.Audio 部分的驱动程序框架如下图所示: 这幅图明显地分为 3 级. 上方蓝色系的 ALSA Kern ...
- Linux音频驱动开发概括
原址 1.嵌入式音频系统硬件连接 下图所示的嵌入式设备使用IIS将音频数据发送给编解码器.对编解码器的I/O寄存器的编程通过IIC总线进行. 2.音频体系结构-ALSA ALSA是Advanced L ...
- linux音频子系统 - DAPM
Dynamic Audio Power Management for Portable Devices 移动设备的动态电源管理(DAPM) 1. Description DAPM使得使用音频子系统的移 ...
- linux 声卡配置文件,Linux音频配置文件asound.conf的使用
Linux音频配置文件asound.conf的使用 asound.conf文件作用:主要用来做Android/Linux音频的路由控制,不同路由可以设置多个寄存器的不同配置组合,形成不同的音频通道,从 ...
- 嵌入式Linux音频驱动开发
1.嵌入式音频系统硬件连接 下图所示的嵌入式设备使用IIS将音频数据发送给编解码器.对编解码器的I/O寄存器的编程通过IIC总线进行. 2.音频体系结构-ALSA ALSA是Advanced Linu ...
- 体验 Linux 音频驱动
目录 一.音频接口简介 1.音频编解码芯片 2. WM8960 3.I2S总线接口 二.硬件原理图 三.音频驱动使能 三.使能内核的 WM8960 驱动 1.取消 ALSA 模拟 OSS API 2. ...
- Linux 音频驱动
Linux 音频驱动 硬件介绍 WM8960与IMX6ULL之间有两个通信接口:I2C和I2S 其中I2C用于配置WM8960 I2S用于音频数据传输 修改设备树文件 编写I2C子节点设备树 code ...
- Linux 音频驱动(四) ASoC音频驱动之Machine驱动
目录 1. 基本介绍 2. 源码分析 2.1. Machine数据结构 struct snd_soc_dai_link 3. 声卡 3.1. 数据结构struct snd_soc_card 3.2. ...
最新文章
- linux系统文件分类,Linux系统文件概念和文件类型
- 小程序中页面兼容h5标签的解析
- Android将联系人读取到LISTVIEW中遇到的问题!
- rails采用MongoDB感觉相当不错!
- 私有属性和方法-子类对象不能直接访问
- java嵌入groovy脚本,java-如何捕获传递给Groovy脚本的参数?
- 【Jmeter篇】Jmeter分布式调度压测部署
- MySQL5添加外键约束错误 (Error Code : 1005)
- 【转】.Net 架构图
- win2008 401 - 未授权: 由于凭据无效,访问被拒绝。解决方法
- 浏览器自动打开html怎么办,浏览器自动弹出网页怎么处理?开机自动弹出垃圾网页如何解决?...
- U盘中的SanDiskSecureAccess可以删除么?删除后影响U盘的使用么?
- 巴比特观察 | NFT朋克热潮:CryptoPunks的成功可以复制吗
- IDEA打包普通Java web项目
- 哈勃分析系统解密:中招敲诈木马不用交赎金
- Ubuntu论坛遭到入侵 用户数据泄露
- 观自在菩萨,行深般若波罗蜜多时,照见五蕴皆空,度一切苦厄。舍利子,色不异空,空不异色,色即是空,空即是色,受想行识,亦复如是。舍利子,是诸法空相,不生不灭,不垢不净,不增不减。是故空中无色,无受想行识
- eureka集群高可用配置
- 实现简单的三D立方体自动旋转
- ascii unicode utf8 gkb之间的关系
热门文章
- Scala系列20:Scala中异常捕获与抛出异常
- 个人永久性免费-Excel催化剂功能第94波-地图数据挖宝之搜索地图上的各种兴趣点数据(商铺名、地名、公共设施等)...
- C++ Armadillo矩阵库的安装与基本用法
- 将图片转换为Base64
- java高级程序员(Java高级程序员招聘)
- 在线公开课 | 教你如何自行搭建一个威胁感知大脑?
- java 解析dat_JAVA中怎么读取DAT文件中的内容
- 他曾与20人挤在80㎡的宿舍 现在拥有全国最大的自媒体平台
- DDPG中的Ornstein-Uhlenbeck过程怎么理解
- centos(7.9) minikube(v1.28.0) kaniko 构建镜像