alsa框架与音频芯片移植基础

news2024/11/25 10:29:28

ALSA音频框架

Alsa是Advanced Linux Sound Architecture的缩写,即高级Linux声音架构,在Linux操作系统上提供了对音频和MIDI的支持。在Linux 2.6的内核版本后,Alsa目前已经成为了linux的主流音频体系结构。

除了 alsa-driver,ALSA 包含在用户空间的 alsa-lib 函数库,具有更加友好的编程接口,并且完全兼容于 OSS,开发者可以通过这些高级 API使用驱动,不必直接与内核驱动 API 进行交互。

一、系统框架

img

  • User空间:主要由Alsa Libray API对应用程序提供统一的API接口,各个APP应用程序只要调用 alsa-lib 提供的 API接口来实现放音、录音、控制。现在提供了两套基本的库,tinyalsa是一个简化的alsa-lib库,现在Android的系统中主要使用它。
  • ALSA CORE:alsa 核心层,向上提供逻辑设备(PCM/CTL/MIDI/TIMER/…)系统调用,向下驱动硬件设备(Machine/I2S/DMA/CODEC)
  • ASOC Core:是 ALSA 的标准框架,是 ALSA-driver 的核心部分,提供了各种音频设备驱动的通用方法和数据结构,为 Audio driver提供 ALSA Driver API
  • Hardware Driver:音频硬件设备驱动,由三大部分组成,分别是 Machine、Platform、Codec,提供的 ALSA Driver API 和相应音频设备的初始化及工作流程,实现具体的功能组件,这也是驱动开发人员需要具体实现的部分。

二、ASoC 硬件驱动结构

ASoC–ALSA System on Chip , 是建立在标准ALSA驱动层上, 为了更好地支持嵌入式处理器和移动设备中的音频Codec的一套软件体系.

嵌入式设备的音频系统可以被划分为板载硬件(Machine)、Soc(Platform)、Codec三大部分。

img

img

1. ASoC Platform Driver

指某款 SoC 平台的音频模块,如IMX6 等等。

包括 dma 和 cpu_dai 两部分:

  • dma:负责把 dma buffer 中的音频数据搬运到 I2S tx FIFO。音频 dma 驱动通过snd_soc_register_platform() 来注册。
  • cpu dai:指 SoC 的 I2S、PCM 总线控制器,负责把音频数据从 I2S tx FIFO 搬运到 CODEC(这是回放的情形,录制则方向相反)。cpu_dai 通过 snd_soc_register_dai() 来注册。

2. ASoC Machine Driver

作为链结 Platform 和 Codec 的载体,通过配置 dai_link 把 cpu_dai、codec_dai、modem_dai 各个音频接口给链结成一条条音频链路,然后注册 snd_soc_card。

  • snd_soc_dai_link:音频链路描述及板级操作函数,它指定链路用到的 codec、codec_dai、cpu_dai、platform,这四者就构成了一条音频数据链路用于多媒体声音的回放和录制。
  • snd_soc_dai_driver:音频数据接口描述及操作函数,根据 codec 端和 soc 端,分为 codec_dai 和 cpu_dai。
    • linux 4.4 内核中支持两种方式创建dai_driver, 一种是通用的simple-audio-card 架构(简单通用的 machine driver), 一种是传统的编写自定义的 machine driver 来创建。
  • snd_soc_codec_driver:音频编解码芯片描述及操作函数,如控件/微件/音频路由的描述信息、时钟配置、IO 控制等
  • snd_soc_platform_driver:音频 dma 设备描述及操作函数

1)simple-audio-card

简单通用的 machine driver, 是一个为了简化音频框架,在alsa上面的一个封装。如果 simple-audio-card 框架足够满足需求, 建议优先使用 simple-audio-card 框架。

simple-audio-card的框架主要配置说明

status:声卡目前的状态,目前是未激活;
compatible:设备文件中的的名字,系统靠这个去匹配驱动代码中的simple-audio-card层的驱动程序;
simple-audio-card,name:声卡在系统中的名字;
simple-audio-card,cpu {
      sound-dai:soc端的dai 配置,就是rk3399的spdif或i2s接口的配置;
}
simple-audio-card,codec {
      sound-dai:codec端的dai配置,就是soc外界codec的接口的配置,这里是虚拟声卡;
}

3. ASoC Codec Driver

Codec 字面意思是编解码器,可以是用于回放或录制音频的。对于回放来说,userspace 送过来的音频数据是经过采样量化的数字信号,在 codec 经过 DAC 转换成模拟信号然后输出到外放或耳机,这样就可以听到声音了(对于录制则相反)。

Codec 芯片里面的功能部件很多,常见的有 AIF、DAC、ADC、Mixer、PGA、Line-in、Line-out,有些高端的 codec 芯片还有 EQ、DSP、SRC、DRC、AGC、Echo-Canceller、Noise-Suppression 等部件。

img

Codec驱动主要提供以下特性:

  • Codec DAI 和 PCM的配置信息;
  • Codec的IO控制方式(I2C,SPI等);
  • Mixer和其他的音频控件;
  • Codec的ALSA音频操作接口;
  • DAPM描述信息;
  • DAPM事件处理程序;
  • DAC数字静音控制

1)dummy_codec

ASoC Codec Driver之一,dummy_codec 是虚拟声卡 ,在soc外部没有外接codec的情况下,为了匹配声卡驱动框架,虚拟的一个设备,类似于占位符之类的东西的作用。

对一些名词的解释:

  • Codec:编解码器, PCM:脉冲编码调制

    脉冲编码调制就是把一个时间连续,取值连续的模拟信号变换成时间离散,取值离散的数字信号后在信道信道中传输。脉冲编码调制就是对模拟信号先抽样,再对样值幅度量化编码的过程。

  • DAPM:Dynamic audio power management-动态电源管理

  • dai:[digital](javascript:😉 [audio](javascript:😉 [interface](javascript:😉-数字音频接口

三 、接口介绍

音频芯片数据时钟接口:

ADCDAT:ADC 数据输出引脚,采集到的音频数据转换为数字信号以后通过此引脚传输给主控制器。

ADCLRC:ADC 数据对齐时钟,也就是帧时钟(LRCK),用于切换左右声道数据,此信号的频率就是采样率。此引脚可以配置为 GPIO 功能,配置为 GPIO 以后 ADC 就会使用 DACLRC引脚作为帧时钟。

DACDAT:DAC 数据输入引脚,主控器通过此引脚将数字信号输入给 音频芯片 的 DAC。

DACLRC:DAC 数据对齐时钟,功能和 ADCLRC 一样,都是帧时钟(LRCK),用于切换左右声道数据,此信号的频率等于采样率。

BCLK:位时钟,用于同步。

MCLK:主时钟,工作的时候还需要一路主时钟

控制接口:

标准IIC,这个 I2C 接口用于配置音频芯片的工作模式等,用来cpu和codec间通信

SCLK

SDA

img

CPU-IIS接口:

用到四个引脚

SCLK:串行时钟信号

WS:字段(声道)选择信号

SDI:串行数据输入

SDO:串行数据输出

在总线上,只能同时存在一个主设备和发射设备;提供时钟的设备为主设备,可以是发射设备也可以是接收设备,或者是协

调两者的其他控制设备。在高端应用场合中,CODEX经常作为主设备以便精确控制IIS的数据流。

下面以8960为例介绍一下四种工作状态:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v0ZJuDfA-1670813790685)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220802144132738.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fHtFFDYJ-1670813790686)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220802144216834.png)]

四、时钟介绍和计算

下图是一个简单的时序图:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NjiA4J0K-1670813790686)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220802143536112.png)]

PCM是英文Pulse-code modulation的缩写,中文译名是脉冲编码调制。我们知道在现实生活中,人耳听到的声音是模拟信号,PCM就是要把声音从模拟转换成数字信号的一种技术,他的原理简单地说就是利用一个固定的频率对模拟信号进行采样,采样后的信号在波形上看就像一串连续的幅值不一的脉冲,把这些脉冲的幅值按一定的精度进行量化,这些量化后的数值被连续地输出、传输、处理或记录到存储介质中,所有这些组成了数字音频的产生过程。
img

  1.采样率(rate):也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。采样频率的倒数是采样周期或者叫作采样时间,它是采样之间的时间间隔。通俗的讲采样频率是指计算机每秒钟采集多少个声音样本,是描述声音文件的音质、音调,衡量声卡、声音文件的质量标准。采样频率常有:8khz,16khz,44.1khz,48khz。
  
  2.量化位数(bits):是对模拟音频信号的振幅进行的数字化。常用的8位,16位,32位。量化度越高,音频信号越可能接近原生信号。

  3.声道数(channels): 是指支持能不同发声的音响的个数,它是衡量音响设备的重要指标之一,一般分单声道和双通道。

  4.帧(frame):桢记录了一个声音单元,其长度为样本长度与通道数的乘积。其大小等于=bits *  channels /8  ,单位是btye。

  5.周期(period_size)  周期大小,即每次dma硬件中断处理音频数据的帧数。如果周期设定得较大,则单次处理的数据较多,这意味着单位时间内硬件中断的次数较少,CPU也就有更多时间处理其他任务,功耗也更低,但这样也带来一个显著的弊端——数据处理的时延(latency)会增大   period_size=frame*rate*framecount. framecount的值是底层定义好的。

  6.周期数(period_count)  应用程序缓存区的大小可以通过ALSA库函数调用来控制。缓存区可以很大,一次传输操作可能会导致不可接受的延迟,我们把它称为延时(latency)。为了解决这个问题,ALSA将缓存区拆分成一系列周期(period)(OSS/Free中叫片断fragments).ALSA以period为单元来传送数据。
     
  7.声音缓存(buffer)和数据传输:
每个声卡都有一个硬件缓存区来保存记录下来的样本。当缓存区足够满时,声卡将产生一个中断。内核声卡驱动然后使用直接内存(DMA)访问通道将样本传送到内存中的应用程序缓存区。类似地,对于回放,任何应用程序使用DMA将自己的缓存区数据传送到声卡的硬件缓存区中。
这样硬件缓存区是环缓存。也就是说当数据到达缓存区末尾时将重新回到缓存区的起始位置。ALSA维护一个指针来指向硬件缓存以及应用程序缓存区中数据操作的当前位置。从内核外部看,我们只对应用程序的缓存区感兴趣,所以本文只讨论应用程序缓存区。

应用程序缓存区的大小可以通过ALSA库函数调用来控制。缓存区可以很大,一次传输操作可能会导致不可接受的延迟,我们把它称为延时(latency)。为了解决这个问题,ALSA将缓存区拆分成一系列周期(period)(OSS/Free中叫片断fragments).ALSA以period为单元来传送数据。

一个周期(period)存储一些帧(frames)。每一帧包含时间上一个点所抓取的样本。对于立体声设备,一个帧会包含两个信道上的样本。分解过程:一个缓存区分解成周期,然后是帧,然后是样本。左右信道信息被交替地存储在一个帧内。这称为交错 (interleaved)模式。在非交错模式中,一个信道的所有样本数据存储在另外一个信道的数据之后。

时钟的计算公式:

mclk(主时钟)= fs(分频系数) x rclk(采样率)

bclk(位时钟)= rclk(采样率)x length x channel (帧长度)

参考链接:

(70条消息) Linux ALSA音频框架及RK3399 DTS音频配置_pingis58的博客-CSDN博客_alsa音频架构

(70条消息) RK3399 Audio驱动讲解_Free飝Fly的博客-CSDN博客_rk3399 音频

(70条消息) Linux ALSA声卡驱动之六:PCM的注册流程_Bill_xiao的博客-CSDN博客

(70条消息) Linux 音频驱动(一) ASoC音频框架简介__Modest_的博客-CSDN博客_音频驱动框架

(70条消息) wm8960介绍_北极……星的博客-CSDN博客_wm8960

(70条消息) Linux 音频驱动(三) ASoC音频驱动之Codec驱动__Modest_的博客-CSDN博客_snd_soc_codec_driver

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/84238.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CSS -- 使用纯CSS绘制三角形及常见案例汇总

文章目录1. 绘制原理2. 绘制最简单的三角形3. 绘制对话框4. 绘制两条直角边不等长的三角形1. 绘制原理 网页中常见一些三角形,使用 CSS 直接画出来就可以,不必做成图片或者字体图标 给每个边框不同的颜色可以看到,每个边框其实都是一个小三…

测试(缺陷管理)

目录 1.缺陷管理理论 1.1.定义 1.2缺陷的名称 1.3.产生缺陷的原因 1.4.缺陷管理流程 1.5.缺陷管理生命周期与状态 2.如何提交缺陷 2.1.提交的Bug的目的 2.2.提交Bug的注意事项 2.3.提交Bug报告应遵循的原则 2.4.Bug报告需包含哪些内容 1.缺陷管理理论 1.1.定义 软件…

rust编程-rust所有权理解(chapter 4.3 Slice切片类型)

目录 3. 切片(Slice)类型 3.1 String slice(字符串切片) 3.2 其它切片 3. 切片(Slice)类型 切片可以用来获取一个集合中连续的元素序列,且切片是一种引用类型,因此不具有所有权。 如下是一个小的编程示…

day17_面向对象的三大特征之一(多态)

概述 多态是继封装、继承之后,面向对象的第三大特性。 生活中,比如求面积的功能,圆、矩形、三角形实现起来是不一样的。跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞的动作,昆虫、鸟类和飞机&a…

【数字IC设计】Design Compiler入门

本博客参考自文章链接 本文以全加器为例,演示DC综合的流程。设计文件如下: module full_adder( input clk, input rstn, input [31:0] a_in, input [31:0] b_in, input c_in, output reg [31:0] sum_out, output reg c_out ); wire c_out_w; wire [31:0…

[vue学习笔记]数组+事件+v-model的使用

1.关于数组的使用以及常见的函数 (1)在队尾操作函数:push():追加,pop():删除 arr.push(9,8,7,6); 这种批量追加的方式也是被允许的 (2&#xf…

Gem5模拟器,关于Adding parameters to SimObjects and more events的一些问题记录(六)

目录 (1)为什么Gem是Python和C混合使用编程? (2)关于析构函数 创建类的时候一般都需要写上析构函数吗? (3)关于HelloObject和GoodbyeObject的先后后创建关系 (1&…

C# 类 字段 方法

一 现实中的实物抽象为类 类(class)最基本的要素是 ① 字段(field):变量; ② 方法(method):函数; class Person {public string name;public int age;public void SayHello(){Console.WriteLine("Hello!My name is"name);}public string Ge…

(Python)第2章-12 输出三角形面积和周长 (15 分)

Python解决输入三条边输出面积与周长1.问题2.解决思路代码在孤单的日子里,你单枪匹马奋斗的样子酷毙了。江客:时荒![在这里插入图片描述](https://img-blog.csdnimg.cn/85fc4495dcfc4578a8612a432d8045cd.png#pic_center)1.问题 本题要求编写程序&#…

Arduino Uno零基础入门学习笔记——变量与函数

文章目录一、创建变量二、函数三、delay的例子总结一、创建变量 int currentTemperature;整数型变量 变量名字 分号 使用驼峰命名法对进行命名 有些程序员喜欢全部小写,有些程序员喜欢用下划线,所以如果要写一个my name的变量,他们常用的写…

vue3中的propemit

状态是什么: 页面中要显示的东西,放在一个变量中,每次更改完值,就会被拦截,同时再重新渲染页面; 状态的对立面就是属性; 可以没有状态,那只能用父组件传过来的属性来自己用&#…

Saga 模式

Saga 模式目录概述需求:设计思路实现思路分析1.2.适用场景:3.缺点:4.Saga的实现:参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy,skip hardness,ma…

mysql数据恢复,mysql数据备份,详细聊聊mysql数据备份与恢复

文章目录写在前面数据备份与恢复1、全量备份模拟全量备份与恢复全量备份的缺点2、增量备份模拟增量备份与恢复增量备份注意事项总结写在前面 作为互联网开发人员来说,数据安全性一直排在第一位的重中之重。 mysql作为关系型数据库的一个巨头,其备份与恢…

从GNU/Linux看国产操作系统的安全可控性

作者:IT圈黎俊杰 在信创的春风下,做为IT基础软件三驾马车之一的操作系统,自然是国产化替代的重点,再加上一直以来被大家当成”免费RedHat Enterprise Linux“的CentOS因被redhat收购,并宣布于2021年12月31日起在停止维…

SpringBoot+SpringCloud微服务搭建全过程(一)

一:什么是SpringBoot 1. SpringBoot不是一个全新的框架,而是对Spring框架的一个封装。所以,以前Spring可以做的事情,现在用SpringBoot都可以做。 2. SpringBoot整合了很多优秀的框架,用来简化Spring应用搭建和开发过程&#xff…

java项目_第171期ssm房屋租赁系统_计算机毕业设计

java项目_第171期ssm房屋租赁系统_计算机毕业设计 【源码请到下载专栏下载】 今天分享的项目是《ssm房屋租赁系统》 该项目分为2个角色,管理员和用户。 用户可以浏览前台,查看房屋租赁情况,并且进行租赁。 还可以登录到后台,进行租赁订单管理…

【20221212】【每日一题】一和零

给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度,该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素,集合 x 是集合 y 的 子集 。 思路:背包有两个维度:m、n。不…

【工作项目总结】交易系统

写工作项目总结的目的就是,明明自己工作中负责了一些模块也写了很多代码,解决了不少坑。但是面试的时候,总是记不起来在自己过往做的项目中,该项目的具体亮点难点分别是什么,有哪些令人印象深刻的问题,以及是如何解决它的。那么记录问题与解决思维就是我创作这个工作复盘…

C#连接蓝牙设备

看过各种博主的文章,发现基本上都是属于误人子弟的狗屁文章,踩过各种坑最终实现了此功能。 1.思路 电脑蓝牙和蓝牙模块配对连接 和我们平时正常连接蓝牙设备一样,需要先搜索附近的蓝牙设备,然后根据设备名来选择要连接的蓝牙模块…

VSCODE 系列(六)使用Plantuml插件制作UML类图

文章目录前言下载和安装支持文件格式支持绘制类型导出语法申报要素UML类图关系参考例子参考前言 软件设计中,有好几种图需要画,比如流程图、类图、组件图等,我知道大部分人画流程图一般都会用微软的visio绘制,visio画图有个不好的…