【002_音频开发_基础篇_Linux音频架构简介】

002_音频开发_基础篇_Linux音频架构简介

文章目录

  • 002_音频开发_基础篇_Linux音频架构简介
    • 创作背景
    • `Linux` 音频架构
    • `ALSA` 简介
    • `ASoC` 驱动
      • 硬件架构
      • 软件架构
        • `Machine`
        • `Platform`
        • `Codec`
      • `ASoC` 驱动 `PCM`
      • `ALSA`设备文件结构
    • `ALSA` 使用
      • 常用概念
      • `alsa-lib`
      • `ALSA` `Open` 流程
      • `ALSA` `Write` 流程
        • 2种写入方法
        • 2种读取方法
      • `Ring Buffer`
        • `Ring buffer` 管理

创作背景

学历代表过去、能力代表现在、学习力代表将来。 一个良好的学习方法是通过输出来倒逼自己输入。写博客既是对过去零散知识点的总结和复盘,也是参加了 零声教育 写博客活动。

零声教育体验课:https://xxetb.xetslk.com/s/3fbO81

本文是开发过程中的知识点总结,供大家学习交流使用,如有任何错误或不足之处,请在评论区指出。

Linux 音频架构

  • OSS (Open Sound System):是 Linux 系统上最早的音频接口系统之一。它提供了一个统一的接口来管理音频设备和音频数据的输入输出。但在发展过程中逐渐被 ALSA 替代。

  • ALSA (Advanced Linux Sound Architecture)

    • Linux 内核中的音频驱动架构,提供了对各种音频设备的支持,包括声卡、数字音频接口等。
    • ALSA 提供了一组 API 和工具,用于在 Linux 上进行音频编程和音频流处理。
    • 2002 年它被引进入Linux内核的开发版本(2.5.4-2.5.5)。
    • 2.6 版本开始 ALSA 成为 Linux 内核中默认的标准音频驱动程序集,OSS 则被标记为废弃。
    • 为了向后兼容,ALSA 提供内核模块来模拟 OSS,这样之前的许多在 OSS 基础上开发的应用程序不需要任何改动就可以在 ALSA 上运行。
    • libaoss 库也可以模拟 OSS,而它不需要内核模块。
  • ASoC (ALSA System on Chip)

    • ALSA 的一个子系统,专门用于在嵌入式系统中管理和配置与硬件集成的音频设备。ASoC 提供了一种灵活的框架,使得开发者能够轻松地将 ALSA 应用于各种嵌入式系统中的音频硬件。
    • ASoCALSASoC 方面的发展和演变,它在本质上仍然属于 ALSA,但是在 ALSA 架构的基础上对 CPU 相关的代码和 CODEC 相关的代码进行了分离。其原因是,采用传统 ALSA 架构的情况下,同一型号的 CODEC 工作于不同的 CPU 时,需要不同的驱动,这不符合代码重用的要求。

ALSA 简介

目前 linux 的主流音频体系架构,官网:http://www.alsa-project.org/

软件包名称描述
alsa-driver内核驱动程序,包括硬件相关的和一些公共代码。
alsa-libALSA 核心库,提供 ALSA API 的实现和访问接口。
需要包含头文件 asoundlib.h,链接共享库 libasound.so
alsa-utils包含 ALSA 工具,用于配置和管理 ALSA 音频设备。
alsa-tools包含用于测试和调试 ALSA 音频设备的工具。
alsa-plugins包含用于扩展 ALSA 功能的插件。
jack 模拟 alsa 接口。
oss 来模拟 alsa 接口。
alsa-firmware包含用于 ALSA 音频设备的固件文件。
alsa-ucm-confALSA UCM (Use Case Manager) 配置文件,用于管理音频设备的用例。
alsa-topology-confALSA 拓扑配置文件,用于配置音频设备的拓扑结构。
alsa-ossALSA OSS (Open Sound System) 兼容层,用于支持使用 OSS 接口的应用程序。
pyalsaPython 绑定,用于在 Python 中访问 ALSA API
tinycompressALSA 压缩库,用于与压缩音频硬件进行交互。

img_alsa_architecture

ASoC 驱动

硬件架构

img_asoc_driver_hardware_architecture

软件架构

img_asoc_driver_software_architecture

Machine
  • 是指某一款机器,可以是某款设备,某款开发板,又或者是某款智能手机。
  • 每个Machine上的硬件实现可能都不一样,CPU不一样,Codec不一样,音频的输入、输出设备也不一样。
  • MachineCPUCodec、输入输出设备提供了一个载体。
  • 单独的PlatformCodec驱动是不能工作的,它必须由Machine驱动把它们结合在一起才能完成整个设备的音频处理工作。
  • 例如:Rockchip_es8323就是一个Machine:
    img_asoc_machine_example
Platform
  • 一般是指某一个SoC平台,比如RK3229,S3c4430,MT6795等等。
  • 与音频相关的通常包含该SoC中的时钟、DMAI2SPCM等等。
  • 只要指定了SoC,那么我们可以认为它会有一个对应的Platform,它只与SoC相关,与Machine无关,这样我们就可以把Platform抽象出来。
  • 同一款SoC不用做任何的改动,就可以用在不同的Machine中。
  • 实际上,把Platform认为是某个SoC更好理解。
    img_asoc_platform_example
Codec
  • 字面上的意思就是编解码器,Codec里面包含了I2S接口、D/AA/DMixerPA(功放),通常包含多种输入(MicLine-inI2SPCM)和多个输出(耳机、喇叭、听筒,Line-out)。
  • Codec和Platform一样,是可重用的部件,同一个Codec可以被不同的Machine使用。
  • 嵌入式Codec通常通过I2C对内部的寄存器进行控制。
  • Controls就是对Codec输入输出的寄存器进行操作。
    img_asoc_codec_example

ASoC 驱动 PCM

img_asoc_pcm

  • 在实例化snd_card的时候进行创建,一个pcm实例由一个playback stream和一个capture stream组成,
  • 这两个stream又分别有一个或多个substreams组成。
  • 大多数情况下是一个声卡,一个pcm实例,pcm下面有一个playback streamcapture streamplaybackcapture下面各自有一个substream

ALSA设备文件结构

声卡初始化之后,会生成设备节点,以供上层调用,alsa驱动的设备文件结构,可以在/dev/snd下用ls查看,如下所示:

controlC0   -->                 用于声卡的控制,例如通道选择,混音,麦克风的控制等
pcmC0D0c  -->                用于录音的pcm设备
pcmC0D0p -->                用于播放的pcm设备
timer            -->                 定时器
  • alsa-driver中的命名规则:
    • C0代表的是声卡0
    • D0代表声卡中的设备0
    • pcmC0D0c最后一个c代表capture
    • pcmC0D0p最后一个p代表`playback

ALSA 使用

常用概念

  • 样本长度(sample, format): 样本是记录音频数据最基本的单位,计算机对每个通道采样量化时数字比特位数,常见的有162432位,也就是format
  • 通道数(channel): 1表示单声道/Mono2则是立体声/Stereo
  • 帧(frame): 构成一个完整的声音单元,Frame = Sample(format) * channel
  • 采样率(rate): 又称 sample rate,采样率,即每秒的采样次数,针对帧而言;常用的采样率如8KHz的人声, 44.1KHzmp3音乐, 96Khz的蓝光音频。
  • 周期(period): 每次硬件中断处理音频数据的帧数,对于音频设备的数据读写,以此为单位。
  • Buffer size: 数据缓冲区大小,这里指 runtimebuffer size,而不是结构图 snd_pcm_hardware 中定义的 buffer_bytes_max;一般来说 buffer_size = period_size * period_countperiod_count 相当于处理完一个 buffer 数据所需的硬件中断次数,一般就是DMA的中断。
  • 比特率(Bits Per Second): 比特率表示每秒的比特数,比特率=采样率×通道数×样本长度
  • 交错模式(interleaved): 是一种音频数据的记录方式,在交错模式下,数据以连续桢的形式存放,即首先记录完桢1的左声道样本和右声道样本(假设为立体声格式),再开始桢2的记录。
  • 非交错模式: 首先记录的是一个周期内所有桢的左声道样本,再记录右声道样本,数据是以连续通道的方式存储。不过多数情况下,我们只需要使用交错模式就可以了。

img_alsa_use_architecture

alsa-lib

  • 指用户空间的函数库,提供给应用程序使用,应用程序应包括头文件asoundlib.h。并使用共享库libasound.so
  • 应用程序开发者应该使用libasound而不是内核中的 ALSA接口。因为libasound提供最高级并且编程方便的编程接口。并且提供一个设备逻辑命名功能,这样开发者甚至不需要知道类似设备文件这样的低层接口。
  • 相反,OSS/Free驱动是在内核系统调用级上编程,它要求开发者提供设备文件名并且利用ioctrl来实现相应的功能。
  • ALSA包含插件功能,使用插件可以扩展新的声卡驱动,包括完全用软件实现的虚拟声卡。
  • ALSA提供一系列基于命令行的工具集,比如:
    • 混音器(mixer),
    • 音频文件播放器(aplay),
    • 以及控制特定声卡特定属性的工具。
  • AlSA本身也提供混音的plugin,dmix .

ALSA Open 流程

通过alsa lib的snd_pcm_open函数打开音频设备,这样间接会调用到驱动提供的接口:

  • open(fn, "/dev/snd/pcmC0D0p"):
    • 打开播放的PCM设备, 建立与驱动的联系。
  • ioctl(pcm->fd, SNDRV_PCM_IOCTL_HW_PARAMS):
    • 设置音频相关的参数,包括传输的formatchannelsrate等。
  • mmap(NULL, buffer_size):
    • 建立内存映射, 给应用直接访问设备内存的能力,当用户进程在分配的内存范围内读写时,实际就是访问是设备。
  • ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE):
    • 进行播放前的准备,通知widget更新电源状态,包括设置codecplatform相关寄存器,准备好进行播放。

ALSA Write 流程

应用通过 alsa-lib 里面的 API 函数 snd_pcm_writei 写入数据。

2种写入方法
  1. 通过 copy_form_user 把应用的音频数据拷贝到 DMA 中,然后通过 DMA 把数据发送到 SoCI2S 控制器的 FIFO,再到 codec,最后由喇叭或者手机播放。
    img_alsa_write_01
  2. 通过 mmap 建立内存映射,应用直接操作映射好的内存区域,相当于直接写到 DMA 中,然后通过 DMA 把数据发送到 SoCI2S 控制器的FIFO,再到codec,最后由喇叭或者手机播放。
    img_alsa_write_02
2种读取方法

与写入一样有两种方法:

  1. 通过 copy_to_user
  2. 通过 mmap

img_alsa_read

Ring Buffer

  • 播放时,应用程序把音频数据源源不断地写入 dma buffer 中, 然后相应 platformdma 操作则不停地从该 buffer 中取出数据,经 dai 送往 codec 中。
  • 录音时则正好相反,codec 源源不断地把 A/D 转换好的音频数据经过 dai 送入 dma buffer 中,而应用程序则不断地从该 buffer 中读走音频数据。

img_alsa_ring_buffer

Ring buffer 管理

alsa driver 使用 Ring Bufferdma buffer 进行管理:

  • Buffer size 就是一个 HW buffer(虚拟),相当于应用的 period * count,实际的 Buffer 大小。
  • snd_pcm_runtime.hw_ptr_base  环形缓冲区每一圈的基地址,当读写指针越过一圈后,它按 buffer size 进行移动;
  • snd_pcm_runtime.status->hw_ptr  硬件逻辑位置,播放时相当于读指针,录音时相当于写指针;
  • snd_pcm_runtime.control->appl_ptr 应用逻辑位置,播放时相当于写指针,录音时相当于读指针;
  • snd_pcm_runtime.boundary 扩展后的逻辑缓冲区大小,通常是(2^n)*size, runtime->boundary一般都是较大的数。 不是真实的缓冲区的地址 偏移,经过转换才得到 物理缓冲的偏移。

img_alsa_ring_buffer_02

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基础SQL DDL语句

MySQL的DDL(Data Definition Language)语句用于定义或修改数据库结构。 DDL数据库操作 查看所有的数据库 show databases; 红色圈起来的是系统数据库,是系统自带的 mysql:包含存储MySQL服务器运行时所需信息的表。这包括数据字典…

如何利用pg_dump和pg_restore迁移从一个PostgreSQL服务器到另一个服务器,同时保持一致性与高效性?

文章目录 解决方案1. 使用pg_dump导出数据2. 将导出的数据复制到目标服务器3. 使用pg_restore导入数据保持一致性与高效性的策略一致性高效性 示例代码导出数据复制数据到目标服务器在目标服务器上解压并导入数据 PostgreSQL数据库的迁移是一个常见的任务,特别是在升…

用Vue全家桶手工搓了一个高仿抖音源码 全开源

用Vue全家桶手工搓了一个高仿抖音,全开源 PC浏览器请用手机模式访问。先按F12调出控制台,再按CtrlShiftM切换到手机模式,手机请用Via浏览器或者Chrome浏览器预览。其他浏览器会强制将视频全屏,导致样式都失效。 运行项目&#x…

【C++】STL:vector常用接口的使用和模拟实现

Hello everybody!这篇文章主要给大家讲讲vector常用接口的模拟实现,STL库中的实现一层套着一层,十分复杂,目前阶段还不适合看源代码。而模拟实现可以让我们从底层上了解这些接口的原理从而更好的使用这些接口。另外我还会讲一些在vector使用过…

【第34天】SQL进阶-SQL高级技巧-Window Funtion(SQL 小虚竹)

回城传送–》《100天精通MYSQL从入门到就业》 文章目录 零、前言一、练习题目二、SQL思路初始化数据什么是Window Funtion窗口函数的分类语法结构第一种写法:第二种写法: 实战体验序号函数:row_number()序号函数:rank()序号函数&…

【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建+内核源码获取与配置+内核交叉编译+内核镜像挂载)

【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建内核源码获取与配置内核交叉编译内核镜像挂载) 文章目录 【树莓派Linux内核开发】入门实操篇(虚拟机Ubuntu环境搭建内核源码获取与配置内核交叉编译内核镜像挂载)一、搭建…

什么是0-day漏洞,怎么防护0-day漏洞攻击

随着信息技术的快速发展,网络安全问题日益凸显,其中0day漏洞攻击作为一种高级威胁手段,给企业和个人用户带来了极大的风险。下面德迅云安全就对0day漏洞攻击进行简单讲解下,并分享相应的一些安全措施,以期提高网络安全…

网络空间地图测绘理论体系白皮书(2023年)02网络空间测绘研究背景(想法比较好,着重看)

01前言 02 网络空间测绘研究背景 2.1 网络空间的起源 2.2 传统测绘理论 2.3 网络空间测绘相关工作 03 测绘体系框架概念定义 3.1 网络空间 3.2 网络空间地图测绘 3.3 体系框架总体思路 04 测绘体系框架应用实践 4.1 网络空间地形图 4.2 网络空间地志图 4.3 网络空间战略图 05 总…

Python 全栈安全(一)

原文:annas-archive.org/md5/712ab41a4ed6036d0e8214d788514d6b 译者:飞龙 协议:CC BY-NC-SA 4.0 前言 序言 多年前,我在亚马逊搜索了一本基于 Python 的应用程序安全书。我以为会有多本书可供选择。已经有了很多其他主题的 Pyt…

【ZYNQ】Zynq 芯片介绍

Zynq 是 Xilinx 公司提出的全可编程 SoC 架构,集成了单核或多核 ARM 处理器与 Xilinx 16nm 或 28nm 可编程逻辑,包括 Zynq 7000 Soc,Zynq UltraScale MPSoC 和 Zync UltraScale RFSoC 等系列。本文主要介绍 Xilinx Zynq 7000 系列芯片架构、功…

Hadoop1X,Hadoop2X和hadoop3X有很大的区别么?

Hadoop的演进从Hadoop 1到Hadoop 3主要是为了提供更高的效率、更好的资源管理、更高的可靠性以及对更多数据处理方式的支持。下面是Hadoop 1, Hadoop 2, 和 Hadoop 3之间的主要区别和演进的原因: Hadoop 1 特点: 主要包括两大核心组件:HDFS&a…

simple-jwt快速入门(包含自定制)

simple-jwt快速入门(包含自定制) 目录 simple-jwt快速入门(包含自定制)安装路由层视图层全局配置前端传入参数配置文件定制登录返回格式定制payload格式自定制签发-认证 安装 pip install djangorestframework-simplejwt路由层 from rest_framework_simplejwt.views import T…

【 AIGC 研究最新方向(上)】面向平面、视觉、时尚设计的高可用 AIGC 研究方向总结

目前面向平面、视觉、时尚等设计领域的高可用 AIGC 方向有以下 4 种: 透明图层生成可控生成图像定制化SVG 生成 本篇(上篇)介绍 1、2,而下篇将介绍 3、4。 透明图层生成 LayerDiffuse 代表性论文:Transparent Imag…

Qt基础之四十六:Qt界面中嵌入第三方程序的一点心得

本文主要讲解QWidget和QWindow的区别,以及如何在QWidget中嵌入第三方程序,并完美解决在QWidget中嵌入某些程序(比如Qt程序)时出现的白边问题。 下面是嵌入QQ音乐的样子,这首歌还不错。 先用spy++查看QQ音乐的窗口信息,如果安装了Visual Studio,工具菜单里自带spy++ 然后…

Spring Boot | Spring Boot 默认 “缓存管理“ 、Spring Boot “缓存注解“ 介绍

目录: 一、Spring Boot 默认 "缓存" 管理 :1.1 基础环境搭建① 准备数据② 创建项目③ 编写 "数据库表" 对应的 "实体类"④ 编写 "操作数据库" 的 Repository接口文件⑤ 编写 "业务操作列" Service文件⑥ 编写 "applic…

Redis入门到通关之数据结构解析-QuickList

文章目录 ☃️前提概要☃️ 配置项相关☃️简要源码☃️总结 Redis中的 QuickList 是一种特殊的数据结构,用于存储列表类型的数据。它的设计目的是在内存中高效地存储和操作大量的列表元素,尤其是当列表长度很大时。 QuickList的内部结构是一个由多个节…

政安晨:【Keras机器学习示例演绎】(八)—— 利用 PointNet 进行点云分割

目录 简介 导入 下载数据集 加载数据集 构建数据集 预处理 创建 TensorFlow 数据集 PointNet 模型 排列不变性 变换不变性 点之间的相互作用 实例化模型 训练 直观了解培训情况 推论 最后说明 政安晨的个人主页:政安晨 欢迎 👍点赞✍评论…

【PCL】教程 implicit_shape_model.cpp 3D点云数据的对象识别 利用隐式形状模型进行训练和识别...

ism_test_cat.pcd 参数:ism_train_cat.pcd 0 ism_train_horse.pcd 1 ism_train_lioness.pcd 2 ism_train_michael.pcd 3 ism_train_wolf.pcd 4 ism_test_cat.pcd 0 这里红点表示对应感兴趣类别的对象预测中心 ./ism_t…

字节FE:JavaScript学习路线图

JavaScript简介 JavaScript是一种高级的、解释执行的编程语言。它是互联网的三大核心技术之一,与HTML和CSS一同工作,用于创建交互式的网页。JavaScript被所有现代网页浏览器支持而不需要任何插件。它可以增强用户界面和网页的交互性,可以进行…

【讲解下Spring Boot单元测试】

🌈个人主页: 程序员不想敲代码啊 🏆CSDN优质创作者,CSDN实力新星,CSDN博客专家 👍点赞⭐评论⭐收藏 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共…