音频基础知识详解

参考自:https://www.jianshu.com/p/86e1b1017564
    https://blog.csdn.net/qq_25333681/article/details/90682989

1、引言

现实生活中,我们听到的声音都是时间连续的,我们称为这种信号叫模拟信号。模拟信号需要进行数字化以后才能在计算机中使用。

目前我们在计算机上进行音频播放都需要依赖于音频文件。音频文件的生成过程是将声音信息采样量化编码产生的数字信号的过程,人耳所能听到的声音,最低的频率是从20Hz起一直到最高频率20KHZ,因此音频文件格式的最大带宽是20KHZ。根据奈奎斯特的理论,只有采样频率高于声音信号最高频率的两倍时,才能把数字信号表示的声音还原成为原来的声音,所以音频文件的采样率一般在40~50KHZ,比如最常见的CD音质采样率44.1KHZ。

2、音频基本概念

采样: 波是无限光滑的,采样的过程就是从波中抽取某些点的频率值,就是把模拟信号数字化。如下图所示:
在这里插入图片描述
蓝色代表模拟音频信号,红色代表采样得到的量化数值

采样频率: 单位时间内对模拟信号的采样次数,它用赫兹(Hz)来表示。采样频率越高,声音的还原就越真实越自然,当然数据量就越大。采样频率一般共分为22.05KHz、44.1KHz、48KHz三个等级。8KHz - 电话所用采样率, 对于人的说话已经足够,22.05KHz只能达到FM广播的声音品质(适用于语音和中等品质的音乐),44.1KHz则是是最常见的采样率标准,理论上的CD音质界限,48KHz则更加精确一些(对于高于48KHz的采样频率人耳已无法辨别出来了,所以在电脑上没有多少使用价值)。

小知识点:
5kHz的采样率仅能达到人们讲话的声音质量。
11kHz的采样率是播放小段声音的最低标准,是CD音质的四分之一。
22kHz采样率的声音可以达到CD音质的一半,目前大多数网站都选用这样的采样率。
44kHz的采样率是标准的CD音质,可以达到很好的听觉效果。

重采样: 主要是分为上采样和下采样,在进行采样的过程中,需要注意采样的倍率的问题,并不是可以随意的改变采样率的大小的,根据采样定理:在进行模拟/数字信号的转换过程中,当采样频率大于信号中最高频率的2倍时,采样之后的数字信号完整地保留了原始信号中的信息,一般实际应用中保证采样频率为信号是最高频率的5~10倍。采样定理又称奈奎斯特定理。

  • 上采样: 在进行采样的过程中,通常是分为上采样和下采样的,而区分的依据是重新采样的时候新采样率和原采样率的大小的比较,如果是大于原信号就成为是上采样,如果是小于原信号就称为下采样。而上采样的实质也就是内插或插值。
  • 下采样: 新的采样率的大小小于原采样率的大小。
  • 方法: 重采样的时候,主要是有最邻近法、双线性内插法以及三次卷积内插法这三种。 在卷积网络中还有反卷积,亚像素卷积等。

采样位数(也称量化级、样本尺寸、量化数据位数): 每个采样点能够表示的数据范围。采样位数通常有8bits或16bits两种,采样位数越大,所能记录声音的变化度就越细腻,相应的数据量就越大。8位字长量化(低品质)和16位字长量化(高品质),16 bit 是最常见的采样精度。

"采样频率"和"采样位数"是数字化声音的两个最基本要素,相当于视频中的屏幕大小
(例如800*600)和颜色分辨率(例如24bit)。

声道数(或通道数): 声道数是指支持能不同发声的音响的个数,它是衡量音响设备的重要指标之一。

单声道的声道数为1个声道;
双声道的声道数为2个声道;
立体声道的声道数默认为2个声道;
立体声道(4声道)的声道数为4个声道。

帧: 帧记录了一个声音单元,其长度为样本长度(采样位数)和通道数的乘积。

周期: 音频设备一次处理所需要的帧数,对于音频设备的数据访问以及音频数据的存储,都是以此为单位。

在这里插入图片描述

交错模式: 数字音频信号存储的方式。数据以连续帧的方式存放,即首先记录帧1的左声道样本和右声道样本,再开始帧2的记录…

非交错模式: 首先记录的是一个周期内所有帧的左声道样本,再记录所有右声道样本。

量化: 将采样后离散信号的幅度用二进制数表示出来的过程称为量化。(日常生活所说的量化,就是设定一个范围或者区间,然后看获取到的数据在这个条件内的收集出来)。

PCM: PCM(Pulse Code Modulation),即脉冲编码调制,对声音进行采样、量化过程,未经过任何编码和压缩处理。

PCM数据是最原始的音频数据完全无损,所以PCM数据虽然音质优秀但体积庞大,
为了解决这个问题先后诞生了一系列的音频格式,这些音频格式运用不同的方法对音频数据
进行压缩,其中有无损压缩(ALAC、APE、FLAC)和有损压缩(MP3、AAC、OGG、WMA)两种。

编码: 采样和量化后的信号还不是数字信号,需要将它转化为数字编码脉冲,这一过程称为编码。模拟音频进采样、量化和编码后形成的二进制序列就是数字音频信号。

码率:(也成位速、比特率) 是指在一个数据流中每秒钟能通过的信息量,代表了压缩质量。 比如MP3常用码率有128kbit/s、160kbit/s、320kbit/s等等,越高代表着声音音质越好。MP3中的数据有ID3和音频数据组成,ID3用于存储歌名、演唱者、专辑、音轨等我们可以常见的信息。

公式:
码率 = 采样率 * 采样位数 * 声道数
例如:
如果是CD音质,采样率44.1KHz,采样位数16bit,立体声(双声道), 码率 = 44.1 * 1000 * 16 * 2 =
1411200bps = 176400Bps,那么录制一分钟的音乐, 大概176400 * 1 * 60 / 1024 / 1024 =
10.09MB。

音频帧: 音频数据是流式的,本身没有明确的一帧帧的概念,在实际的应用中,为了音频算法处理/传输的方便,一般约定俗成取2.5ms~60ms为单位的数据量为一帧音频。这个时间被称之为“采样时间”,其长度没有特别的标准,它是根据编解码器和具体应用的需求来决定的。

举例:

目前最为常用的音频格式是MP3,MP3是一种有损压缩的音频格式,设计这种格式的目的就是为了大幅度的减小音频的数据量,它舍弃PCM音频数据中人类听觉不敏感的部分。

MP3格式中的码率(BitRate)代表了MP3数据的压缩质量,现在常用的码率有 128kbit/s、160kbit/s、320kbit/s等等,这个值越高声音质量也就越高。
MP3编码方式常用的有两种"固定码率"(Constant bitrate,CBR) 和"可变码率"(Variabl bitrate,VBR)。

MP3格式中的数据通常由两部分组成,一部分为"ID3"用来存储歌名、演唱者、专辑、音轨数等信息,另一部分为音频数据。音频数据部分以帧(frame)为单位存储,每个音频都有自己的帧头,如图所示就是一个MP3文件帧结构图。MP3中的每一个帧都有自己的帧头,其中存储了采样率等解码必须的信息,所以每一个帧都可以独立于文件存在和播放,这个特性加上高压缩比使得MP3文件成为了音频流播放的主流格式。帧头之后存储着音频数据,这些音频数据是若干个
PCM数据帧经过压缩算法压缩得到的,对CBR的MP3数据来说每个帧中包含的PCM数据帧是固定的, 而VBR是可变的。
在这里插入图片描述
MP3文件帧结构图

3、声音具体处理流程

模拟信号 -> 输入设备(传递电压值)-> 声卡(经过采样跟量化(即设置声音大小等各种值))-> 磁盘(文件) -> 声卡 -> 输出设备 -> 模拟信号

我们声音在物理上用波形表示,那么我们将这些波形称作为模拟信号。而我们计算机磁盘只能存储(01010101)的格式。我们将模拟信号转换成能够被磁盘存储的格式(010101)称之为数字信号。这个转换的过程我们叫模数转换

我们发出来的声音(模拟信号)是连续的,我们如果要一直的对模拟信号进行转化,产生的数字信号会很大。那么我们就要采样,而采样精度就是每秒计算机对模拟信号进行采样的次数。最常见的采样精度就是上面提到的44.1khz/s,这个是经过大师们多年研究得出的数据,低于这个数据,效果就会很差,而高于这个数据,效果的差距不是很明显。

采样后就是变成了(0101010110100101…),那声音的音量是有大小的,那这串数据,怎样表示声音的大小呢? 这就涉及到了比特率,它是指在一个数据流中每秒钟能通过的信息量。 比特率就是将声音的大小划分为多少等级。举例下:8比特,在二进制中,表示有8位,表示的十进制的值就是0(00000000)~256(11111111),那每个数值就代表着一个声音大小。

经过采样、量化、编码后转化成数字信号,然后存储为文件。

文件是用来装数字信号的,文件包括了比特率、采样率、声道、编码方式、以及被编码过后的数字信号。

文件格式就是制造者自己规定的一种名称,在每个文件格式都会特定支持几种编码格式。打个比方就是文件就是一个容器,里面可以装不同的水,有的可以装一种,有的可以装好几种。

经过采样后的数字信号很大,有时候我们不需要这么大的,所以我们就要进行编码压缩,当然压缩技术都是有损的。在不大影响音频的效果的情况下,舍弃掉一些高频或者低频的数据。

编码格式可以理解为每种音频格式不同的编解码方式。

封装格式就是文件格式,编码就是编码格式。

比较通俗的理解:封装格式和编码的关系,就是和酒瓶与酒的关系差不多,而播放器就是开酒器。
为了可以喝更好的酒,最好先了解酒是什么酒,酒瓶是什么酒瓶,怎么使用开酒器开酒瓶,码率或者可以比喻做酒的原料。对于同一个酒瓶和做同一种酒的情况下,如果原料太少,又要要求用酒把酒瓶灌满,此时只好兑水了,酒的品质就会变差了。然而,如果原料太多,又会造成 原料浪费。所以要做好酒,我们就需要充足的原料。

4、PCM数据常用量化指标

采样率(Sample rate): 每秒钟采样多少次,以Hz为单位。

位深度(Bit-depth): 表示用多少个二进制位来描述采样数据,一般为16bit。

字节序: 表示音频PCM数据存储的字节序是大端存储(big-endian)还是小端存储(little-endian),为了数据处理效率的高效,通常为小端存储。

声道数(channel number): 当前PCM文件中包含的声道数,是单声道(mono)、双声道(stereo)?此外还有5.1声道等。

采样数据是否有符号(Sign): 要表达的就是字面上的意思,需要注意的是,使用有符号的采样数据不能用无符号的方式播放。

以FFmpeg中常见的PCM数据格式s16le为例:它描述的是有符号16位小端PCM数据。

s表示有符号,16表示位深,le表示小端存储。

5、PCM数据流

对于PCM数据都是一些图像化的描述,那么一段PCM格式的数据流怎么表示的呢?

以8-bit有符号为例,长得像这样:

+---------+-----------+-----------+----
 binary 	| 0010 0000 | 1010 0000 | ...
 decimal	| 32        | -96       | ...
+---------+-----------+-----------+----  

每个分割符"|"分割字节。因为是 8-bit 有符号表示的采样数据,所以采样的范围为-128~128

图示中表示的是两个连续采样数据的二进制和十进制表示的值。

如果我们有一个PCM文件,在代码中,我们可以通过以下方式来读取这样的PCM数据流(Stream)。

FILE *file
int8_t *buffer;
file = fopen("PCM file path");
buffer = malloc(fileSize);
fread(buffer, sizeof(int8_t), fileSize / sizeof(int8_t), file);

伪代码仅仅表示一种加载方式。但在代码中,一开始就将整个文件加载到了内存中,这是不对的。因为我们的音频数据量往往会比较大,一次性全部加载增加了内存负担,而且并不必要。

通常我们会为buffer分配一个固定的长度,例如2048字节,通过循环的方式一边从文件中加载PCM数据,一边播放。

加载好PCM数据后,需要送到音频设备驱动程序中播放,这时我们应该能听到声音。与PCM数数据一同到达驱动程序的通常还有采样率(sample rate),用来告诉驱动每秒钟应该播放多少个采样数据。如果传递给驱动程序的采样率大于PCM实际采样率,那么声音的播放速度将比实际速度快,反之亦然。

OK,对于PCM数据流的存储而言,上面仅仅只是单声道。对于多声道的PCM数据而言,通常会交错排列,就像这样:

+---------+-----------+-----------+-----------+-----------+----
     FL 	|     FR    |     FL 	  |     FR    |     FL 	  |    
+---------+-----------+-----------+-----------+-----------+----

对于8-bit有符号的PCM数据而言,上图表示第一个字节存放第一个左声道数据(FL),第二个字节放第一个右声道数据(FL),第三个字节放第二个左声道数据(FL)

不同的驱动程序对于多声道数据的排列方式可能稍有区别,下面是常用的声道排列地图:

2:  FL FR                       (stereo)
3:  FL FR LFE                   (2.1 surround)
4:  FL FR BL BR                 (quad)
5:  FL FR FC BL BR              (quad + center)
6:  FL FR FC LFE SL SR          (5.1 surround - last two can also be BL BR)
7:  FL FR FC LFE BC SL SR       (6.1 surround)
8:  FL FR FC LFE BL BR SL SR    (7.1 surround)

6、音量控制

音量的表示实际上就是量化过程中每个采样数据的level值,只要适当的增大或者缩小采样的level就可以达到更改音量的目的。

但需要说明的是,并是不将level值*2就能得到两倍于原声音的音量。

因为如下两个原因:

  • 数据溢出: 我们都知道每个采样数据的取值范围是有限制的,例如一个signed 8-bit样本,取值范围为-128~128,值为125时,放大两倍后的值为250,超过了可描述的范围,此时发生了数据溢出。这个时候就需要我们做策略性的裁剪处理,使放大后的值符合当前格式的取值区间。

如下伪代码描述了signed 8-bit格式的声音放大两倍的裁剪处理:

int16_t pcm[1024] = read in some pcm data;
int32_t pcmval;
for (ctr = 0; ctr < 1024; ctr++) {
    
    
    pcmval = pcm[ctr] * 2;
    if (pcmval < 128 && pcmval > -128) {
    
    
        pcm[ctr] = pcmval
    } else if (pcmval > 128) {
    
    
        pcm[ctr] = 128;
    } else if (pcmval < -128) {
    
    
        pcm[ctr] = -128;
    }
}
  • 对数描述: 平时表示声音强度我们都是用分贝(db)作单位的,声学领域中,分贝的定义是声源功率与基准声功率比值的对数乘以10的数值。根据人耳的心理声学模型,人耳对声音感知程度是对数关系,而不是线性关系。人类的听觉反应是基于声音的相对变化而非绝对的变化。对数标度正好能模仿人类耳朵对声音的反应。所以用分贝作单位描述声音强度更符合人类对声音强度的感知。前面我们直接将声音乘以某个值,也就是线性调节,调节音量时会感觉到刚开始音量变化很快,后面调的话好像都没啥变化,使用对数关系调节音量的话声音听起来就会均匀增大。

如下图所示,横轴表示音量调节滑块,纵坐标表示人耳感知到的音量,图中取了两块横轴变化相同的区域,音量滑块滑动变化一样,但是人耳感觉到的音量变化是不一样的,在左侧也就是较安静的地方,感觉到音量变化大,在右侧声音较大区域人耳感觉到的音量变化较小。
在这里插入图片描述
这就需要对音量值的乘数系数合理取值。具体如何取值,请参考非常专业的一篇文章:PCM音量控制

7、采样率调整

采样率的定义为:每秒钟采样次数。而降低增加采样率只需要以固定的频率复制或者丢弃采样数据即可。

如10Hz表示每秒钟采样10次,我们只需要将2*n(n为从0开始的值)处的采样数据舍弃,就可以得到10/2 = 5Hz的采样数据。

猜你喜欢

转载自blog.csdn.net/houxiaoni01/article/details/109175486