编解码格式 -- AAC


音频基础

  • 采样率(samplerate):定义了每秒从连续信号中提取并组成离散信号的采样个数,单位为Hz。
  • 采样周期:即采样率的倒数,表示采样点之间的时间间隔。
  • 采样位数:记录采样点数据的精度,一般是8bits或16bits。
  • 码率(kbps) = 采样率(kHz) x 采样位数(bits/采样点) x 声道数量

AAC的特点

1. 数据组织格式

AAC有两种音频数据组织格式:ADIF 和 ADTS。

  • ADIF (Audio Data Interchange Format),音频数据交换格式。
    配置信息在整个文件的开头,只能从文件起始点开始解码,负载率高,适合本地存储。
    结构图如下:
    在这里插入图片描述
  • ADTS (Audio Data Transport Stream),音频数据传输流。
    特征是它是有同步字节(12bits,0xFFF)的比特流,可以在这个音频流的任意帧开始解码。也就是说每一帧AAC都有头信息,可以在任意帧开始解码。而ADIF只有一个统一的头信息,只有拿到这个头信息才可以开始解码。
    结构图如下:
    在这里插入图片描述

2.数据帧

AAC一帧一般是1024个采样点,对于采样率为44.1kHz的音频,一帧时间为23.22ms;对于采样率为48kHz,一帧时间为21.33ms。(音频数据是流式的,本身没有明确的一帧帧的概念,为了音频算法处理/传输的方便,一般取2.5ms~60ms音频为一帧)

Android audioflinger会做resample,音频输出会转换为48kHz,2 ch。

3.带ADTS的AAC特点

  • 带有同步字节(0xFFF),在失去同步的时候可以通过该同步字节迅速重新同步。
  • 每笔音频数据都带有配置信息,解码器可以从任意一笔数据开始解码。

ADTS

1. 结构

ADTS header总共7个字节或者9个字节(7+2字节CRC),分为固定信息可变信息,分别有28bits。
带ADTS的AAC格式结构图:
在这里插入图片描述

2. ADTS固定头部信息

每个ADTS头中固定不变的部分。记录AAC流的编码级别,采样率,声道数等信息。

示意图

在这里插入图片描述

关键信息

  • Sync word:
    同步码。12 bits,表示一个ADTS帧的开始,都是1,即0xFFF。

  • ID:
    MPEG标识符。
    0:MPEG-4;
    1:MPEG-2。

  • Layer:
    总是0。

  • protection absent:
    表示是否缺少CRC校验,一般为1。
    0:没有缺少CRC校验,ADTS header最后加2个字节的校验码,总共9字节的header。
    1:缺少CRC校验,adts header大小为7字节。

  • Profile:
    表示使用那个级别的AAC。
    对于MPEG-2(也就是ID),定义了三种AAC级别。

    profileAAC level
    0AAC Main
    1AAC LC
    2AAC SSR
    3(reserved)

    对于MPEG-4(也就是ID == 2),定义了Audio Object Type,而profile = Audio Object Type ID – 1

    profileAAC levelObject Type ID
    0AAC Main1
    1 AAC LC2
    2 AAC SSR3
    3 AAC LTP4

    可以看到,对于MPEG-2和MPEG-4,前面三个profile的值代表的AAC level是一样的。

  • Sampleing frequencry index:
    采样率下标,通过下标查表可得AAC的采样率。规范中最高支持96Kbps。
    在这里插入图片描述

  • Channel configuration:
    声道数。
    在这里插入图片描述

3. ADTS可变头部信息

每个ADTS头中可变的部分(因payload不同而不同),记录该AAC音频帧的数据大小以及有多少个数据块。

示意图

在这里插入图片描述

关键信息

  • aac frame length:
    一个ADTS帧的长度,包括ADTS头和AAC原始流。
    aac frame length = (protection_absent ==1 ? 7 : 9) + size(AAC ES data)
  • Adts buffer fullness:
    0x7FF说明码率可变码流。
  • number of raw data block in frame:
    表示一个ADTS帧中有多少个AAC原始数据块。
    该栏位为0表示ADTS帧中有1个AAC原始数据块;为1表示ADTS帧中有2个AAC原始数据块 …
    即:acc frame = number_of_raw_data_block_in_frame + 1

4. 举个例子

	ADTS header:
	fff9 5040 017f fc
	-->(Binary)
	11111111 11111001 01010000 01000000 00000001 01111111 11111100
	So:
	11111111 1111   --> sync code, 0xfff
	1               --> MPEG-2
	00              --> 总是0
	1               --> 缺少CRC校验,adts header长度为7
	01              --> 按照MPEG-2的标准,AAC的level是AAC LC
	0100            --> 44100Hz
	0               --> private bit
	001             --> 声道数为1
	0               --> original copy
	0               --> home
	0               --> copyright identification bit
	0               --> copyright identification start
	00 00000001 011 --> frame长度为11,因为adts header为7,所以该frame的aac原始流是4字节
	11111 111111    --> buffer fullness
	00              --> 该AAC帧只有一个AAC原始数据块

问题

  1. ADTS中没有记录采样位数,解码器如何知道一个采样点有多少字节数据?
    答:解码是不需要采样位数这个参数的,音频输出(PCM)才需要这个参数。
    而采样位数可以通过解码出来的一笔pcm其它参数计算出来。
    Bit = pcm_data_size / (pcm_sample_count * channel_count)

版权声明:本文为Ritchie_Lin原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。