介绍
主要总结了下学到的一些音频理论知识,算是比较基础的部分,不会涉及编码算法这一类(编码算法实现话题太高端了),还有会介绍下常见的音频编码器,其中重点介绍下最广泛应用的aac。
文章目录
一、音频压缩
有损压缩
在不存在音频压缩的情况下,每秒钟PCM的数据量大约在1M左右,一般的网络用户来说10M的光纤上下行是不对称的,如果单纯的只是音频数据每秒都有1M,其他的事情基本都做不了了,所以需要使用到压缩技术,有两个方向:
- 压缩的越快越好
- 压缩的越小越好
很难做到又小又快,一般会寻求平衡点。找到适合网络传输的大小,同时又相对来说比较快,那这种就是和我们的实时传输了。
音频压缩技术是在保证信号在听觉方面不产生失真的前提下,对音频数据信号进行最可能大的压缩。压缩的主要方式是去除采集到的音频冗余信息,所谓的冗余信息包括人耳听觉范围之外的信号以及被遮蔽掉的音频信号。信号的屏蔽可以分为频域遮蔽与时域遮蔽。
-
频域遮蔽:
频域遮蔽是指在频域中,一个频率成分的存在会对附近的频率成分产生影响,使得这些附近的频率成分在被人耳感知时变得不明显或完全被掩盖。这种效应通常发生在音频编码或压缩中,其中一些频率成分可能会被较高能量的频率成分所遮蔽,从而可以在一定程度上减少对这些较低能量频率成分的编码或传输。
在音频编解码中,频域遮蔽的概念可以用来优化编码算法,减少需要传输或存储的数据量,而不损失音频质量
-
时域遮蔽:
时域遮蔽是指在时域中,一个信号的某些部分可能会被同一信号中较大的部分所遮蔽,使得这些较小的部分在时间上变得不明显或完全被掩盖。这种效应通常与人类听觉系统的特性有关,即当一个音频信号的强度较大时,人的听觉系统会对较小幅度的信号变化不太敏感。
在音频信号处理中,时域遮蔽的概念可以用来进行音频动态范围控制、噪声掩蔽以及声音控制等操作,以优化音频的感知效果。
无损压缩
对于以及剔除完容易信息的部分在进行无损压缩以求达到最好的效果,无损压缩技术比如zip,rar。无损压缩完之后是可以恢复的。对于音频中比较常用的熵编码,它是一种压缩数据的技术,其核心思想是利用输入数据的统计特性,将出现频率较高的符号用较短的编码表示,而出现频率较低的符号用较长的编码表示,从而实现数据压缩。
常见的熵编码方法包括:
- 霍夫曼编码
- 算术编码
- 自适应编码
二、音频的编码过程
当我们采集到一段声音之后,他会给两个模块进行处理,一个是时域转频遇,将一个时域的长时间的一段数据交给频遇转换器,把他转换成多种频段的数据,这样我们就能拆出哪些是我们需要的数据。另外的数据交给心理声学模型,去掉20Hz~20000Hz 以外的不在人耳听觉范围之内的数据,最后将两个数据汇总在一起,将其中要去掉的数据都去掉留下真正需要编码的数据,编码的数据经过量化后面在经过熵编码,编码之后形成的比特流数据,这个比特流数据就是编码好的数据,你可以保存在本地或者进行网络传输。
三 、常见的音频编码器
常见的音频编码器包括opus,aac,Ogg ,Speex,iLBC,AMR,G.711等,其中AAC在直播系统中应用的比较广泛,OPUS是较新的编码器,在webrtc中默认使用的就是OPUS,固化一般使用G.711。
观察下图纵轴是音频质量,横轴是码流大小
纵轴是延迟性,横轴是码率
四、AAC介绍
AAC 规格
AAC规格有十几种,常用的三种AAC规格:
- AAC-LC: 低复杂度规格,码流是128k,音质好
- AAC HE:等于AAC-LC + SBR,其核心思想是按频谱分保存,低频编码保存主要成分,高频单独放大编码保存音质,码流在64k左右。
- AAC HE V2:等于AAC-LC + SBR+ PS,其核心思想是双声道中的声音存在某种相似性,只需存储一个声道的全部信息,然后花很少的字节用参数描述另一个声道和他不同的地方。
封装AAC的格式
AAC(Advanced Audio Coding)格式可以使用不同的封装方式进行存储和传输,其中两种常见的封装方式是ADTS(Audio Data Transport Stream)和ADIF(Audio Data Interchange Format)。这两种封装方式在AAC格式:
- ADIF(Audio Data Interchange Format):这种格式的特征是可以确定的找到这个音频数据的开始,只能从头开始解码,不能从音频数据流中间开始,这种格式常用在磁盘文件中。
- ADTS(Audio Data Transport Stream) :这种格式的特征是每一帧都有一个同步字,所以可以在音频流的任意位置开始解码。类似于数据流格式。
ADTS的结构
AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)
A~Q每个字符分别代表1个bit位。AAC前面均包含ADTS头,按位可以节省很多内存。
下图是维基百科上的位的详细解释
这个地址可以给你解析出adts的含义:
https://www.p23.nl/projects/aac-header/
类似于下图
五、音频重采样
什么是音频重采样?
将音频三元组(采样率,位深(采样大小),通道数)转换成另一组值,例如将44100/16/2 转换成48000/16/2. 三元组中任何一项发生变化都是重采样。
为什么需要重采样
- 从设备采集的音频数据与编码器要求的不一样
- 扬声器要求的音频数据与要播放的音频数据不一样
- 更方便计算
前面两点还是很好理解的,第三点我要举个场景,比如在处理音频数据的时候会经常遇到回音消除的问题,如果他的通道数是2的话是非常不好计算的。所以这个时候就换需要重采样把通道数改成单身道。
重采样的步骤
- 创建重采样上下文:在进行重采样之前,首先需要创建一个重采样上下文对象。这个上下文对象是用来存储重采样过程中的参数和状态信息的数据结构。
- 设置参数:在创建重采样上下文后,需要设置重采样的参数,包括输入采样率、输出采样率、声道数等。这些参数决定了重采样过程中的转换规则。
- 初始化重采样:在设置参数之后,需要通过调用初始化函数来初始化重采样上下文。这个步骤通常会进行内存分配和其他初始化操作,确保重采样器能够正常工作。
- 进行重采样:初始化完成后,就可以开始进行重采样了。这个步骤涉及将输入音频数据传递给重采样器,并从重采样器中获取输出音频数据。重采样器会根据设置的参数对输入音频进行采样率转换和声道转换等操作,生成与期望的输出采样率和声道数相匹配的音频数据。
总结
以上是在音频开发中常用的一些理论概念,做了一部分归纳,有些是维基百科上的原话,做了点翻译,在此特意把这些个知识做个笔记,方便自己查阅。