【音频驱动】Linux之ALSA声卡、WAV文件相关概念

Linux之ALSA音频相关概念

一、ALSA简介

​ ALSA是Advanced Linux Sound Architecture,高级Linux声音架构的简称,它在Linux操作系统上提供了音频和MIDI(Musical Instrument Digital Interface,音乐设备数字化接口)的支持。在2.6系列内核中,ALSA已经成为默认的声音子系统,用来替换2.4系列内核中的OSS(Open Sound System,开放声音系统)。

​ ALSA的主要特性包括:高效地支持从消费类入门级声卡到专业级音频设备所有类型的音频接口,完全模块化的设计, 支持对称多处理(SMP)和线程安全,对OSS的向后兼容,以及提供了用户空间的alsa-lib库来简化应用程序的开发。

在应用层, ALSA 为我们提供了一套标准的 API,应用程序只需要调用这些 API 就可完成对底层音频硬
件设备的控制, 譬如播放、录音等, 这一套 API 称为 alsa-lib。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IagvEmyd-1680762065823)(image/Linux之ALSA声卡应用驱动/1680752749018.png)]

二、音频相关概念

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

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

理解声音数字化的两个关键步骤:采样量化

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QgJIZGcb-1680762065824)(image/Linux之ALSA声卡应用驱动/1680753135165.png)]

1、采样频率

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

在这里插入图片描述

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

​ 一般重建音乐信号时采用的最低采样频率为44.1KHz

2、量化位数(ADC精度)

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

​ 音频应用中常用的数字表示方法为脉冲编码调制**(Pulse-Code-Modulated,PCM)**信号。在这种表示方法中,每个采样周期用一个数字电平对模拟信号的幅度进行编码。得到的数字波形是一组采样自输入模拟波形的近似值。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w02Cj4j4-1680762065826)(image/Linux之ALSA声卡应用驱动/1680753385724.png)]

3、声道数

分为单声道(Mono)和双声道/立体声(Stereo)。 1 表示单声道、 2 表示立体声。

4、交错模式

交错模式是一种音频数据的记录方式,分为交错模式和非交错模式。 在交错模式下,数据以连续桢的形
式存放,即首先记录完桢 1 的左声道样本和右声道样本(假设为立体声格式),再记录桢 2 的左声道样本和
右声道样本。而在非交错模式下,首先记录的是一个周期内所有桢的左声道样本,再记录右声道样本,数据是以连续通道的方式存储。不过多数情况下, 我们一般都是使用交错模式。

三、WAV文件

wav是最常见的声音文件格式之一。wav是微软公司专门为Windows开发的一种标准数字音频文件,该文件能记录各种单声道或立体声的声音信息,并能保证声音不失真。但WAV文件有一个致命的缺点,就是它所占用的磁盘空间太大(每分钟的音乐大约需要12兆磁盘空间)。它符合资源互换文件格式(RIFF)规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持。Wave格式支持MSADPCM、CCITT A律、CCITT μ律和其他压缩算法,支持多种音频位数、采样频率和声道,是PC机上最为流行的声音文件格式;但其文件尺寸较大,多用于存储简短的声音片段。

1、编码格式

PCM编码是直接存储声波采样被量化后所产生的非压缩数据,故被视为单纯的无损耗编码格式,其优点是可获得高质量的音频信号。
基于PCM编码的WAV格式是最基本的WAV格式,被声卡直接支持,能直接存储采样的声音数据,所存储的数据能直接通过声卡播放,还原的波形曲线与原始声音波形十分接近,播放的声音质量是一流的,在Windows平台下被支持得最好,常常被用作在其它编码的文件之间转换的中间文件。PCM的缺点是文件体积过大,不适合长时间记录。正因为如此,又出现了多种在PCM编码的基础上经改进发展起来的编码格式,如:DPCM,ADPCM编码等。

2、文件格式

​ 在Windows环境下,大部分多媒体文件都是按照资源互换文件格式(Resources lnterchange File Format) 存放信息,简称RIFF格式。构成RIFF文件的基本单位称之为块(chunk)。每个RIFF文档是由若干个块构成每个块(chunk)由块标识、块长度及数据等三部分所组成,

​ WAV文件采用的是RIFF格式结构。至少是由3个块构成,分别是RIFFfmtData

  • WAVE 文件结构 :
RIFF 块
文件格式类型“WAVE”
fmt 块
fact 块(压缩编码格式要含有该块)
data 块
  • RIFF块结构:
块标识(4Bytes)
块长度(4Bytes)
数据

数据结构:

typedef struct WAV_RIFF {
    
    
char 	  ChunkID[4]; /* "RIFF" */
u_int32_t ChunkSize; /* 从下一个地址开始到文件末尾的总字节数 */
char      Format[4]; /* "WAVE" */
} __attribute__ ((packed)) RIFF_t;

/* __attribute__ ((packed)) */
/* 告诉编译器取消结构在编译过程中的优化对齐,按照实际占用字节数进行对齐, */
  • fmt块结构
偏移 地址 字节数 数据 类型 字段名称 字段说明
00H 4 字符 文档标识 大写字符串"RIFF",标明该文件为有效的 RIFF 格式文档。
04H 4 长整型数 文件数据长度 从下一个字段首地址开始到文件末尾的总字节数。该字段的数值加 8 为当前文件的实际长度。
08H 4 字符 文件格式类型 所有 WAV 格式的文件此处为字符串"WAVE",标明该文件是 WAV 格式文件。
0CH 4 字符 格式块标识 小写字符串,"fmt "。
10H 4 长整型数 格式块长度。 其数值不确定,取决于编码格式。可以是 16、 18 、20、40 等。(见表 2)
14H 2 整型数 编码格式代码。 常见的 WAV 文件使用 PCM 脉冲编码调制格式,该数值通常为 1。(见表 3)
16H 2 整型数 声道个数 单声道为 1,立体声或双声道为 2
18H 4 长整型数 采样频率 每个声道单位时间采样次数。常用的采样频率有 11025, 22050 和 44100 kHz。
1CH 4 长整型数 数据传输速率, 该数值为:声道数×采样频率×每样本的数据位数/8。播放软件利用此值可以估计缓冲区的大小。
20H 2 整型数 数据块对齐单位 采样帧大小。该数值为:声道数×位数/8。播放软件需要一次处理多个该值大小的字节数据,用该数值调整缓冲区。
22H 2 整型数 采样位数 存储每个采样值所用的二进制数位数。常见的位数有 4、8、12、16、24、32
24H 对基本格式块的扩充部分(详见扩展格式块,格式块的扩充)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VfWRMUxt-1680762065826)(image/Linux之ALSA声卡应用驱动/1680759110295.png)]

数据结构如下:

typedef struct WAV_FMT {
    
    
char Subchunk1ID[4]; /* "fmt " */
u_int32_t Subchunk1Size; /* 16 for PCM */
u_int16_t AudioFormat; /* PCM = 1*/
u_int16_t NumChannels; /* Mono = 1, Stereo = 2, etc. */
u_int32_t SampleRate; /* 8000, 44100, etc. */
u_int32_t ByteRate; /* = SampleRate * NumChannels * BitsPerSample/8 */
u_int16_t BlockAlign; /* = NumChannels * BitsPerSample/8 */
u_int16_t BitsPerSample; /* 8bits, 16bits, etc. */
} __attribute__ ((packed)) FMT_t;
  • data块结构如下:
数据(4bit)
数据大小(32bit)

数据结构如下:

typedef struct WAV_DATA {
    
    
char Subchunk2ID[4]; /* "data" */
u_int32_t Subchunk2Size; /* data size */
} __attribute__ ((packed)) DATA_t;

3、WAV文件格式实例分析

【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )_wav文件头格式_韩曙亮的博客-CSDN博客

参考资料

【音频处理】WAV 文件格式分析 ( 逐个字节解析文件头 | 相关字段的计算公式 )_wav文件头格式_韩曙亮的博客-CSDN博客

史上全最的WAV格式详解 - 掘金 (juejin.cn)

wav文件格式分析与详解 - nigaopeng - 博客园 (cnblogs.com)

正点原子文档

韦东山文档

猜你喜欢

转载自blog.csdn.net/m0_61737429/article/details/129988568