音频编码之AAC

 

概述

高级音频编码 (英语:Advanced Audio Coding,AAC)是有损音频压缩专利数字音频编码标准,由Fraunhofer IIS杜比实验室贝尔实验室SonyNokia等公司共同开发。出现于1997年,为一种基于MPEG-2的标准,2000年,MPEG-4标准在原本的基础上加上了PNS(Perceptual Noise Substitution)等技术,并提供了多种扩展工具。为了区别于传统的MPEG-2 AAC又称为MPEG-4 AAC。其作为MP3的后继者而被设计出来,在相同的比特率之下,AAC相较于MP3通常可以达到更好的声音质量 ^[2]^ 。

AAC由国际标准化组织国际电工委员会标准化为MPEG-2MPEG-4规格的一部分。 ^[3]^ ^[4]^ 部分的AAC、HE-AAC(AAC+)为MPEG-4音频的一部分,并且被采用在数字声音广播世界数字广播 “DRM (广播)”)两个数字广播标准中以及DVB-H、ATSC-M/H两个移动电视标准中。

AAC支持包含一个流中48个最高至96 kHz的全带宽声道,加上16个120 Hz的低频声道(LFE)、不多于16个耦合声道及资料流。在joint stereo模式下,要使立体声的质量达到可接受的程度仅需96 kbps的比特率,若要达到Hi-fi则最少需要在可变比特率下128 kbps。

AAC被YouTubeiPhoneiPodiPad任天堂DSi任天堂3DSiTunesDivXPlayStation 3和多款Nokia 40系列、Sony Ericsson手机采用为默认的音频编码格式,并且被PlayStation VitaWiiSony Walkman MP3系列及随后的AndroidBlackBerry移动操作系统支持。

扩展名

  • .aac - 使用MPEG-2 Audio Transport Stream(ADTS, 参见MPEG-2 )容器,区别于使用MPEG-4容器的MP4/M4A格式,属于传统的AAC编码(FAAC默认的封装,但FAAC亦可输出MPEG-4封装的AAC)。
  • .mp4 - 使用了MPEG-4 Part 14(第14部分)的简化版即3GPP Media Release 6 Basic(3gp6, 参见3GP )进行封装的AAC编码(Nero AAC编码器仅能输出MPEG-4封装的AAC)。
  • .m4a - 为了区别纯音频MP4文件和包含视频的MP4文件而由苹果(Apple)公司使用的扩展名,Apple iTunes对纯音频MP4文件采用了”.m4a”命名。M4A的本质和音频MP4相同,故音频MP4文件亦可直接更改扩展名为M4A。Sony Ericsson于2006年后发表的手机原厂铃声几乎都慢慢改为M4A文件。

技术概览

AAC作为一种高压缩比的音频压缩算法,压缩比通常为18:1,也有资料说为20:1;在音质方面,由于采用多声道,和使用低复杂性的描述方式,使其比几乎所有的传统编码方式在同规格的情况下更胜一筹。

AAC是一种宽带音频编码算法,主要利用以下两种编码策略来大幅减少存储高质量数字音频所需要的资料量:

  • 舍去与感知上无关的信号成分
  • 去除编码后信号的冗余部分

实际的编码流程包含以下步骤:

在MPEG-4中并没有定义一个单一的高效率压缩流程,而是一组复杂的工具来达成从低编码速率的语音编码到高质量音频压缩、音乐合成等广泛的操作。

  • MPEG-4音频编码算法家族横跨了从低比特率的语音编码(最低至2 kbps)到高质量音频编码(每声道64 kbps或更高)
  • AAC提供了低至8 kHz高至96 kHz的多种采样率、更高的比特深度(8, 16, 24, 32 bit),并且支持1到48之间的任何声道数
  • 相较于MP3使用的混和滤波器组,AAC使用MDCT搭配增加至1024或960点的长度

AAC编码器可以动态的在单一的1024点MDCT区块或8个128点区块之间切换(或960及120点)

  • 在有暂态的信号变化时,选择使用8个较短的128/120点区块以达到更好的时域分辨率
  • 在默认的情况下则使用较长的1024/960点区块以增加频域的分辨率,因为如此可以运用更复杂的心理声学模型来达成更好的编码效率

相较于MP3的改进

AAC是作为MP3的后继者被设计出来,在1990年代后期的双盲试验中显示在相同的比特率下,AAC比MP3表现出更好的声音质量。

AAC相较于MP3的改进包含:

  • 更多的采样率选择(8 kHz至96 kHz,MP3为16 kHz至48 kHz)
  • 更高的声道数上限(48个,MP3在MPEG-1模式下为最多双声道,MPEG-2模式下5.1声道)
  • 任意的比特率和可变的帧长度
  • 更高效率及更单纯的滤波器组(AAC使用纯粹的MDCT,MP3则使用较复杂的混和滤波器组)
  • 对平稳的信号有更高的编码效率(AAC使用较长的1024/960点区块长度,MP3则为576点)
  • 对暂态变化的信号有更高的编码准确度(AAC使用较短的128/120点区块长度,MP3则为192点)
  • 可选择使用凯泽窗函数,以较大的主瓣(main lobe)为代价,消除频谱泄漏效应(spectral leakage)
  • 对于频率在16 kHz的声音频号成分有更好的处理
  • 有额外的模块如噪声移频(noise shaping)、反向预测(backward prediction)、感知上的噪声替代(perceptual noise substitution)等,可结合这些模块建构出各种不同的编码规格

整体而言,AAC格式相较于MP3给予开发者在设计编码上更大的弹性,并且修正许多在MPEG-1音频规格上的设计选择,这些增加的弹性使得更多的编码策略可以同时存在,进而达成更高的压缩效率。尽管如此,若要论及AAC是否比MP3好,AAC并没有完全的决定性的优势,MP3虽然较为古老且有相当的瑕疵,却也被证实是意外的坚固耐用。在低比特率的情况下(通常低于128 kbps),AAC及HE-AAC则因为更好的立体声编码、纯粹的MDCT及更好的窗函数长度,优于MP3,尤其在极低比特率的情况下优势更为显著。

MP3作为最早数年音乐开始在网络上传播、分享所被使用的格式,拥有最为普遍的软件及硬件支持,AAC则由于一些产业界持续坚定的支持,成为MP3一个有力的竞争对手,另一个竞争对手是开源产业界支持的IETF标准开放格式Opus (音频格式) “Opus (音频格式)”)。

低码率规格

高效AACHE-AAC ,英语:High-Efficiency AAC)为有损数据压缩技术,是对 高级音频编码AAC)的扩展。HE-AAC v1使用频段复制(SBR,英语:Spectral Band Replication)提高频域的压缩效率,适用于低码率(64kbps以下)。HE-AAC v2结合使用SBR和参数立体声(PS,英语:Parametric Stereo)提高立体声信号的压缩效率。HE-AAC v2进一步降低了对码率的需求(接近于50%),被应用于类似于DAB等码率资源很有限的领域。

HE-AAC之另一常见名称 aacPlus (aac+),为开发SBR之公司Coding Technologies的注册商标。MPEG组织于2003年五月将aac+纳入ISOIEC 14496-3(MPEG-4 Part 3)。HE-AAC适合于在低比特率(low bitrates)的应用,如:网络电台数字电视等,其宣称在48kbps的音质可以比128kbps的MP3还好,主要的竞争对象是无专利的IETF标准开放格式Opus “Opus (音频格式)”)。

版本

HE-AAC之不同版本:

版本 别称 编码功能 标准
HE-AAC v1 aacPlus v1, eAAC, AAC+, CT-aacPlus AAC LC + SBR ISO/IEC 14496-3:2001/Amd 1:2003
HE-AAC v2 aacPlus v2, eAAC+, AAC++, Enhanced AAC+ AAC LC + SBR + PS ISO/IEC 14496-3:2005/Amd 2:2006

规格一览

因为AAC是一个庞大家族,他们共分为9种规格,以适应不同场合的需要,也正是由于AAC的规格(Profile)繁多,导致普通电脑用户感觉十分困扰:

  1. MPEG-2 AAC LC低复杂度规格(Low Complexity)
  2. MPEG-2 AAC Main主规格
  3. MPEG-2 AAC SSR可变采样率规格(Scaleable Sample Rate)
  4. MPEG-4 AAC LC低复杂度规格(Low Complexity),现在的手机比较常见的MP4文件中的音频部分就包括了该规格音频档案
  5. MPEG-4 AAC Main主规格
  6. MPEG-4 AAC SSR可变采样率规格(Scaleable Sample Rate)
  7. MPEG-4 AAC LTP长时期预测规格(Long Term Predicition)
  8. MPEG-4 AAC LD低延迟规格(Low Delay)
  9. MPEG-4 AAC HE高效率规格(High Efficiency)

上述的规格中,主规格(Main)包含了除增益控制之外的全部功能,其音质最好,而低复杂度规格(LC)则是比较简单,没有了增益控制,但提高了编码效率,至“SSR”对“LC”规格大体是相同,但是多了增益的控制功能,另外,MPEG-4 AAC/LTP/LD/HE,都是用在低比特率下编码,特别是“HE”是有Nero AAC编码器支持,是近来常用的一种编码器,不过通常来说,Main规格和LC规格的音质相差不大,因此目前使用最多的AAC规格多数是“LC”规格,因为要考虑手机目前的存储器能力未达合理水准。MPEG-4 AAC LC(Low Complexity)是最常用的规格,我们叫“低复杂度规格”,我们简称“LC-AAC”,这种规格在中等码率的编码效率以及音质方面,都能找到平衡点。所谓中等码率,就是指:96kbps-192kbps之间的码率。因此,如果要使用LC-AAC规格,请尽可能把码率控制在之前说的那个区间内。

编码器一览

由于AAC格式家族比较庞大,要了解他,首先要清楚其各有不同的编码器,目前包括了商业的、免费的AAC格式音频编码器,这里只列举几款常用的AAC编解码器:

  • Nero AAC
    • 支持LC/HE规格
    • 目前已经停止开发维护
  • FFmpeg AAC
    • 支持LC规格
    • FFmpeg官方内置的AAC编解码器,在libavcodec库中
      • 编解码器名字叫做aac
      • 在开发过程中通过这个名字找到编解码器
  • FAAC(Freeware Advanced Audio Coder)
    • 支持LC规格
    • 可以集成到FFmpeg的libavcodec中
      • 编解码器名字叫做libfaac
      • 在开发过程中通过这个名字找到编解码器,最后调用FAAC库的功能
    • 从2016年开始,FFmpeg已经移除了对FAAC的支持
  • Fraunhofer FDK AAC
    • 支持LC/HE规格
    • 目前质量最高的AAC编解码器
    • 可以集成到FFmpeg的libavcodec中
      • 编解码器名字叫做libfdk_aac
      • 在开发过程中通过这个名字找到编解码器,最后调用FDK AAC库的功能

编码质量排名:Fraunhofer FDK AAC > FFmpeg AAC > FAAC。

目前听到用的比较多的应该是LC和HE(适合低码率)。

HE:“high efficiency”(高效性)。

HE-AAC v1(又称AACPlusV1,SBR)用容器的方法加了原AAC(LC)+SBR技术。SBR其实代表的是Spectral Band Replication(频段复制)。简单概括一下,音乐的主要频谱集中在低频段,高频段幅度很小,如果对整个频段编码,要么为了保护高频造成低频段编码过细以致文件巨大,要么为了保存了低频的主要成分而失去高频成分以致丧失音质。SBR把频谱切割开来,低频单独编码保存主要成分,高频单独放大编码保存音质,在相同音质下降低了文件大小。

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

许可和专利

用户不需要许可或付款来流式传输或分发AAC格式的内容。 AAC比照其前身的MP3一样,特别是根据适用于流媒体(如互联网广播)分发内容成为更有吸引力的格式。

然而,AAC 编解码器的所有制造商或开发商都需要专利许可。 FFmpeg和FAAC等自由开放源代码软件的实现可能仅以源代码形式分发,以避免专利侵权。

文件格式一览

ADIF

Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。简单来说,它只有一个统一的头,所以必须得到所有的数据后再解码。

ADIF格式图:

帧数据 帧数据 帧数据
header raw_data_block raw_data_block ……

ADIF头(header)信息:

Field name Field size in bits Comment
adif_id 32 Always:”ADIF”
copyright_id_present 1  
copyright_id 72 only if copyright_id_present == 1
original_copy 1  
home 1  
bit_stream_type 1 0:CBR, 1:VBR
bit_rate 23 for CBR :bit rate, for VBR:peak bit rate
0:means unknown
num_program_config_element 4  
     
buffer_fullness 20 only if bitstream_type==0
program_config_element VAR  

ADTS

Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。简单来说,它每一帧都有头信息,也就可以在任意帧解码。

  • ADTS Frame由ADTS_Header和AAC ES组成。
  • ADTS_Header包含采样率、声道数、帧长度的信息。
  • ADTS头信息的长度是7个字节或9字节(有CRC的情况)

完整格式图:

| ADTS Header | AAC ES | ADTS Header | AAC ES | …… | | ———– | —— | ———– | —— | —— |

头格式图:

| adts_fixed_header | adts_variable_header | crc | | —————– | ——————– | — |

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 配置级别
sample_frequency_index 4 标识使用的采用频率
private_bit 1 见 ISO/IEC 11172-3
channel_configuration 3 值为0是,通过inband的PCE设置channel
original/copy 1 编码设置为0,解码忽略
home 1 编码设置为0,解码时忽略

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

crc:

字段 比特数 说明
CRC 16 CRC ifprotection absent is 0

示例:

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;
}
static void get_adts_header_f(AVCodecContext *ctx, uint8_t *adts_header, int aac_length){
    uint8_t freq_idx = 0;    //0: 96000 Hz  3: 48000 Hz 4: 44100 Hz
    switch (ctx->sample_rate) {
        case 96000: freq_idx = 0; break;
        case 88200: freq_idx = 1; break;
        case 64000: freq_idx = 2; break;
        case 48000: freq_idx = 3; break;
        case 44100: freq_idx = 4; break;
        case 32000: freq_idx = 5; break;
        case 24000: freq_idx = 6; break;
        case 22050: freq_idx = 7; break;
        case 16000: freq_idx = 8; break;
        case 12000: freq_idx = 9; break;
        case 11025: freq_idx = 10; break;
        case 8000: freq_idx = 11; break;
        case 7350: freq_idx = 12; break;
        default: freq_idx = 4; break;
    }
 
    uint8_t chanCfg = ctx->channels;
    uint32_t frame_length = aac_length + 7;
    adts_header[0] = 0xFF;
    adts_header[1] = 0xF1;
    adts_header[2] = ((ctx->profile) << 6) | (freq_idx << 2) | (chanCfg >> 2);
    adts_header[3] = (((chanCfg & 3) << 6) | (frame_length  >> 11));
    adts_header[4] = ((frame_length & 0x7FF) >> 3);
    adts_header[5] = (((frame_length & 7) << 5) | 0x1F);
    adts_header[6] = 0xFC;
}