音频基础知识总结

目录

音频基础知识

声道

采样率

样本格式

分片(plane)和打包(packed)

声道分布(channel_layout)

音频帧的数据量计算

音频播放时间计算

音频重采样

AAC资料

AAC规格简述

AAC特点

AAC音频文件格式

ADTS头

术语说明

参考


 

音频基础知识

不仅限于ffmpeg,音频采样所得的PCM都含有三个要素:声道(channel)、采样率(sample rate)、样本格式(sample format)。

 

声道

当人听到声音时,能对声源进行定位,那么通过在不同的位置设置声源,就可以造就出更好的听觉感受,如果配合影像进行音频位置的调整,则会得到更好的视听效果。常见的声道有:

  1. 单声道,mono
  2. 双声道,stereo,最常见的类型,包含左声道以及右声道
  3. 2.1声道,在双声道基础上加入一个低音声道
  4. 5.1声道,包含一个正面声道、左前方声道、右前方声道、左环绕声道、右环绕声道、一个低音声道,最早应用于早期的电影院
  5. 7.1声道,在5.1声道的基础上,把左右的环绕声道拆分为左右环绕声道以及左右后置声道,主要应用于BD以及现代的电影院

如下是一个双声道的音频系统

音频基础知识总结

 

一般情况下大家使用的音箱或耳机都是“立体声(Stereo)”的,即只有左右两个声道;而家庭影院的“环绕声(Surround)”则一般至少有四个声道。声道数通常用类似“X.Y”的数字表示,常见的声道配置有4.0,5.1,7.1等。一般家用可以简单地理解为:小数点前的数字表示全音域声道数,也就是普通音箱的数量;小数点后的数字表示低频声道数,也就是低音炮(Subwoofer)的数量

 

采样率

音频采样,是把声音从模拟信号转换为数字信号。采样率,就是每秒对声音进行采集的次数,同样也是所得的数字信号的每秒样本数。正常人听觉的频率范围大约在20Hz~20kHz之间。根据奈奎斯特采样理论,为了保证声音不失真,采样频率应该在40kHz左右。

常用的音频采样频率有8kHz(电话)、11.025kHz、22.05kHz、16kHz、37.8kHz、44.1kHz(CD)、48kHz(视频音轨)、96k/192k(Hi-Res)等。

音频基础知识总结

出于历史原因,所有CD一律采用44.1KHz,而DVD/BD视频音轨一律采用48KHz。所以不出意外,你听到的那些音乐都是44.1KHz,而你看的视频,它们的音频一般都采用48KHz的采样率。

如下图所示,原则上更高的采样率更为精准,但是一般认为44.1KHz就接近人耳极限了。

音频基础知识总结

为什么常见的WAV比特率是1141KBit/s了:44.1KHz * 32bit =1141.2
题外话:非整数倍SRC(Sample Rate Convert,采样率转换)带来的毁灭性后果。

既然原则上采样率越高越好,是不是意味着我们可以随便改变采样率呢?答案是否定的:

音频基础知识总结

从图中可以看出,原始波形分4段5个采样点(包括首尾),如果整数倍转换,采用了8个分段9个采样点(采样率翻倍),波形是没有改变的。但是,如果新的采样率是原来的1.5倍,采用6个分段7个采样点,新的波形就会和原波形相差很远,造成很大的误差,换言之,这是一个有损转换过程。同样,44.1KHz和48KHz之间的转换也是属于非整数倍转换,会带来可观的音质损失。

android系统之所以不适合多媒体,是因为android系统会把所有非44.1KHz的音频强制转换成44.1KHz再输出。但是这问题也不大——你听到的多数音乐文件都是用44.1KHz,无非是多数视频文件的音频被改变了——谁管呢。

但是android一旦碰上高通,毁灭性的就来了:高通的CPU,会把44.1KHz的先转换成48KHz(一次有损),然后android系统再把48KHz转换成44.1KHz。这是最悲惨的过程。注意,这两次转换不是说效果相互抵消,而是相互叠加——你看看上图最后一个折线图,你采用原始的采样率看看,波形变化有多恐怖。

 

样本格式

单个声道的样本的编码类型

区别于前文所述的样本,我们这里为其添加了前缀,特指单个声道中的样本。音频在经过采样得到样本后,还需要对该样本执行两个步骤

  1. 量化。音频量化的量化位数常用的有8bit、16bit、32bit、64bit。
  2. 二进制编码。也就是把量化所得的结果,即单个声道的样本,以二进制的码字进行存放。其中有两种存放方式:直接以整形来存放量化结果,即Two's complement code;以浮点类型来存放量化结果,即Floating point encoding code。两者有如下关系:

    QFLT=QINTXRangeQFLT=QINTXRange

    其中XRangeXRange代表该量化器的量化范围,QINTQINT量化器所得出的结果,QFLTQFLT则是该结果的浮点表示。量化器所得出的量化结果必定在量化范围之内,因此从上面的式子可以看出,QFLTQFLT的绝对值必然小于等于1。

ffmpeg中的样本格式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

enum AVSampleFormat {

    AV_SAMPLE_FMT_NONE = -1,

    AV_SAMPLE_FMT_U8,          ///< unsigned 8 bits

    AV_SAMPLE_FMT_S16,         ///< signed 16 bits

    AV_SAMPLE_FMT_S32,         ///< signed 32 bits

    AV_SAMPLE_FMT_FLT,         ///< float

    AV_SAMPLE_FMT_DBL,         ///< double

 

    AV_SAMPLE_FMT_U8P,         ///< unsigned 8 bits, planar

    AV_SAMPLE_FMT_S16P,        ///< signed 16 bits, planar

    AV_SAMPLE_FMT_S32P,        ///< signed 32 bits, planar

    AV_SAMPLE_FMT_FLTP,        ///< float, planar

    AV_SAMPLE_FMT_DBLP,        ///< double, planar

    AV_SAMPLE_FMT_S64,         ///< signed 64 bits

    AV_SAMPLE_FMT_S64P,        ///< signed 64 bits, planar

 

    AV_SAMPLE_FMT_NB           ///< Number of sample formats. DO NOT USE if linking dynamically

};

可见其中有U8(无符号整型8bit)、S16(整型16bit)、S32(整型32bit)、FLT(单精度浮点类型)、DBL(双精度浮点类型)、S64(整型64bit),不以P为结尾的都是interleaved结构,以P为结尾的是planar结构。

 

分片(plane)和打包(packed)

帧当中的样本的组合方式

  1. 交错(interleaved)。以stereo为例,一个stereo音频的样本是由两个单声道的样本交错地进行存储得到的。
  2. 平面(planar)。各个声道的样本分开进行存储,。

音频基础知识总结

    以双声道为例,带P(plane)的数据格式在存储时,其左声道和右声道的数据是分开存储的,左声道的数据存储在data[0],右声道的数据存储在data[1],每个声道的所占用的字节数为linesize[0]和linesize[1];

    不带P(packed)的音频数据在存储时,是按照LRLRLR...的格式交替存储在data[0]中,linesize[0]表示总的数据量。

 

声道分布(channel_layout)

    声道分布在FFmpeg\libavutil\channel_layout.h中有定义,一般来说用的比较多的是AV_CH_LAYOUT_STEREO(双声道)和AV_CH_LAYOUT_SURROUND(三声道),这两者的定义如下:

#define AV_CH_LAYOUT_STEREO            (AV_CH_FRONT_LEFT|AV_CH_FRONT_RIGHT)
#define AV_CH_LAYOUT_SURROUND          (AV_CH_LAYOUT_STEREO|AV_CH_FRONT_CENTER)

 

音频帧的数据量计算

    一帧音频的数据量=channel数 * nb_samples样本数 * 每个样本占用的字节数

    如果该音频帧是FLTP格式的PCM数据,包含1024个样本,双声道,那么该音频帧包含的音频数据量是2*1024*4=8192字节。

 

音频播放时间计算

音频帧的播放时间= 一个AAC帧对应的采样样本的个数/采样频率

    以采样率44100Hz来计算,每秒44100个sample,而正常一帧为1024个sample,可知每帧播放时间/1024=1000ms/44100,得到每帧播放时间=1024*1000/44100=23.2ms。

所以,一个AAC帧的解码时间须控制在23.22毫秒内
反过来,如当想通过音频缓冲多少ms来计算实际应缓冲多少个音频帧时,可下计算:
比如对48K缓冲300ms需要多少个buffer,
buffer = 一秒内能产生多少个音频帧(48000/1024) 乘以 时间比例(300/1000) = (48000*300)/(1024*1000) = 14.0625个。

一个mp3 每帧均为1152个字节, 则:
frame_duration = 1152 * 1000 / sample_rate
例如:sample_rate = 44100HZ时, 计算出的时长为26.122ms,这就是经常听到的mp3每帧播放时间固定为26ms的由来。

 

音频重采样

1. 什么是重采样

所谓的重采样,就是改变音频的采样率、sample format、声道数等参数,使之按照我们期望的参数输出。

2. 为什么要重采样

为什么要重采样?当然是原有的音频参数不满足我们的需求,比如在FFMPEG解码音频的时候,不同的音源有不同的格式,采样率等,在解码后的数据中的这些参数也会不一致(最新FFMPEG 16 解码音频后,音频格式为AV_SAMPLE_FMT_FLTP,这个参数应该是一致的),如果我们接下来需要使用解码后的音频数据做其他操作,而这些参数的不一致导致会有很多额外工作,此时直接对其进行重采样,获取我们制定的音频参数,这样就会方便很多。 
再比如在将音频进行SDL播放时候,因为当前的SDL2.0不支持planar格式,也不支持浮点型的,而最新的FFMPEG 16年会将音频解码为AV_SAMPLE_FMT_FLTP格式,因此此时就需要我们对其重采样,使之可以在SDL2.0上进行播放。

3. 可调节的参数

通过重采样,我们可以对 sample rate(采样率)、sample format(采样格式)、channel layout(通道布局,可以通过此参数获取声道数)。

4. 相关函数说明

在ffmpeg中,提供了音频重采样的函数接口,如下:

  swr_alloc_set_opts

struct SwrContext *swr_alloc_set_opts(struct SwrContext *s,
    int64_t out_ch_layout, enum AVSampleFormat out_sample_fmt, int out_sample_rate,
    int64_t  in_ch_layout, enum AVSampleFormat  in_sample_fmt, int  in_sample_rate,
    int log_offset, void *log_ctx);
 * @param s               Swr context, can be NULL
 * @param out_ch_layout   output channel layout (AV_CH_LAYOUT_*)
 * @param out_sample_fmt  output sample format (AV_SAMPLE_FMT_*).
 * @param out_sample_rate output sample rate (frequency in Hz)
 * @param in_ch_layout    input channel layout (AV_CH_LAYOUT_*)
 * @param in_sample_fmt   input sample format (AV_SAMPLE_FMT_*).
 * @param in_sample_rate  input sample rate (frequency in Hz)
 * @param log_offset      logging level offset
 * @param log_ctx         parent logging context, can be NULL

功能: set the parameters on the allocated context.

参数1:重采样上下文

参数2:输出的layout, 如:5.1声道…

参数3:输出的样本格式。Float, S16, S24

参数4:输出的样本率。可以不变。

参数5:输入的layout。

参数6:输入的样本格式。

参数7:输入的样本率。

参数8,参数9,日志,不用管,可直接传0

音频的播放速度,是根据采样率,采样格式,声道数等参数决定的,当参数固定后, 音频播放速度也就固定了,关于这一点的认识在后续音视频同步过程中非常重要。

调用效果如下:

SwrContext *swr = swr_alloc_set_opts(NULL,  // we're allocating a new context
                        AV_CH_LAYOUT_STEREO,  // out_ch_layout
                        AV_SAMPLE_FMT_S16,    // out_sample_fmt,每种音频格式有不同的量化精度(位宽),位数越多,表示值就越精确,声音表现自然就越精准
                        44100,                // out_sample_rate
                        AV_CH_LAYOUT_5POINT1, // in_ch_layout
                        AV_SAMPLE_FMT_FLTP,   // in_sample_fmt
                        48000,                // in_sample_rate
                        0,                    // log_offset
                        NULL);                // log_ctx

是将输入音源参数为: 5.1声道 48K采样率 AV_SAMPLE_FMT_FLTP格式转换为 双声道 44.1k采样率 AV_SAMPLE_FMT_S16格式

 

swr_convert

int swr_convert(struct SwrContext *s, uint8_t **out, int out_count, const uint8_t **in, int in_count);

功能: 对音频作相应的重采样

参数1:音频重采样的上下文

参数2:输出的指针。传递的输出的数组

参数3:输出的样本数量,不是字节数。单通道的样本数量。

参数4:输入的数组,AVFrame解码出来的DATA

参数5:输入的单通道的样本数量。 

音频基础知识总结

 

AAC资料

AAC是高级音频编码(Advanced Audio Coding)的缩写,出现于1997年,最初是基于MPEG-2的音频编码技术。由Fraunhofer IIS、Dolby Laboratories、AT&T、Sony等公司共同开发,目的是取代MP3格式。2000年,MPEG-4标准出台,AAC重新集成了其它技术(PS,SBR),为区别于传统的MPEG-2 AAC,故含有SBR或PS特性的AAC又称为MPEG-4 AAC。

    AAC是新一代的音频有损压缩技术,它通过一些附加的编码技术(比如PS,SBR等),衍生出了LC-AAC,HE-AAC,HE-AACv2三种主要的编码,LC-AAC就是比较传统的AAC,相对而言,主要用于中高码率(>=80Kbps),HE-AAC(相当于AAC+SBR)主要用于中低码(<=80Kbps),而新近推出的HE-AACv2(相当于AAC+SBR+PS)主要用于低码率(<=48Kbps),事实上大部分编码器设成<=48Kbps自动启用PS技术,而>48Kbps就不加PS,就相当于普通的HE-AAC。

 

AAC规格简述

      AAC共有9种规格,以适应不同的场合的需要:

       MPEG-2 AAC LC 低复杂度规格(Low Complexity)--比较简单,没有增益控制,但提高了

  编码效率,在中等码率的编码效率以及音质方面,都能找到平衡点

       MPEG-2 AAC Main 主规格

       MPEG-2 AAC SSR 可变采样率规格(Scaleable Sample Rate)

       MPEG-4 AAC LC 低复杂度规格(Low Complexity)------现在的手机比较常见的MP4文件中

  的音频部份就包括了该规格音频文件

       MPEG-4 AAC Main 主规格 ------包含了除增益控制之外的全部功能,其音质最好

       MPEG-4 AAC SSR 可变采样率规格(Scaleable Sample Rate)

       MPEG-4 AAC LTP 长时期预测规格(Long Term Predicition)

      MPEG-4 AAC LD 低延迟规格(Low Delay)

      MPEG-4 AAC HE 高效率规格(High Efficiency)-----这种规格适合用于低码率编码,有

  Nero ACC 编码器支持

      目前使用最多的是LC和HE(适合低码率)。流行的Nero AAC编码程序只支持LC,HE,HEv2这三种规格,编码后的AAC音频,规格显示都是LC。HE其实就是AAC(LC)+SBR技术,HEv2就是AAC(LC)+SBR+PS技术;

   音频基础知识总结

          Hev1和HEv2用此图简单表示:

            (图中AAC即指的是原来的AAC-LC) 

 

      HE:“High Efficiency”(高效性)。HE-AAC v1(又称AACPlusV1,SBR),用容器的方法实现了AAC(LC)+SBR技术。SBR其实代表的是Spectral Band Replication(频段复制)。简要叙述一下,音乐的主要频谱集中在低频段,高频段幅度很小,但很重要,决定了音质。如果对整个频段编码,若是为了保护高频就会造成低频段编码过细以致文件巨大;若是保存了低频的主要成分而失去高频成分就会丧失音质。SBR把频谱切割开来,低频单独编码保存主要成分,高频单独放大编码保存音质,“统筹兼顾”了,在减少文件大小的情况下还保存了音质,完美的化解这一矛盾。

      HEv2:用容器的方法包含了HE-AAC v1和PS技术。PS指“parametric stereo”(参数立体声)。原来的立体声文件文件大小是一个声道的两倍。但是两个声道的声音存在某种相似性,根据香农信息熵编码定理,相关性应该被去掉才能减小文件大小。所以PS技术存储了一个声道的全部信息,然后,花很少的字节用参数描述另一个声道和它不同的地方。

 

AAC特点

       (1)AAC是一种高压缩比的音频压缩算法,但它的压缩比要远超过较老的音频压缩算法,

 如AC-3、MP3等。并且其质量可以同未压缩的CD音质相媲美。

       (2)同其他类似的音频编码算法一样,AAC也是采用了变换编码算法,但AAC使用了分辨率

 更高的滤波器组,因此它可以达到更高的压缩比。
      (3)AAC使用了临时噪声重整、后向自适应线性预测、联合立体声技术和量化哈夫曼编码等最新技术,这些新技术的使用都使压缩比得到进一步的提高。

     (4)AAC支持更多种采样率和比特率、支持1个到48个音轨、支持多达15个低频音轨、具有

多种语言的兼容能力、还有多达15个内嵌数据流。
     (5)AAC支持更宽的声音频率范围,最高可达到96kHz,最低可达8KHz,远宽于MP3的16KHz-48kHz的范围。
     (6)不同于MP3及WMA,AAC几乎不损失声音频率中的甚高、甚低频率成分,并且比WMA在频谱结构上更接近于原始音频,因而声音的保真度更好。专业评测中表明,AAC比WMA声音更清晰,而且更接近原音。 
     (7)AAC采用优化的算法达到了更高的解码效率,解码时只需较少的处理能力。

 

AAC音频文件格式

      1. AAC的音频文件格式有ADIF & ADTS:

       ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。

       ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。

       简单说,ADTS可以在任意帧解码,也就是说它每一帧都有头信息。ADIF只有一个统一的头,所以必须得到所有的数据后解码。且这两种的header的格式也是不同的,目前一般编码后的和抽取出的都是ADTS格式的音频流。两者具体的组织结构如下所示:

      AAC的ADIF格式见下图:

      音频基础知识总结

  

      AAC的ADTS的一般格式见下图:

     

         音频基础知识总结

      图中表示出了ADTS一帧的简明结构,其两边的空白矩形表示一帧前后的数据。

  

     2. ADIF和ADTS的header

        ADIF 的头信息:

 

       音频基础知识总结

   

 

  ADIF头信息位于AAC文件的起始处,接下来就是连续的 raw data blocks。

     组成ADIF头信息的各个域如下所示:

 

      音频基础知识总结

     ADTS 的固定头信息:

    音频基础知识总结

     

 

     ADTS的可变头信息:

   音频基础知识总结

    

(1)帧同步目的在于找出帧头在比特流中的位置,13818-7规定,aac ADTS格式的帧头

             同步字为12比特的“1111 1111 1111”.

           

      (2)ADTS的头信息为两部分组成,其一为固定头信息,紧接着是可变头信息。固定头信息中

           的数据每一帧都相同,而可变头信息则在帧与帧之间可变。

 

ADTS头

ADTS_header:
ADTS包含着音频的基本信息:采样率、声道数、帧长度......
ADTS一般分为2个部分:

adds_fixed_header()
{
      syncword;                            //同步头总是0xFFF,all bits must be 1,代表一个ADTS帧的开始
      ID;                                  //MPEG Version,  0 for MPEG-4 ,1 for MPEG-2
      layer;                               //always: '00'
      profile;                             //表示使用哪一个级别的AAC,在MPEG-2AAC中定义了3种,如图profile.png
      sampling_frequency_index             //表示使用的采样率下标,通过这个下标在Sampling Frequencies[]数组中国查找得知采样率的值
      private_bit;
      channel_configuration;               //表示声道数
      original_copy;                       
      home;
}
  • syncword:帧同步标识一个帧的开始,固定为0xFFF
  • ID:MPEG 标示符。0表示MPEG-4,1表示MPEG-2
  • layer:固定为'00'
  • protection_absent:标识是否进行误码校验。0表示有CRC校验,1表示没有CRC校验
  • profile:标识使用哪个级别的AAC。1: AAC Main 2:AAC LC (Low Complexity) 3:AAC SSR (Scalable Sample Rate) 4:AAC LTP (Long Term Prediction)
  • sampling_frequency_index:标识使用的采样率的下标
  • private_bit:私有位,编码时设置为0,解码时忽略
  • channel_configuration:标识声道数
  • original_copy:编码时设置为0,解码时忽略
  • home:编码时设置为0,解码时忽略

音频基础知识总结

   从视频文件中提取的音频aac数据,是不可以直接播放的,需要在每一帧前面添加ADTS头之后方可播放。
 

术语说明

AAC: Advanced Audio Coding 高级音频编码

AAC LC: AAC with Low Complexity AAC的低复杂度配置

AAC plus: 也叫HE-AAC, AAC+,MPEG4 AAC LC加入SBR模块后形成的一个AAC版本

MPEG:Motion Picture Expert Group

IMDCT:反离散余弦变换

ADIF:Audio Data Interchange Format 音频数据交换格式

ADTS:Audio Data Transport Stream 音频数据传输流

SCE: Single Channel Element单通道元素

CPE: Channel Pair Element 双通道元素

CCE: Coupling Channel Element 藕合通道元素

DSE: Data Stream Element 数据流元素

PCE: Program Config Element 程序配置元素

FIL: Fill Element 填充元素

ICS: Individual Channel Stream 独立通道流

PNS: Perceptual Noise Substitution 知觉噪声替换

SBR: Spectral Band Replication 频段复制

TNS: Temporal Noise Shaping 瞬时噪声整形

ch:channel 通道

PS:parametric stereo 参数立体声

SBR:Spectral Band Replication 频段复制

 

参考

http://blog.csdn.net/jgdu1981/article/details/6870577

 

 

 

 


 

上一篇:Spike Your CPU’s Processor in .Net


下一篇:网络视频流 -- ffmpeg 推流