百问网全志系列开发板音频ALSA配置步骤详解

8 ALSA

8.1 音频相关概念

​ 音频信号是一种连续变化的模拟信号,但计算机只能处理和记录二进制的数字信号,由自然音源得到的音频信号必须经过一定的变换,成为数字音频信号之后,才能送到计算机中作进一步的处理。

​ 数字音频系统通过将声波的波型转换成一系列二进制数据,来实现对原始声音的重现,实现这一步骤的设备常被称为(A/D)。A/D转换器以每秒钟上万次的速率对声波进行采样,每个采样点都记录下了原始模拟声波在某一时刻的状态,通常称之为样本(sample),而每一秒钟所采样的数目则称为采样频率,通过将一串连续的样本连接起来,就可以在计算机中描述一段声音了。对于采样过程中的每一个样本来说,数字音频系统会分配一定存储位来记录声波的振幅,一般称之为采样分辩率或者采样精度,采样精度越高,声音还原时就会越细腻。

​ 数字音频涉及到的概念非常多,对于在Linux下进行音频编程的程序员来说,最重要的是7406解声音数字化的两个关键步骤:采样和量化。

  • 采样就是每隔一定时间就读一次声音信号的幅度,从本质上讲,采样是时间上的数字化。

  • 量化则是将采样得到的声音信号幅度转换为数字值,从本质上讲,量化则是幅度上的数字化。

8.1.1 采样频率

​ 采样频率是指将模拟声音波形进行数字化时,每秒钟抽取声波幅度样本的次数。采样频率的选择应该遵循奈奎斯特(Harry Nyquist)采样理论:如果对某一模拟信号进行采样,则采样后可还原的最高信号频率只有采样频率的一半,或者说只要采样频率高于输入信号最高频率的两倍,就能从采样信号系列重构原始信号。

​ 如上图所示 用40KHz的频率去采样20KHz的信号可以正确捕捉到原始信号。用30KHz的频率去采样20KHz的信号会出现混淆信号。

​ 一般重建音乐信号时采用的最低采样频率为44.1KHz。在许多高品质的系统中,采用的48KHz的采样频率。

系统采样频率
电话8000Hz
CD44100Hz
专业音频48000Hz
DVD音频96000Hz

8.1.2 量化位数

​ 量化位数是对模拟音频信号的幅度进行数字化,它决定了模拟信号数字化以后的动态范围,常用的有8位、12位和16位。量化位越高,信号的动态范围越大,数字化后的音频信号就越可能接近原始信号,但所需要的存贮空间也越大。

​ 音频应用中常用的数字表示方法为脉冲编码调制(Pulse-Code-Modulated,PCM)信号。在这种表示方法中,每个采样周期用一个数字电平对模拟信号的幅度进行编码。得到的数字波形是一组采样自输入模拟波形的近似值。由于所有A/D转换器的分辨率都是有限的,所以在数字音频系统中,A/D转换器带来的量化噪声是不可避免的。

8.2 ALSA架构

​ ALSA全称是Advanced Linux Sound Architecture,中文音译是Linux高级声音体系。ALSA 是Linux内核2.6后续版本中支持音频系统的标准接口程序,由ALSA库、内核驱动和相关测 试开发工具组成,更好的管理Linux中音频系统。

​ 本小节将介绍ALSA的架构。

8.2.1 ALSA架构介绍

​ ALSA是Linux系统中为声卡提供驱动的内核组件。它提供了专门的库函数来简化相应应用程序的编写。相较于OSS的编程接口,ALSA的函数库更加便于使用。

​ 对应用程序而言ALSA无疑是一个更佳的选择,因为它具有更加友好的编程接口,并且完全兼容于OSS。

​ ALSA系统包括7个子项目:

  • 驱动包alsa-driver
  • 开发包alsa-libs
  • 开发包插件alsa-libplugins
  • 设置管理工具包alsa-utils
  • OSS接口兼容模拟层工具alsa-oss
  • 特殊音频固件支持包alsa-finnware
  • 其他声音相关处理小程序包alsa-tools

ALSA声卡驱动与用户空间体系结构交互如下图所示:

8.3 移植ALSA库及工具

移植ALSA主要是移植alsa-Ub和alsa-utils。

  • alsa-lib:用户空间函数库, 封装驱动提供的抽象接口, 通过文件libasound.so提供API给应用程序使用。

  • alsa-utils:实用工具包,通过调用alsa-lib实现播放音频(aplay)、录音(arecord) 等工具。

​ ALSA Util是纯应用层的软件,相当于ALSA设备的测试程序,ALSA-Lib则是支持应用API的中间层程序,ALSA-Util中的应用程序中会调用到ALSA-Lib中的接口来操作到我们的音频编解码芯片的寄存器,而lib中接口就是依赖于最底层驱动代码,因此移植ALSA程序的顺序就是先后移植Driver,Lib,Util。

8.3.1 ALSA库下载

​ ALSA首先需要在ALSA的官网上下载官网http://www.alsa-project.org下载alsa-lib和alsa-utils。

如上图所示我们下载的版本为:

  • alsa-lib-1.2.2.tar.bz2
  • alsa-utils-1.2.2.tar.bz2

8.3.2 ALSA Lib编译

​ ALSA Lib移植不需要修改源码,只需要重新编译库代码以支持自己的平台。

tar -xvf alsa-lib-1.0.27.2.tar.bz2 
cd alsa-lib-1.0.27.2  
CC=arm-none-linux-gnueabi-gcc
./configure --host=arm-linux  --prefix=/home/m/3rd/alsa/install/  
make  
make install 

​ 在上述命令中./configure配置的几个重要的配置选项解释如下:

  • –host指定编译器,这里指定为交叉编译器,运行本配置命令前务必保证编译器已经可以在Shell下可以直接执行了。

  • –prefix指定编译后文件的安装路径,这样安装命令就还会指定的这个目录中创建lib和include两个目录。

8.3.3 ALSA Util编译

​ ALSA Util可以生成用于播放,录制,配置音频的应用可执行文件,测试驱动代码时用处很大,编译过程如下:

tar -xvf alsa-utils-1.0.27.2.tar.bz2  
cd alsa-utils-1.0.27.2  
CC=arm-none-linux-gnueabi-gcc 
./configure --prefix=/home/m/3rd/alsa/install/ --host=arm-linux --with-alsa-inc-prefix=/home/m/3rd/alsa/install/include --with-alsa-prefix=/home/m/3rd/alsa/install/lib --disable-alsamixer --disable-xmlto --disable-nls  
make  

8.3.4 ALSA库和工具移植入嵌入式平台

​ ALSA库和测试工具的移植就是将相应库文件和可执行文件放在目标板上,以下文件 必须被拷贝至对应位置 :
while (r > 0)
{
snd_pcm_wait(handle, 100);
do
{
res = snd_pcm_writei(handle, input_buffer, frames);
if (res == -EPIPE){
AUDIO_DEV_UNLOCK;
snd_pcm_prepare(handle);
continue;
}
}while (res < 0);
r -= err;
input_buffer += res * bits_per_frame / 8;
}
return 0;
}


## 8.9 基于ALSA音频的录制### 8.9.1 程序设计- 文件列表| 序号 | 文件名          | 描述           |
| ---- | --------------- | -------------- |
| 1    | AlsaCapture.h   | 音频录制头文件 |
| 2    | AlsaCapture.cpp | 音频录制程序   |- 成员函数设计| 序号 | 函数名  | 参数 | 参数描述 | 函数描述 |
| ---- | ------- | ---- | -------- | -------- |
| 1    | capture | 无   |          | 录制音频 |- 成员变量设计| 序号 | 成员变量名     | 类型              | 描述                 |
| ---- | -------------- | ----------------- | -------------------- |
| 1    | _VOLUMECHANGE  | const float       | 音量调节步进大小     |
| 2    | handle         | snd_mixer_t*      | Mixer handle         |
| 3    | element_handle | snd_mixer_elem_t* | Mixer element handle |
| 4    | minVolume      | long              | 最小音量             |
| 5    | maxVolume      | long              | 最大音量             |### 8.9.2 AlsaPlay类的定义```c
#pragma once
#include "AlsaBase.h"
namespace rv1108_audio{class AlsaCapture : public AlsaBase
{public:// 输出数据缓存char *output_buffer;// 输出缓存大小unsigned int output_buffer_size;// int frames_to_read;// 用于返回已读的帧数int frames_readed;AlsaCapture(const std::string &dev);~AlsaCapture();int open_device();int capture();private:int err;
};}

8.9.3 AlsaCapture类中成员函数的实现

  • AlsaCapture类的构造函数
AlsaCapture::AlsaCapture(const std::string &dev) : AlsaBase(dev)
{if (!DEVICE_OPENED)open_device();if (!PARAMS_SETED)set_params();output_buffer_size = default_output_buffer_size;output_buffer = (char *)calloc(output_buffer_size, sizeof(char));
}
int AlsaCapture::open_device()
{if ((err = snd_pcm_open(&handle,device,SND_PCM_STREAM_CAPTURE,0)) < 0){ DEVICE_OPENED = false;return -1;}else{DEVICE_OPENED = true;}return 0;
}
  • AlsaCapture类的构造函数
int AlsaCapture::capture()
{while (1){int err;if ((frames_readed = snd_pcm_readi(handle, output_buffer, frames)) < 0){// Overrun happenedif (frames_readed == -EPIPE){snd_pcm_prepare(handle);continue;}return -1;}else{return frames_readed;}}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统重装简记

写在文章开头 因为固态损毁而更换固态&#xff0c;所以需要进行系统重装&#xff0c;由于系统重装都是固定的繁琐的步骤&#xff0c;所以就以这篇文章来记录一下系统重装的一些日常步骤&#xff0c;希望对你有帮助。 Hi&#xff0c;我是 sharkChili &#xff0c;是个不断在硬核…

《Linux运维总结:基于x86_64架构CPU使用docker-compose一键离线部署etcd 3.5.15容器版分布式集群》

总结&#xff1a;整理不易&#xff0c;如果对你有帮助&#xff0c;可否点赞关注一下&#xff1f; 更多详细内容请参考&#xff1a;《Linux运维篇&#xff1a;Linux系统运维指南》 一、部署背景 由于业务系统的特殊性&#xff0c;我们需要面对不同的客户部署业务系统&#xff0…

【网编】——UDP编程

宏观操作 服务器&#xff1a;socket创套接字—bind绑定连接—recvfrom接收数据/sendto发送数据 客户端&#xff1a;socket创套接字—sendto发送数/recvfrom接收数据—close关闭套接字 函数 recv ssize_t recvfrom ( int sockfd , void * buf , size_t len , int flags , str…

链接Mysql 报错connection errors; unblock with ‘mysqladmin flush-hosts‘错误的解决方法!亲测有效!

文章目录 前言一、使用 mysqladmin flush-hosts 命令解锁 IP 地址二、增加 max_connect_errors 参数三、检查连接错误的原因 前言 今天正常的对各大的测试服进行重启的时候发现每台服务器都启动失败&#xff01;查看日志发现每台服务器都报一下的错误 java.sql.SQLException:…

【学习笔记】Day 13

一、进度概述 1、《地震勘探原理》第六章 二、详情 个人感觉第五&#xff0c;六&#xff0c;八章的解释更倾向于地质学那边负责的&#xff0c;但是多了解相关原理&#xff0c;肯定是有利于 DL-FWI 的相关研究的&#xff0c;所以这里只是做一个粗略的归纳&#xff0c;相关内容详…

android车载手机互联投屏新专题-实战作业布置

背景&#xff1a; 学习了马哥的投屏实战开发课程后&#xff0c;大家都可以实现如下图一样的手机车机多端互联的投屏场景。 即已经实现了手机和车机投屏互动&#xff0c;车机上手机画面屏幕可以与手机实体屏幕一样就是常见的Mirror模式&#xff0c;如果不一样就是课程里面讲的扩…

【策略模式】设计模式系列:在Java中实现灵活的行为选择(实战指南)

文章目录 策略模式&#xff1a;在Java中实现灵活的行为选择引言1. 策略模式的组成1.1 抽象策略 (Strategy)1.2 具体策略 (Concrete Strategy)1.3 上下文 (Context)1.4 UML类图和时序图 2. 策略模式在Java中的实现步骤一&#xff1a;定义抽象策略接口步骤二&#xff1a;创建具体…

波涛汹涌的海面:适用于恶劣环境的水冷电阻器

电阻器液体冷却可提升 3.3kV 中压负载&#xff0c;并大幅减少工业和船舶应用中的电阻器占用空间。在起重机、升降机、升降机和输送机等电机驱动应用中&#xff0c;风冷电阻器很常见&#xff0c;但在中压、高功率应用中&#xff0c;液体冷却胜出。 使用 3.3kV 电源运行以转动 5…

vue前端可以完整的显示编辑子级部门,用户管理可以为用户分配角色和部门?

用户和角色是一对多的关系用户和部门是多对多得关系<template><div class="s"><!-- 操作按钮 --><div class="shang"><el-input v-model="searchText" placeholder="请输入搜索关键词" style="width:…

MySQL的InnoDB的页里面存了些什么 --InnoDB存储梳理(三)

文章目录 创建新表页的信息新增一条数据根据页号找数据信息脚本代码py_innodb_page_info根据地址计算页号根据页号计算起始地址 主要介绍表空间索引页里面有哪些内容&#xff0c;数据在表空间文件里面是怎么组织的 创建新表页的信息 CREATE TABLE test8 (id bigint(20) NOT N…

跟着iMeta学做图|ggplot2绘制多个饼图展示菌群物种组成

原始教程链接&#xff1a;https://github.com/iMetaScience/iMetaPlot/tree/main/221017multi-pieplot 写在前面 饼图 (Pie Plot) 在微生物组研究中可以用来展示菌群物种组成&#xff0c;可以起到与堆叠柱状图相同的展示效果。本期我们挑选2022年4月5日刊登在iMeta上的The imp…

服务器安装哪吒面板详细教程

本文长期更新地址&#xff1a; 服务器安装哪吒面板详细教程-星零岁的博客https://blog.0xwl.com/13568.html 注&#xff1a;本文中部分内容源自网络&#xff0c;第四步中部分来自本人曾经文章&#xff1a;云服务器安装配置宝塔面板并安装基础运行环境教程-星零岁的博客 今天来讲…

VGMShield:揭秘视频生成模型滥用的检测与追踪技术

人工智能咨询培训老师叶梓 转载标明出处 视频生成模型&#xff0c;如 Stable Video Diffusion 和 Videocrafter&#xff0c;已经能够生成合理且高分辨率的视频。但这些技术进步也带来了被恶意利用的风险&#xff0c;比如用于制造假新闻或进行政治宣传。因此&#xff0c;来自弗…

前端学习大纲 | 主流前端技术 | 学习路线

需要完整的学习路线的宝子可以点击获取&#xff1a;点击即可获取完整的学习路线 第一阶段&#xff08;页面还原能力&#xff09; HTML5、CSS3、Git 第二阶段&#xff08;专攻 JS 逻辑能力&#xff09; JavaScript 基础、JavaScript 进阶、JavaScript 高级、ES6 第三阶段&a…

Leetcode面试经典150题-125.验证回文串

解法都在代码里&#xff0c;不懂就留言或者私信 class Solution {/**这题目感觉不是算法题&#xff0c;应该是考coding的细节点&#xff0c;比如如何判断两个字符是否equals&#xff08;大小写要equals&#xff09;空格要忽略&#xff0c;感觉就是纯coding&#xff0c;难道是为…

城市信息模型:构建未来智慧城市之基底座

在智慧城市的宏大叙事中&#xff0c;城市信息模型&#xff08;City Information Model, CIM&#xff09;平台如同城市智能的神经中枢&#xff0c;将数据、空间与技术深度融合&#xff0c;为城市规划、管理、服务、居民生活提供了前所未有的洞察与优化途径。CIM平台的构建不仅是…

【鸿蒙学习】HarmonyOS应用开发者基础 - 构建更加丰富的页面之Tabs(三)

学完时间&#xff1a;2024年8月14日 一、前言叨叨 学习HarmonyOS的第六课&#xff0c;人数又成功的降了500名左右&#xff0c;到了3575人了。 本文接上一文章【鸿蒙学习】HarmonyOS应用开发者基础 - 构建更加丰富的页面&#xff08;一&#xff09;&#xff0c;继续记录构建更…

微信小程序预览PDF、H5预览PDF、网页预览PDF,并添加专属文字水印

下载PDF.js 点击PDF.js下载地址 引入预览PDF 文件 // const url new URL("./1.pdf", import.meta.url).href // 在本地项目获取pdf // const url "https://xxxx/05d833041f.pdf" // 在线上链接获取pdf const url query.get(url) // 在地址栏获取pdf c…

【STM32项目】在FreeRtos背景下的实战项目的实现过程(一)

个人主页~ 这篇文章是我亲身经历的&#xff0c;在做完一个项目之后总结的经验&#xff0c;虽然我没有将整个项目给放出来&#xff0c;因为这项目确实也是花了米让导师指导的&#xff0c;但是这个过程对于STM32的实战项目开发都是非常好用的&#xff0c;可以说按照这个过程&…

c++ - 特殊类设计

文章目录 一、设计一个不允许拷贝的类二、设计一个只能在堆上实例对象的类三、设计一个只能在栈上创建对象的类四、设计一个不能被继承的类五、设计一个只能创建一个对象的类&#xff08;单例模式&#xff09; 一、设计一个不允许拷贝的类 1、方法一&#xff1a;将拷贝构造和赋…