// 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\n", 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\n",
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;
}