// faad2.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include <cassert> #include <iostream> #pragma comment(lib, "libfaad2.lib") #include <stdio.h> #include <memory.h> #include <string> //#ifdef UNICODE //typedef std::wstring _tstring; //#else //typedef std::string _tstring; //#endif #include <faad.h> #include "WavMaker1.h" const unsigned int g_frmMaxLen = 1024 * 5; const unsigned int g_BufMaxLen = 1024 * 2048;//1024 * 1024 /** * fetch one ADTS frame * buffer 传递的是指针而不是指针的引用真是非常巧妙的一种方式. */ int get_one_ADTS_frame(unsigned char* buffer, size_t buf_size, unsigned char* data ,size_t* data_size) { size_t size = 0; if(!buffer || !data || !data_size ) { assert(0); return -1; } while(1) { if(buf_size < 7 ) { assert(0); return -1; } if((buffer[0] == 0xff) && ((buffer[1] & 0xf0) == 0xf0) ) { // profile; 2 uimsbf // sampling_frequency_index; 4 uimsbf // private_bit; 1 bslbf // channel_configuration; 3 uimsbf // original/copy; 1 bslbf // home; 1 bslbf // copyright_identification_bit; 1 bslbf // copyright_identification_start; 1 bslbf // frame_length; 13 bslbf 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 _tmain(int argc, _TCHAR* argv[]) { static unsigned char aacFrm[g_frmMaxLen]; //aac 最大帧长 static unsigned char buffer[g_BufMaxLen]; //截取 aac文件的最大长度 string src_file = "mp410.AAC";//输入文件 string dst_file = "mp410.wav";//输出文件 FILE* ifile = NULL; unsigned long samplerate = 0; unsigned char channels = 0; NeAACDecHandle decoder = 0; size_t data_size = 0; size_t size = 0; NeAACDecFrameInfo frame_info; memset(&frame_info, 0, sizeof(frame_info)); unsigned char* input_data = buffer; unsigned char* pcm_data = NULL; ifile = fopen(src_file.c_str(), "rb"); //打开输入文件 const char* p = dst_file.c_str(); WavMaker WavFile(p); if(!ifile) { assert(0); printf("source or destination file"); return -1; } //* 读取AAC文件. data_size = fread(buffer, 1, g_BufMaxLen, ifile); //读取AAC文件长度 //* 打开解码器 decoder = NeAACDecOpen(); //* 初始化解码器 if(get_one_ADTS_frame(buffer, data_size, aacFrm, &size) < 0) { assert(0); return -1; } NeAACDecInit(decoder, aacFrm, size, &samplerate, &channels); printf("samplerate %d, channels %d ", samplerate, channels); //* 初始化Wav结构 //WAVEFORMATEX fmt; //fmt.wFormatTag = WAVE_FORMAT_PCM; //fmt.nChannels = channels; //fmt.nSamplesPerSec = samplerate; //fmt.wBitsPerSample = 16; //fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample /8; //fmt.nAvgBytesPerSec = fmt.nBlockAlign * samplerate; //fmt.cbSize = 0; //ofile.Init(fmt); //* 循环解码,写文件 while(get_one_ADTS_frame(input_data, data_size, aacFrm, &size) == 0) { pcm_data = (unsigned char*)NeAACDecDecode(decoder, &frame_info, aacFrm, size); //解码信息在frame_info if(frame_info.error > 0) { std::cout<<NeAACDecGetErrorMessage(frame_info.error)<<std::endl; } else if(pcm_data && frame_info.samples > 0) { printf("frame info: bytesconsumed %d, channels %d, header_type %d object_type %d, samples %d, samplerate %d ", frame_info.bytesconsumed, frame_info.channels, frame_info.header_type, frame_info.object_type, frame_info.samples, frame_info.samplerate); WavFile.writebody(pcm_data, frame_info.samples * frame_info.channels );//may be 有问题 } data_size -= size; input_data += size; } NeAACDecClose(decoder); fclose(ifile); WavFile.writeheader(frame_info.channels,frame_info.samplerate); WavFile.closeFile(); return 0; }