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音频格式有ADIF和ADTS:
ADIF:Audio Data Interchange Format 音频数据交换格式。这种格式的特征是可以确定的找到这个音频数据的开始,
不需进行在音频数据流中间开始的解码,即它的解码必须在明确定义的开始处进行。故这种格式常用在磁盘文件中。
adif格式:
adif_header:
adif_id always:"ADIF"。
ADTS:Audio Data Transport Stream 音频数据传输流。这种格式的特征是它是一个有同步字的比特流,
解码可以在这个流中任何位置开始。它的特征类似于mp3数据流格式。
adts_header:
adts_fixed_header头的部分属性
链接:https://www.jianshu.com/p/30856dccd9cb
int getADTSframe(unsigned char* buffer, int buf_size, unsigned char* data, int* data_size) { int size = 0; if (!buffer || !data || !data_size) { return -1; } while (1) { if (buf_size < 7) { return -1; } //Sync words if ((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0)) { size |= ((buffer[3] & 0x03) << 11); //high 2 bit size |= buffer[4] << 3; //middle 8 bit size |= ((buffer[5] & 0xe0) >> 5); //low 3bit break; } --buf_size; ++buffer; } if (buf_size < size) { return 1; } memcpy(data, buffer, size); *data_size = size; return 0; } int simplest_aac_parser(char *url) { int data_size = 0; int size = 0; int cnt = 0; int offset = 0; //FILE *myout=fopen("output_log.txt","wb+"); FILE *myout = stdout; unsigned char *aacframe = (unsigned char *)malloc(1024 * 5); unsigned char *aacbuffer = (unsigned char *)malloc(1024 * 1024); FILE *ifile = fopen(url, "rb"); if (!ifile) { printf("Open file error"); return -1; } printf("-----+- ADTS Frame Table -+------+\n"); printf(" NUM | Profile | Frequency| Size |\n"); printf("-----+---------+----------+------+\n"); while (!feof(ifile)) { data_size = fread(aacbuffer + offset, 1, 1024 * 1024 - offset, ifile); unsigned char* input_data = aacbuffer; while (1) { int ret = getADTSframe(input_data, data_size, aacframe, &size); if (ret == -1) { break; } else if (ret == 1) { memcpy(aacbuffer, input_data, data_size); offset = data_size; break; } char profile_str[10] = { 0 }; char frequence_str[10] = { 0 }; unsigned char profile = aacframe[2] & 0xC0; profile = profile >> 6; switch (profile) { case 0: sprintf(profile_str, "Main"); break; case 1: sprintf(profile_str, "LC"); break; case 2: sprintf(profile_str, "SSR"); break; default: sprintf(profile_str, "unknown"); break; } unsigned char sampling_frequency_index = aacframe[2] & 0x3C; sampling_frequency_index = sampling_frequency_index >> 2; switch (sampling_frequency_index) { case 0: sprintf(frequence_str, "96000Hz"); break; case 1: sprintf(frequence_str, "88200Hz"); break; case 2: sprintf(frequence_str, "64000Hz"); break; case 3: sprintf(frequence_str, "48000Hz"); break; case 4: sprintf(frequence_str, "44100Hz"); break; case 5: sprintf(frequence_str, "32000Hz"); break; case 6: sprintf(frequence_str, "24000Hz"); break; case 7: sprintf(frequence_str, "22050Hz"); break; case 8: sprintf(frequence_str, "16000Hz"); break; case 9: sprintf(frequence_str, "12000Hz"); break; case 10: sprintf(frequence_str, "11025Hz"); break; case 11: sprintf(frequence_str, "8000Hz"); break; default: sprintf(frequence_str, "unknown"); break; } fprintf(myout, "%5d| %8s| %8s| %5d|\n", cnt, profile_str, frequence_str, size); data_size -= size; input_data += size; cnt++; } } fclose(ifile); free(aacbuffer); free(aacframe); return 0; }
链接:https://blog.csdn.net/leixiaohua1020/article/details/50535042