对于aac ld的编码,通常为RAW的数据和每帧长度的记录,而不是通过带adts头来记录数据信息.
而相应的解码信息,通过aacDecoder_ConfigRaw来完成配置.
对于aacDecoder_ConfigRaw的配置,即ASC(audio special configure),分两种情况,拿例子说话
(1) aac eld 44.1kHz 双声道 conf为{ 0xF8, 0xE8, 0x50, 0x00 },转为二进制为:
11111 000111 0100 0010 1 0000 0000 0000
32 + 7 4 2 其他
aot为39,即eld; 4查表为44.1Hz, 2为双声道; 其他设置,参考源代码来解释,前3项正确,基本可以解码.
(2) aac ld 32kHz 单声道 conf为{ 0xBA, 0x88, 0x00, 0x00 },转为为二进制为:
10111 0101 0001 0000 0000 0000 0000 000
23 5 1 其他
aot为23,即ld; 5查表为32Hz, 1为单声道; 其他设置,参考源代码来解释,前3项正确,基本可以解码.
aot的具体含义,可以搜索aot的profile或者规格,有9种,其中aac lc广泛用于mp4中,比较常见,而aac ld用于实时音视频通信中,相对小众.
附表格为
索引 | 采样频率 |
0 | 96k |
1 | 88.2k |
2 | 64k |
3 | 48k |
4 | 44.1k |
5 | 32k |
6 | 24k |
7 | 22.05k |
8 | 16k |
9 | 12k |
a | 11.025k |
b | 8k |
c | 7.35k |
注意(1)(2)两种情况,对于audio of type (aot)的长度不同.以(2)情况的,aac ld进行解码,测试代码如下:
#include
#include
#include
#include
#include "aacdecoder_lib.h"
#include
using namespace std;
int main() {
HANDLE_AACDECODER handle;
handle = aacDecoder_Open(TT_MP4_RAW , 1);
int conceal_method=2;//0 muting 1 noise 2 interpolation
//UCHAR eld_conf[] = { 0xF8, 0xE8, 0x50, 0x00 };//ste eld 44.1k
UCHAR ld_conf[] = { 0xBA, 0x88, 0x00, 0x00 };//mono ld 32k
UCHAR *conf[] = { ld_conf };
static UINT conf_len = sizeof(ld_conf);
AAC_DECODER_ERROR err = aacDecoder_ConfigRaw(handle, conf, &conf_len);
if(err>0)
cout<<"conf err:"< 0)
cout<<"fill err:"< 0)
cout<<"dec err:"<numChannels<sampleRate<frameSize<frameSize*2,pcmHandle);
frameCnt++;
}while(true);
cout<<"frame count:"<
读入的是encode.aac的文件,文件格式是RAW, 32Khz采样,单声道.
length.txt为每一帧的长度信息,用来辅助解码,在产品环境下,可以通过rtp的负载长度,进行区分.
对于AAC_CONCEAL_METHOD,我认为选插值的方式(设置为2)比较合理.
解码后得到decoder.pcm,为原始的PCM流.