AAC音频编码

2018-11-07  本文已影响28人  充满活力的早晨

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

定义

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

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

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

特点

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

AAC 规格介绍

AAC共有9种规格,以适应不同的场合的需要:

AAC音频文件格式

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

AAC的ADIF格式见下图:



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


ADTS 文件格式

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



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

固定部分 adts_fixed_header

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


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


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

可变部分adts_variable_header

这里需要注意的是每一个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
百度百科

上一篇 下一篇

猜你喜欢

热点阅读