Linux系统中内核音频驱动实现

简介: Linux系统中内核音频驱动实现

本文以I2S接口为例介绍Linux内核音频相关知识。

一、名词介绍

下面是音频调试中常见的名词缩略语。

1、AEC(Acoustic Echo Cancellor):回声消除。

2、AGC(Automatic Gain Control):自动增益补偿,调整MIC收音量。

3、ALSA(Advanced Linux Sound Architecture):高级Linux声音架构。

4、ANS(Automatic Noise Suppression):背景噪音抑制,ANS可探测出背景固定频率的杂音并消除背景噪音。

5、BCK(Bit Clock Line):位时钟,对应数字音频的每一位数据。标准称为SCK(Serial Clock),串行时钟。SCK=2x采样频率x采样位数

6、DAI(Digital Audio Interface):数字音频接口。

7、DAPM(Dynamic Audio Power Management):动态电源管理,DAPM可使基于linux的移动设备上的音频子系统,在任何时候都工作在最小功耗状态。

8、DRC(Dynamic Range Control):动态压缩,将音频输出控制在一定范围内。

9、EQ(Equaliser):均衡器,通过对声音某一个或多个频段进行增益或衰减,达到调整音色的目的。

10、I2S(Inter-IC Sound):IC间传输数字音频资料的一种接口标准,采用序列的方式传输2组(左右声道)资料。

11、LRCK(Left-Right Clock):帧时钟,用于切换左右声道数据,0:左声道;1:右声道。标准称为WS(World Select),声道选择;或称为FS(Frame Sync),帧同步;LRCK的频率=采样频率。

12、MCLK(Master Clock):主时钟,一般MCLK=256*LRCK。不是I2S标准中的一部分,主要用来同步模拟/数字转换器的内部操作。

13、Mono:单声道。

14、OSS(Open Sound System):开放声音系统。

15、PCM(Pulse Code Modulation):脉冲编码调制,I2S是PCM的子集。

16、ramp:逐步增加或减少音量等级,避免声音急速变化,用于暂停或恢复音乐。

17、Stereo:双声道

18、TDM(Time Division Multiplexing):时分复用。I2S最多只能传2声道数据,TDM最多支持16通道。

二、I2S接口

I2S是飞利浦定义的数字音频传输标准,用于数字音频数据在系统内部器件之间传输。

I2S是PCM的一个分支,接口定义相同。I2S的采样率一般为44.1/48KHZ,PCM采样频率一般为8/16KHZ等。

I2S接口有4组信号:SCK(位时钟)、LRCK(帧时钟)、SDI/SDO(数据)。

在I2S总线上,只能同时存在一个主设备和发送设备,主设备可以是发送设备或接收设备。常见的I2S框图如下:

三、I2S协议

I2S接口常见的协议模式包括:I2S正常模式、I2S左对齐模式和I2S右对齐模式等。

1、I2S正常模式

I2S正常模式属于I2S左对齐中的一种特例,也叫Philips模式。下图是I2S正常模式的波形。

LRCK(i2s_LRCK_rx/i2s_LRCK_tx)信号变低表示左声道,变高表示右声道。

SD(i2s_sdo,i2s_sdi)信号首先传输MSB或LSB,并在LRCK改变后的一个SCLK时钟周期发送第一个bit。

SD信号宽度的范围是从16到32位。

2、I2S左对齐模式

下图是I2S左对齐模式的波形。

LRCK(i2s_LRCK_rx/i2s_LRCK_tx)信号变高表示左声道,变低表示右声道。

SD(i2s_sdo,i2s_sdi)信号首先传输MSB或LSB,并在LRCK改变的同时发送第一个bit。

SD信号宽度的范围是从16到32位。

3、I2S右对齐模式

下图是I2S右对齐模式的波形。

LRCK(i2s_LRCK_rx/i2s_LRCK_tx)信号变高表示左通道,变低表示右通道。

SD(i2s_sdo、i2s_sdi)信号首先传输MSB或LSB,与I2S正常或左对齐模式不同,其数据与LRCK信号的边缘处的最后一位对齐。

SD信号宽度范围从16到32位。

其他协议格式还有:PCM early mode、PCM late1 mode和PCM late2 mode等。

四、ALSA框架

Linux内核2.6之后,ALSA取代了OSS成为了Linux内核音频子系统是一部分。

ALSA系统包括:

1、alsa-driver:alsa系统驱动。

2、alsa-lib:alsa库,用户空间调用,和内核空间交互。

3、alsa-utils:命令行工具。

4、alsa-plugin:alsa插件。

5、alsa-tools:alsa工具。

ALSA框架组成如下:

alsa-driver中相关功能如下(以rockchip 4a单板为例):

1、Codec:音频芯片共有的部分,包括codec初始化函数,控制接口,寄存器缓存,控件,dapm部件,音频路由,偏置电压设置函数等描述信息。

Rockchip 4A单板,Codec选用的是ES8316芯片,该芯片的dts配置如下:

2、Codec DAI:codec上的音频接口驱动描述,包括:时钟配置,格式配置,能力描述等。

Codec DAI相关实现如下:

3、CPU DAI:指 SoC 的 I2S、PCM 总线控制器,负责把音频数据从 I2S tx FIFO 搬运到 codec。

RK3399 CPU DAI的dts相关配置如下:

4、DAI Link:音频数据链路,它指定链路用到的codec、codec_dai、cpu_dai和platform。

Linux 4.4 内核支持两种方式创建声卡:一种是通用的simple-card framework;一种是传统的编写自定义的 machine driver 来创建。

Simple card是简单通用的machine driver,如果 simple-card框架足够满足需求,可优先选择simple card 框架。

DAI Link的dts相关配置如下:

DAI Link的相关实现如下:

5、DAPM:动态电源管理,是基于kcontrol改进过后的相应框架,增加了相应的电源管理机制, widget是DAPM的基本单位。

Codec(es8316)中kcontrol、dapm widget和dapm routes的相关实现如下:

6、DMA:负责把 dma buffer 中的音频数据搬运到 I2S tx FIFO。

五、调试命令

ALSA是Linux处理音频的基本接口,但ALSA只提供基层的接口,操作较为繁复,一般情况下可以直接使用其附带提供的 utils 工具集,utils 工具集是一些封装好了的功能模块,直接以命令的方式提供,用户只需要敲入相关命令和参数即可实现音频操作功能。

1、查看声卡信息

root@xiaotianbsp:~# cat /proc/asound/cards
 0 [rockchipes8316c]: rockchip_es8316 - rockchip,es8316-codec
                      rockchip,es8316-codec
 1 [HDMICODEC      ]: HDMI-CODEC - HDMI-CODEC
                      HDMI-CODEC
root@xiaotianbsp:~# ls -l /dev/snd/
total 0
drwxr-xr-x  2 root root       80 Aug 16 14:43 by-path
crw-rw----+ 1 root audio 116,  2 Aug 16 14:43 controlC0
crw-rw----+ 1 root audio 116,  5 Aug 16 14:43 controlC1
crw-rw----+ 1 root audio 116,  4 Aug 16 14:43 pcmC0D0c
crw-rw----+ 1 root audio 116,  3 Aug 16 14:43 pcmC0D0p
crw-rw----+ 1 root audio 116,  6 Aug 16 14:43 pcmC1D0p
crw-rw----+ 1 root audio 116,  1 Aug 16 14:43 seq
crw-rw----+ 1 root audio 116, 33 Aug 16 14:43 timer

controlCx:控制接口,提供灵活的方式管理注册的声卡和对存在的声卡进行查询。

pcmCxDxc:PCM接口,对应录音设备。

pcmCxDxp:PCM接口,对应放音设备。

timer:支持声音的同步事件提供声卡上的定时器。

seq:音序器接口,一个比原始MIDI接口高级的MIDI编程和声音同步高层接口。

2、查看声卡采集、播放PCM信息

root@xiaotianbsp:~# cat /proc/asound/pcm
00-00: ff880000.i2s-ES8316 HiFi ES8316 HiFi-0 :  : playback 1 : capture 1
01-00: ff8a0000.i2s-i2s-hifi i2s-hifi-0 :  : playback 1

3、查看ALSA驱动版本

root@xiaotianbsp:~# cat /proc/asound/version
Advanced Linux Sound Architecture Driver Version k4.4.154-90-rockchip-ga14f6502e045.

4、查看声卡0的信息

root@xiaotianbsp:~# cat /proc/asound/card0/pcm0p/sub0/status
closed

5、查看寄存器

## regmap名称
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/1-0011/name
es8316
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/ff880000.i2s/name
rockchip-i2s
## rk3399 i2s0控制器寄存器
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/ff880000.i2s/registers
00: 0000000f
04: 0000000f
08: 00033f3f
0c: 00000000
10: 000f0010
14: 01f00000
18: XXXXXXXX
1c: 00000000
20: XXXXXXXX
28: 00000000
## es8316寄存器
root@xiaotianbsp:~# cat /sys/kernel/debug/regmap/1-0011/registers
00: c0
01: f3
02: 08
03: 20
04: 11
05: 00
06: 11
07: 00
08: 00
09: 04
0a: 0c
0b: 0c
0c: ff
0d: 3f
0e: ff
0f: ff
10: 11
11: fc
12: 28
13: 00
14: 00
15: 33
16: 00
17: 00
18: 00

6、查看时钟

## 采样率44.1KHZ,mclk = 256 * sample = 256*44.1*1000 = 11289600 HZ
root@xiaotianbsp:~# cat /sys/kernel/debug/clk/clk_summary | grep i2s0
          clk_i2s0_div                    1            1   800000000          0 0
             clk_i2s0_frac                1            1    11289600          0 0
                clk_i2s0_mux              1            1    11289600          0 0
                   clk_i2s0               1            2    11289600          0 0
                hclk_i2s0                 1            2   100000000          0 0

7、amixer命令

root@xiaotianbsp:~# amixer -h
Usage: amixer <options> [command]
Available options:
  -h,--help       this help
  -c,--card N     select the card
  -D,--device N   select the device, default 'default'
  -d,--debug      debug mode
  -n,--nocheck    do not perform range checking
  -v,--version    print version of this program
  -q,--quiet      be quiet
  -i,--inactive   show also inactive controls
  -a,--abstract L select abstraction level (none or basic)
  -s,--stdin      Read and execute commands from stdin sequentially
  -R,--raw-volume Use the raw value (default)
  -M,--mapped-volume Use the mapped volume
Available commands:
  scontrols       show all mixer simple controls
  scontents       show contents of all mixer simple controls (default command)
  sset sID P      set contents for one mixer simple control
  sget sID        get contents for one mixer simple control
  controls        show all controls for given card
  contents        show contents of all controls for given card
  cset cID P      set control contents for one control
  cget cID        get control contents for one control

7.1查看card0内容

root@xiaotianbsp:~# amixer -c 0 contents
numid=16,iface=MIXER,name='ADC Double FS Mode'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
numid=14,iface=MIXER,name='ADC Soft Ramp'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on
numid=13,iface=MIXER,name='ADC Capture Volume'
  ; type=INTEGER,access=rw---R--,values=1,min=0,max=192,step=0
  : values=192
  | dBscale-min=-96.00dB,step=0.50dB,mute=1
numid=15,iface=MIXER,name='Capture Polarity'
  ; type=ENUMERATED,access=rw------,values=1,items=2
  ; Item #0 'Normal'
  ; Item #1 'Invert'
  : values=0

7.2查看和配置某个numid命令

## 查看
root@xiaotianbsp:~# amixer -c 0 cget numid=16
numid=16,iface=MIXER,name='ADC Double FS Mode'
  ; type=BOOLEAN,access=rw------,values=1
  : values=off
  
## 配置
root@xiaotianbsp:~# amixer -c 0 cset numid=16 on
numid=16,iface=MIXER,name='ADC Double FS Mode'
  ; type=BOOLEAN,access=rw------,values=1
  : values=on

8、设备名

root@xiaotianbsp:~# aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: rockchipes8316c [rockchip,es8316-codec], device 0: ff880000.i2s-ES8316 HiFi ES8316 HiFi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
card 1: HDMICODEC [HDMI-CODEC], device 0: ff8a0000.i2s-i2s-hifi i2s-hifi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0
root@linaro-alip:~# arecord -l
**** List of CAPTURE Hardware Devices ****
card 0: rockchipes8316c [rockchip,es8316-codec], device 0: ff880000.i2s-ES8316 HiFi ES8316 HiFi-0 []
  Subdevices: 1/1
  Subdevice #0: subdevice #0

9、放音

aplay -D hw:0,0 -r 44100 -c 2 -f s16_le play.wav

10、录音

arecord -D hw:0,0 -r 16000 -c 1 -f s16_le record.wav

-D:播放设备,aplay -l 或arecord -l列出的设备名

-r:采样率

-c:音频文件通道

-f:采样格式,常用的有S16_LE ,S24_LE ,S32_LE, cd (可忽略)

也可参考tinyalsa命令,如:tinymix、tinypcminfo、tinyplay和tinycap的用法。

11、mp3转wav

lame test.mp3 test.wav --decode
目录
相关文章
|
3天前
|
算法 Linux 调度
深入理解Linux内核调度器:从基础到优化####
本文旨在通过剖析Linux操作系统的心脏——内核调度器,为读者揭开其高效管理CPU资源的神秘面纱。不同于传统的摘要概述,本文将直接以一段精简代码片段作为引子,展示一个简化版的任务调度逻辑,随后逐步深入,详细探讨Linux内核调度器的工作原理、关键数据结构、调度算法演变以及性能调优策略,旨在为开发者与系统管理员提供一份实用的技术指南。 ####
18 4
|
3天前
|
Linux
在 Linux 系统中,“cd”命令用于切换当前工作目录
在 Linux 系统中,“cd”命令用于切换当前工作目录。本文详细介绍了“cd”命令的基本用法和常见技巧,包括使用“.”、“..”、“~”、绝对路径和相对路径,以及快速切换到上一次工作目录等。此外,还探讨了高级技巧,如使用通配符、结合其他命令、在脚本中使用,以及实际应用案例,帮助读者提高工作效率。
17 3
|
3天前
|
监控 安全 Linux
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景
在 Linux 系统中,网络管理是重要任务。本文介绍了常用的网络命令及其适用场景,包括 ping(测试连通性)、traceroute(跟踪路由路径)、netstat(显示网络连接信息)、nmap(网络扫描)、ifconfig 和 ip(网络接口配置)。掌握这些命令有助于高效诊断和解决网络问题,保障网络稳定运行。
15 2
|
5天前
|
缓存 资源调度 安全
深入探索Linux操作系统的心脏——内核配置与优化####
本文作为一篇技术性深度解析文章,旨在引领读者踏上一场揭秘Linux内核配置与优化的奇妙之旅。不同于传统的摘要概述,本文将以实战为导向,直接跳入核心内容,探讨如何通过精细调整内核参数来提升系统性能、增强安全性及实现资源高效利用。从基础概念到高级技巧,逐步揭示那些隐藏在命令行背后的强大功能,为系统管理员和高级用户打开一扇通往极致性能与定制化体验的大门。 --- ###
25 9
|
4天前
|
缓存 负载均衡 Linux
深入理解Linux内核调度器
本文探讨了Linux操作系统核心组件之一——内核调度器的工作原理和设计哲学。不同于常规的技术文章,本摘要旨在提供一种全新的视角来审视Linux内核的调度机制,通过分析其对系统性能的影响以及在多核处理器环境下的表现,揭示调度器如何平衡公平性和效率。文章进一步讨论了完全公平调度器(CFS)的设计细节,包括它如何处理不同优先级的任务、如何进行负载均衡以及它是如何适应现代多核架构的挑战。此外,本文还简要概述了Linux调度器的未来发展方向,包括对实时任务支持的改进和对异构计算环境的适应性。
21 6
|
5天前
|
缓存 Linux 开发者
Linux内核中的并发控制机制:深入理解与应用####
【10月更文挑战第21天】 本文旨在为读者提供一个全面的指南,探讨Linux操作系统中用于实现多线程和进程间同步的关键技术——并发控制机制。通过剖析互斥锁、自旋锁、读写锁等核心概念及其在实际场景中的应用,本文将帮助开发者更好地理解和运用这些工具来构建高效且稳定的应用程序。 ####
20 5
|
3天前
|
安全 网络协议 Linux
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。
本文详细介绍了 Linux 系统中 ping 命令的使用方法和技巧,涵盖基本用法、高级用法、实际应用案例及注意事项。通过掌握 ping 命令,读者可以轻松测试网络连通性、诊断网络问题并提升网络管理能力。
18 3
|
5天前
|
算法 Unix Linux
深入理解Linux内核调度器:原理与优化
本文探讨了Linux操作系统的心脏——内核调度器(Scheduler)的工作原理,以及如何通过参数调整和代码优化来提高系统性能。不同于常规摘要仅概述内容,本摘要旨在激发读者对Linux内核调度机制深层次运作的兴趣,并简要介绍文章将覆盖的关键话题,如调度算法、实时性增强及节能策略等。
|
6天前
|
安全 Linux 数据安全/隐私保护
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。
在 Linux 系统中,查找文件所有者是系统管理和安全审计的重要技能。本文介绍了使用 `ls -l` 和 `stat` 命令查找文件所有者的基本方法,以及通过文件路径、通配符和结合其他命令的高级技巧。还提供了实际案例分析和注意事项,帮助读者更好地掌握这一操作。
23 6
|
6天前
|
存储 监控 安全
Linux内核调优的艺术:从基础到高级###
本文深入探讨了Linux操作系统的心脏——内核的调优方法。文章首先概述了Linux内核的基本结构与工作原理,随后详细阐述了内核调优的重要性及基本原则。通过具体的参数调整示例(如sysctl、/proc/sys目录中的设置),文章展示了如何根据实际应用场景优化系统性能,包括提升CPU利用率、内存管理效率以及I/O性能等关键方面。最后,介绍了一些高级工具和技术,如perf、eBPF和SystemTap,用于更深层次的性能分析和问题定位。本文旨在为系统管理员和高级用户提供实用的内核调优策略,以最大化Linux系统的效率和稳定性。 ###