目录
- 概述
- 帧格式
- 算法简介
- 开源的软件
- AAC和MP3的关键性不同
- 参考阅读
1. 概述
AAC(Advanced Audio Coding),被认为是MP3的继任者,相对MP3有更高的压缩效率。由Fraunhofer IIS、杜比实验室、AT&T、Sony(索尼)等公司共同开发。1997年由MPEG正式宣布为国际标准,为MPEG-2标准的第7部分-ISO/IEC 13818-7:1997。MPEG-4标准中,AAC音频流部分在ISO/IEC 14496-3 (subpart 4)中规定。
AAC被iPhone、iTunes以及大多数便携式设备所使用。
AAC有很多的选项和profiles。
2. 帧格式
AAC音频格式有:
- ADIF(Audio Data Interchage Format),音频数据交换格式:只有一个统一的头,必须得到所有数据后解码,适用于本地文件。
- ADTS(Audio Data Transport Stream),音视数据传输流:每一帧都有头信息,任意帧解码,适用于传输流。
下面主要介绍ADTS。
ADTS的组成单元是ADTS Frame。
adts帧.png
- ADTS Frame由ADTS_Header和AAC ES组成。
- ADTS_Header包含采样率、声道数、帧长度的信息。
- ADTS头信息的长度是7个字节或9字节(有CRC的情况)。
ADTS_Header的可以分为以下三部分:
- adts_fixed_header:每一帧的内容是不变的。
- adts_variable_header:每一帧的内容是存在变化的。
- crc:16bits,protection_absent字段为0时存在。
adts_fixed_header:
字段 | 比特数 | 说明 |
---|---|---|
syncword | 12 | 所有位必须为1,即0xFFF。 |
ID | 1 | 0代表MPEG-4, 1代表MPEG-2。 |
layer | 2 | 所有位必须为0。 |
protection_absent | 1 | 1代表没有CRC,0代表有。 |
profile | 2 | 配置级别 |
sampling_frequency_index | 4 | 标识使用的采样频率,具体见下表Table35。 |
private_bit | 1 | see ISO/IEC 11172-3, subclause 2.4.2.3 (Table 8). |
channel_configuration | 3 | 取值为0时,通过inband 的PCE设置channel configuration。 |
original/copy | 1 | 编码时设置为0,解码时忽略。 |
home | 1 | 编码时设置为0,解码时忽略。 |
在MPEG-2 AAC中定义了3种profile:
- MPEG-2 AAC Main
- MPEG-2 AAC LC (Low Complexity)
- MPEG-2 AAC SSR (Scalable Sampling Rate)
在MPEG-4 AAC中定义了6种profile:
- MPEG-4 AAC Main
- MPEG-4 AAC LC (Low Complexity)
- MPEG-4 AAC SSR (Scalable Sample Rate)
- MPEG-4 AAC LTP (Long Term Predicition)
- MPEG-4 AAC LD (Low Delay)
- MPEG-4 AAC HE (High Efficiency) AACPlusV1/V2(3GPP)
sampling_frequency_index采样频率表.PNG
adts_variable_header:
字段 | 比特数 | 说明 |
---|---|---|
copyright_identification_bit | 1 | 编码时设置为0,解码时忽略。 |
copyright_identification_start | 1 | 编码时设置为0,解码时忽略 |
frame_length | 13 | 帧长度,包括header和crc的长度,单位byte |
adts_buffer_fullness | 11 | |
number_of_raw_data_blocks_in_frame | 2 | number of AAC Frames(RDBs) in ADTS frame minus 1, 为了最大的兼容性通常每个ADTS frame 包含一个AAC frame。 |
AAC ES部分说明
- 一个frame的原始数据包含1024个样本时间段的音频数据。
ffmpeg中添加ADTS头的代码,可以很清晰的了解ADTS头的结构:
static int adts_write_frame_header(ADTSContext *ctx,
uint8_t *buf, int size, int pce_size)
{
PutBitContext pb;
unsigned full_frame_size = (unsigned)ADTS_HEADER_SIZE + size + pce_size;
if (full_frame_size > ADTS_MAX_FRAME_BYTES) {
av_log(NULL, AV_LOG_ERROR, "ADTS frame size too large: %u (max %d)\n",
full_frame_size, ADTS_MAX_FRAME_BYTES);
return AVERROR_INVALIDDATA;
}
init_put_bits(&pb, buf, ADTS_HEADER_SIZE);
/* adts_fixed_header */
put_bits(&pb, 12, 0xfff); /* syncword */
put_bits(&pb, 1, 0); /* ID */
put_bits(&pb, 2, 0); /* layer */
put_bits(&pb, 1, 1); /* protection_absent */
put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */
put_bits(&pb, 4, ctx->sample_rate_index);
put_bits(&pb, 1, 0); /* private_bit */
put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */
put_bits(&pb, 1, 0); /* original_copy */
put_bits(&pb, 1, 0); /* home */
/* adts_variable_header */
put_bits(&pb, 1, 0); /* copyright_identification_bit */
put_bits(&pb, 1, 0); /* copyright_identification_start */
put_bits(&pb, 13, full_frame_size); /* aac_frame_length */
put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */
put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */
flush_put_bits(&pb);
return 0;
}
3. 算法简介
AAC是一种宽带音频编码算法,它利用两种主要的编码策略来大幅减少表示高质量数字音频所需的数据量:
- 丢弃在感知上不相关的信号分量。
- 消除了编码音频信号中的冗余。
实际的编码过程包括以下步骤:
- 使用前向修改的离散余弦变换(MDCT)将信号从时域转换到频域。这是通过使用滤波器组来完成的,这些滤波器组采用适当数量的时间采样并将其转换为频率采样。
- 基于心理声学模型量化频域信号并对其进行编码。
- 添加内部纠错码。
- 存储或传输信号。
- 为了防止损坏的样本,将Luhn mod N算法的现代实现应用于每个帧。
算法部分更多介绍可参考[5]。
4. 开源软件
5. AAC和MP3的关键性不同
AAC是在MP3基础上开发出来的,所以两者的编码系统有一些相同之处。但是对比一下两者的编码流程图,你会发现AAC的编码工序更为复杂。
- 滤波器组(Filter bank):
- 时域噪音修整(Temporal Noise Shaping,TNS):这项神奇的技术可以通过在频率域上的预测,来修整时域上的量化噪音的分布。在一些特殊的语音和剧烈变化信号的量化上,TNS技术对音质的提高贡献巨大!
- 预测(Prediction):对音频信号进行预测可以减少重复冗余信号的处理,提高效率。
- 量化(Quantization):AAC的量化过程是使用两个巢状循环进行反复运算。通过对量化分析的良好控制,比特率能够被更高效地利用。
- 比特流格式(Bit-stream format):在AAC中,信息的传输都要经过熵编码,以保证冗余尽可能少。此外AAC拥有一个弹性的比特流结构,使得编码效率进一步提高。
- 长时期预测(Long Term Prediction,LTP):这是一个MPEG-4 AAC中才有的工具,它用来减少连续两个编码音框之间的信号冗余,对于处理低码率的语音非常有效。
- 知觉噪音代替(Perceptual Noise Substitution,PNS):这也是MPEG-4 AAC中才有的工具,当编码器发现类似噪音的信号时,并不对其进行量化,而是作个标记就忽略过去,当解码时再还原出来,这样就提高了效率。