Use FAAD decoding AAC audio for PCM data flow can refer to the following article
Http://blog.csdn.net/gavinr/article/details/6959198#reply
/** * FAADDEC.C * use Faad Library to decode AAC, only can decode frame with ADTS head */#include <stdio.h> #include <memory.h> #include "faad.h" #define Frame_max_len 1024*5 #define Buffer_max_len 1024*1024void show_usage () {print F ("Usage\nfaaddec src_file dst_file");} /** * Fetch one ADTS frame */int get_one_adts_frame (unsigned char* buffer, size_t buf_size, unsigned char* data, size_t* D Ata_size) {size_t size = 0; if (!buffer | |!data | |!data_size) {return-1; } while (1) {if (Buf_size < 7) {return-1; } 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 main (int argc, char* argv[]) {static unsigned char Frame[frame_max_len]; static unsigned char Buffer[buffer_max_len] = {0}; Char src_file[128] = {0}; Char dst_file[128] = {0}; file* ifile = NULL; file* ofile = NULL; unsigned long samplerate; unsigned char channels; Neaacdechandle decoder = 0; size_t data_size = 0; size_t size = 0; Neaacdecframeinfo Frame_info; unsigned char* input_data = buffer; unsigned char* pcm_data = NULL; Analyse parameter if (ARGC < 3) {show_usage (); return-1; } sscanf (Argv[1], "%s", src_file); SSCANF (Argv[2], "%s", dst_file); IFile = fopen (Src_file, "RB"); ofile = fopen (Dst_file, "WB"); if (!ifile | |!ofile) {printf ("Source or destination file"); return-1; } data_size = fread (buffer, 1, Buffer_max_len, ifile); Open Decoder decoder = Neaacdecopen (); IfGet_one_adts_frame (buffer, data_size, frame, &size) < 0) {return-1; }//initialize Decoder Neaacdecinit (decoder, frame, size, &samplerate, &channels); printf ("Samplerate%d, channels%d\n", samplerate, Channels); while (Get_one_adts_frame (Input_data, data_size, frame, &size) = = 0) {//printf ("Frame size%d\n", size); Decode ADTS Frame pcm_data = (unsigned char*) neaacdecdecode (decoder, &frame_info, frame, size); if (Frame_info.error > 0) {printf ("%s\n", Neaacdecgeterrormessage (Frame_info.error)); } else if (pcm_data && frame_info.samples > 0) {printf ("Frame info:bytes Consumed%d, channels%d, Header_type%d object_type%d, samples%d, samplerate%d\n ", Fram E_info.bytesconsumed, Frame_info.channels, Frame_info.header_type, Frame_info.object_type, Frame_info.samples, frame_info.samplerate); Fwrite (Pcm_data, 1, Frame_info.samples * frame_info.channels, ofile); 2 channels of Fflush (ofile); } data_size-= size; Input_data + = size; } neaacdecclose (decoder); Fclose (ifile); Fclose (ofile); return 0;}
Previously encoded with FAAC a PCM data (source data is 16000 sample rate, single channel, 16-bit sampling), the parameters set by encoding is also 16000 sample rate, single channel, 16-bit sampling ... Then decoding with Faad, when the Neaacdecinit, is first encoded in the AAC data (Adts header package) on the buffer to write a frame of the data containing the ADTS header, and then passed into the Neaacdecinit () in the initial resolution code, but do not know why , the sample rate returned is always 32000, the number of channels is always 2, I have looked at the encoded data, which corresponds to the sampling rate, the number of channels corresponding to the bit, that is 16000 sample rate and 1 channels.
later tracking source found Faad neaacdecinit () source code, the problem appears here
Long Neaacdecapi neaacdecinit (Neaacdechandle hpdecoder, unsignedchar *buffer, unsignedlong buffer_size, unsignedlong *samplerate, Unsignedchar *channels) {#if (defined (PS_DEC) | | defined (DRM_PS))/* Check if we have a Mono file */if (*channels = = 1) { /* Upmatrix to 2 channels for implicit signalling of PS * /*channels = 2;//Here CH Annels change to 2,why?} #endifhDecoder->channelconfiguration = *channels; #ifdef sbr_dec/* Implicit signalling */if (*samplerate <= 24000 & amp;& (HDECODER->CONFIG.DONTUPSAMPLEIMPLICITSBR = = 0)) { *samplerate *= 2;//Samplerate into 32000 hdecoder->forceupsampling = 1;} <pre name= "code" class= "CPP" >else if (*samplerate > 24000 && (hdecoder-> CONFIG.DONTUPSAMPLEIMPLICITSBR = = 0)) { hdecoder->downsampledsbr = 1;} #endif}
The above macros, in the source code seems to have been dead, not by the conditional compilation generated,
That is, Ps_dec and Sbr_dec are define. Nor is it through the./configure generation of ...
Take a closer look at the IF statement of the above code
Let's look at the definition of the struct in the neaacdec.h file.
Now it's easy to solve this problem, set the parameter dontupsampleimplicitsbr to 1 before initializing.
Neaacdecconfigurationptr conf = neaacdecgetcurrentconfiguration (decoder); conf->defobjecttype = LC;conf-> Defsamplerate = 8000; Real Samplerate/2conf->outputformat = Faad_fmt_16bit; CONF->DONTUPSAMPLEIMPLICITSBR = 1;<p>neaacdecsetconfiguration (decoder, conf); </p><p></p >
Finally, spit the groove. The FAAD description document downloaded from the official website describes the structure of neaacdecconfiguration ,
no, actually . DONTUPSAMPLEIMPLICITSBR This member, it's too much for dad.
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Decoding AAC instances with Faad Library and incorrect channel count after decoding with Faad