AAC
音频格式
- ADIF和ADTS
- ADIF: Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定 的找到这个音频数据的开始,不需要进行在音频数据流中间开始的解码.即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
- ADTS的全称是Audio Data Transport Stream。是AAC音频的传输流格式。
- 二者的区别:
- ADTS可以在任意帧解码,也就是说它每一帧都有头信息。
- ADIF只有一个统一的头,所以必须得到所有的数据后解码。
AAC音频文件结构
- 组成:AAC音频文件的每一帧都由ADTS Header和AAC Audio Data组成结构
- ADTS header:每一帧的ADTS的头文件都包含了音频的采样率,声道,帧长度等信息,这样解码器才能解析读取。
- 组成:一般情况下ADTS的头信息都是7个字节,分为2部分:
- 固定头信息:信息中的数据每一帧都相同
- 可变头信息: 则在帧与帧之间可变
- 数据结构
- adts_fixed_header
- 组成:一般情况下ADTS的头信息都是7个字节,分为2部分:
struct adts_fixed_header{ //28bit
syncword; //12bit 同步头 总是0xFFF, all bits must be 1,代表着一个ADTS帧的开始
ID; //1bit MPEG标识符,0标识MPEG-4,1标识MPEG-2
layer; //2bit always: '00'
protection_absent; //1bit 表示是否误码校验 。决定是否需要header length的长度 是7还是9(1?7:9)
profile; //2bit profile = MPEG-4 Audio Object Type - 1
sampling_frequency_index; //4bit 表示使用的采样率下标,通过这个下标在 Sampling Frequencies[ ]数组中查找得知采样率的值。
private_bit; //1bit
channel_configuration; //3bit 表示声道数,比如2表示立体声双声道
original_copy; //1bit
home; //1bit
};
- adts_variable_header();
struct adts_variable_header{ //28bit
copyright_identification_bit; //1bit
copyright_identification_start; //1bit
acc_frame_lenght; //13bit; 个ADTS帧的长度包括ADTS头和AAC原始流
//aac_frame_length = (protection_absent == 1 ? 7 : 9) + size(AACFrame)
//protection_absent=0时, header length=9bytes
//protection_absent=1时, header length=7bytes
adts_buffer_fullness; //11bit; 0x7FF 说明是码率可变的码流
number_of_raw_data_blocks_in_frame; //2bit number_of_raw_data_blocks_in_frame + 1个AAC原始帧。
//例如 :number_of_raw_data_blocks_in_frame == 0 表示说ADTS帧中有一个AAC数据块
};
ADTC 十六进制码流结构 样例
- 第一帧的帧头的7个字节为:
0xFF,0xF1,0x4C,0x40,0x20,0xFF,0xFC
7个字节转换为二进制为- 1111 1111, 1111 0001,0100 1100,0100 0000,0010 0000,1111 1111,1111 1010
- 可由第adts_fixed_head 拆分为:
- 1111 1111, 1111 0001,0100 1100,0100 0000,0010 0000,1111 1111,1111 1010
1111 1111 1111 | 头部头,总是为FFF,代表开始 |
---|---|
0 | 表示MPEG-4 |
00 | 默认 |
1 | 没有CRC,有则设置为0 |
01 | AAC MAIN级别 |
0011 | 采样率下标: 3 对应 48000 |
0 | |
001 | 1个声道数 |
0 | |
0 |
- 第二部分为adts_variable_header
0 | Copyring_identification_bit |
---|---|
0 | 2.1 |
00 0010 0000 111 | ADTS的长度 |
1 11 1111 1111 | 0x7FF表示可变码流 |
00 |
面试
计算帧的长度
unsigned int getFrameLength(unsigned char *str){
if(!str)
return;
unsigned int len=0;
int f_bit=str[3];
int m_bit=str[4];
int b_bit=str[5];
len+=(b_bit>>5);
len+=(m_bit<<3);
len+=((f_bif&3)<<11);
return len;
}
音频文件时长:
- 思路:
- file_size为整个音频文件的长度。
- 如果文件是 CBR 码率控制模式 ,
时长 time = file_size / bitrate , bitrate则是文件的固定码率。对于固定码率的音频文件必定有文件头可以读取到这个消息。
- 如果文件是VBR,
则总时长为t=file_size/average_bitrate average_bitrate为文件的平均码率。 一般VBR音频文件都有一个VBR头部来记录音频文件的总帧数及其采样率及其每一帧的采样数。 我们可以根据这些信息来计算总的时长 t=文件总帧数x(每一帧采样数)/(采样率)
- file_size为整个音频文件的长度。