音频基础
- 采样率(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级别。profile AAC level 0 AAC Main 1 AAC LC 2 AAC SSR 3 (reserved) 对于MPEG-4(也就是ID == 2),定义了Audio Object Type,而profile = Audio Object Type ID – 1
profile AAC level Object Type ID 0 AAC Main 1 1 AAC LC 2 2 AAC SSR 3 3 AAC LTP 4 可以看到,对于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原始数据块
问题
- ADTS中没有记录采样位数,解码器如何知道一个采样点有多少字节数据?
答:解码是不需要采样位数这个参数的,音频输出(PCM)才需要这个参数。
而采样位数可以通过解码出来的一笔pcm其它参数计算出来。
Bit = pcm_data_size / (pcm_sample_count * channel_count)