AAC音频编码

AAC(Advanced Audio Coding),中文名:高级音频编码,出现于1997年,基于MPEG-2的音频编码技术。由Fraunhofer IIS、杜比实验室、AT&T、Sony等公司共同开发,目的是取代MP3格式。2000年,MPEG-4标准出现后,AAC重新集成了其特性,加入了SBR技术和PS技术,为了区别于传统的MPEG-2 AAC又称为MPEG-4 AAC。

定义

AAC,全称Advanced Audio Coding,是一种专为声音数据设计的文件压缩格式。与MP3不同,它采用了全新的算法进行编码,更加高效,具有更高的“性价比”。利用AAC格式,可使人感觉声音质量没有明显降低的前提下,更加小巧。苹果ipod、诺基亚手机支持AAC格式的音频文件。

优点:相对于mp3,AAC格式的音质更佳,文件更小。

不足:AAC属于有损压缩的格式,与时下流行的APE、FLAC等无损格式相比音质存在“本质上”的差距。加之,传输速度更快的USB3.0和16G以上大容量MP3正在加速普及,也使得AAC头上“小巧”的光环不复存在。

特点

①提升的压缩率:可以以更小的文件大小获得更高的音质;
②支持多声道:可提供最多48个全音域声道;
③更高的解析度:最高支持96KHz的采样频率;
④提升的解码效率:解码播放所占的资源更少;
杜比实验室的结论
①128Kbps的AAC立体声音乐被专家认为不易察觉到与原来未压缩音源的区别;
②AAC格式在96Kbps码率的表现超过了128Kbps的MP3格式;
③同样是128Kbps,AAC格式的音质明显好于MP3;
④AAC是唯一一个,能够在所有的EBU试听测试项目的获得“优秀”的网络广播格式。
总的来讲,AAC可以说是极为全面的编码方式,一方面,多声道和高采样率的特点使得它非常适合未来的DVD-Audio;另一方面,低码率下的高音质则使它也适合移动通讯、网络电话、在线广播等领域,真是全能的编码方式。

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 编码器支持

AAC音频文件格式

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

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

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

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

AAC的ADIF格式见下图:



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


ADTS 文件格式

AAC音频文件的每一帧由ADTS Header和AAC Audio Data组成。


AAC音频编码_第1张图片

而ADTS的 Header部分分成两部分,固定部分和可变部分

固定部分 adts_fixed_header
AAC音频编码_第2张图片
  • yncword :总是0xFFF, 代表一个ADTS帧的开始, 用于同步.
    解码器可通过0xFFF确定每个ADTS的开始位置.
    因为它的存在,解码可以在这个流中任何位置开始, 即可以在任意帧解码。
  • ID:MPEG 版本: 0 代表 MPEG-4,1 代表 MPEG-2
  • Layer:总是: '00'
  • protection_absent:设置0,进行crc校验,1不进行crc校验,进行crc校验导致固定部分边长成28+16 = 44bits
  • profile:表示使用哪个级别的AAC
    如01 Low Complexity(LC) -- AAC LC。

注意 profile的值等于 Audio Object Type的值减1.
profile = MPEG-4 Audio Object Type - 1


AAC音频编码_第3张图片
  • sampling_frequency_index:采样率的下标


    AAC音频编码_第4张图片
  • channel_configuration:声道数,比如2表示立体声双声道

这里注意,声道数量这里有3个bits表示


AAC音频编码_第5张图片

其他没有介绍的位都是0,保留

可变部分adts_variable_header
AAC音频编码_第6张图片
  • aac_frame_length 一个ADTS帧的长度包括ADTS头和AAC原始流。就是该帧的总长度。
    aac_frame_length = (protection_absent == 1 ? 7 : 9) + size(AACFrame)
  • adts_buffer_fullness:0x7FF 说明是码率可变的码流。
  • number_of_raw_data_blocks_in_frame:表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧。
    所以说number_of_raw_data_blocks_in_frame == 0 表示说ADTS帧中有一个AAC数据块。

这里需要注意的是每一个AAC原始帧包含一段时间内1024个采样及相关数据

总体结构

AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM MMMMMMMM MMMOOOOO OOOOOOPP (QQQQQQQQ QQQQQQQQ)

头部分是7字节或者9字节(有crc就是9字节没有就是7字节)

Letter Length (bits) Description
A 12 syncword 0xFFF, 所有位数都是1
B 1 MPEG 版本: 0 代表 MPEG-4, 1 代表 MPEG-2
C 2 Layer: 总是 0
D 1 protection absent, 1 代表不用crc,0代表用crc
E 2 profile, MPEG-4 Audio Object Type 减去 1
F 4 MPEG-4 Sampling Frequency Index
G 1 私有位置,不会被mpeg适用,编码时候设置0,解码忽略
H 3 MPEG-4 Channel Configuration (在0的情况下,通过带内的PCE发送通道配置)
I 1 originality, 编码设置0,解码忽略
J 1 home, 编码设置0,解码忽略
K 1 copyrighted id bit,编码时候设置0,解码忽略
L 1 copyright id start, 编码时候设置0,解码忽略
M 13 frame length,帧长度,该值保护7或者9个字节的头
FrameLength =(ProtectionAbsent == 1?7:9)+ size(AACFrame)
O 11 Buffer fullness ,缓冲充满度
P 2 ADTS 帧中的AAC帧数-1
为了实现最大的兼容性,每个ADTS帧始终使用一个AAC
也就是说改为始终是0
Q 16 protection absent 是0, 就有q的位置,是1,就没有q的位置

这段代码写的很清楚可惜不是oc写的

int ff_adts_write_frame_header(ADTSContext *ctx,  
                               uint8_t *buf, int size, int pce_size)  
{  
    PutBitContext pb;  
  
    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, ADTS_HEADER_SIZE + size + pce_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;  
} 

这里是LFLiveKit中的代码封装。

- (NSData *)adtsData:(NSInteger)channel rawDataLength:(NSInteger)rawDataLength {
    int adtsLength = 7;
    char *packet = malloc(sizeof(char) * adtsLength);
    
    // Variables Recycled by addADTStoPacket
    int profile = 2;  //AAC LC
    //39=MediaCodecInfo.CodecProfileLevel.AACObjectELD;
    NSInteger freqIdx = [self sampleRateIndex:self.configuration.audioSampleRate];  //44.1KHz
    int chanCfg = (int)channel;  //MPEG-4 Audio Channel Configuration. 1 Channel front-center
    NSUInteger fullLength = adtsLength + rawDataLength;
    // fill in ADTS data
    packet[0] = (char)0xFF;     // 11111111     = syncword
    packet[1] = (char)0xF9;     // 1111 1 00 1  = syncword MPEG-2 Layer CRC
    packet[2] = (char)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
    packet[3] = (char)(((chanCfg&3)<<6) + (fullLength>>11));
    packet[4] = (char)((fullLength&0x7FF) >> 3);
    packet[5] = (char)(((fullLength&7)<<5) + 0x1F);
    packet[6] = (char)0xFC;
    NSData *data = [NSData dataWithBytesNoCopy:packet length:adtsLength freeWhenDone:YES];
    return data;
}

mpeg-4audio
ADTS
参考文章
aac音频格式
aac
百度百科

你可能感兴趣的:(AAC音频编码)