FAAC source code Analysis of Faacencencode

Source: Internet
Author: User
Tags diff

FAAC Coding Code Flowchart


A general block diagram of the AAC coding system (stolen pictures)


The comparison can be found, in fact, FAAC encoding and general AAC coding is roughly the same, mainly including the psychological acoustics model processing part and quantization processing two parts, also includes some optimization process. Implementation of the source + comment:

int Faacapi Faacencencode (faacenchandle hencoder,int32_t *inputbuffer,unsigned int samplesinput,unsigned char * outputbuffer,unsigned int buffersize) {unsigned int channel, i;int SB, framebytes;unsigned int offset; Bitstream *bitstream; /* Bitstream used for writing, the frame to */tnsinfo *TNSINFO_FOR_LTP;  Tnsinfo *tnsdecinfo; #ifdef drmint desbits, diff;double fix; #endif/* Local copy ' s of parameters */channelinfo *channelinfo = hencoder->channelinfo; Coderinfo *coderinfo = hencoder->coderinfo;unsigned int numchannels = hencoder->numchannels;unsigned int samplerate = hencoder->samplerate;unsigned int aacobjecttype = hencoder->config.aacobjecttype;unsigned int mpegversion = hencoder->config.mpegversion;unsigned int uselfe = hencoder->config.uselfe;unsigned int useTns = hencoder->config.usetns;unsigned int allowmidside = hencoder->config.allowmidside;unsigned int bandWidth = hencoder->config.bandwidth;unsigned int shortctl = hencoder->config.shortctl;/* IncreasE frame number */hencoder->framenum++;if (Samplesinput = = 0) hencoder->flushframe++;/* after 4 flush frames all Sampl ES has been encoded,return 0 bytes written */if (Hencoder->flushframe > 4) return 0;/* determine the channel Configu Ration */getchannelinfo (Channelinfo, Numchannels, Uselfe);/* Update Current sample buffers */for (channel = 0; Channel &lt ; Numchannels; channel++) {double *tmp;if (Hencoder->samplebuff[channel]) {for (i = 0; i < Frame_len; i++) {Hencoder->ltptimebuf F[channel][i] = Hencoder->samplebuff[channel][i];}} if (Hencoder->nextsamplebuff[channel]) {for (i = 0; i < Frame_len; i++) {hencoder->ltptimebuff[channel][frame_ LEN + i] =hencoder->nextsamplebuff[channel][i];}} if (!hencoder->samplebuff[channel]) Hencoder->samplebuff[channel] = (double*) allocmemory (FRAME_LEN*sizeof ( (double)); tmp = hencoder->samplebuff[channel];hencoder->samplebuff[channel]= hencoder->nextsamplebuff[ channel];hencoder->nextsamplebuff[channel]= Hencoder->next2samplebuff[channel];hencoder->next2samplebuff[channel]= hencoder->next3samplebuff[channel]; hencoder->next3samplebuff[channel]= tmp;if (Samplesinput = = 0) {/* start flushing*/for (i = 0; i < Frame_len; i++) hEn Coder->next3samplebuff[channel][i] = 0.0;} Else{int Samples_per_channel = samplesinput/numchannels;/* Handle the various input formats and channel remapping */switch (Hencoder->config.inputformat) {case Faac_input_16bit:{short *input_channel = (short*) InputBuffer + hencoder->config.channel_map[channel];for (i = 0; i < Samples_per_channel; i++) {Hencoder->next3samplebuff[channel][i] = (double) *input_channel;input_channel + = Numchannels;}} Break;case faac_input_32bit:{int32_t *input_channel = (int32_t*) InputBuffer + hencoder->config.channel_map[ Channel];for (i = 0; i < Samples_per_channel; i++) {Hencoder->next3samplebuff[channel][i] = (1.0/256) * (double) *INP Ut_channel;input_channel + = Numchannels;}} Break;case faac_input_float:{float *input_Channel = (float*) InputBuffer + hencoder->config.channel_map[channel];for (i = 0; i < Samples_per_channel; i++) {HEn Coder->next3samplebuff[channel][i] = (double) *input_channel;input_channel + = Numchannels;}} break;default:return-1; /* Invalid input format */break;} for (i = (int) (samplesinput/numchannels), I < Frame_len; i++) hencoder->next3samplebuff[channel][i] = 0.0;} /* psychoacoustics *//* Update buffers and run FFT on new samples *//* LFE psychoacoustic can run without it */if (!channe Linfo[channel].lfe | | CHANNELINFO[CHANNEL].CPE) {//The buffer update of the psychological acoustics model, calculates the current frame energy value hencoder->psymodel->psybufferupdate (&hEncoder-> Fft_tables, &hencoder->gpsyinfo, &hencoder->psyinfo[channel],hencoder->next3samplebuff[channel] , Bandwidth,hencoder->srinfo->cb_width_short,hencoder->srinfo->num_cb_short);}} if (Hencoder->framenum <= 3)/* Still filling up the buffers */return 0;//internal call to implement detection transient signal, determine the length of the block/* psychoacoustics */h Encoder->psymodel->psycalculAte (Channelinfo, &hencoder->gpsyinfo, Hencoder->psyinfo,hencoder->srinfo->cb_width_long, Hencoder->srinfo->num_cb_long,hencoder->srinfo->cb_width_short,hencoder->srinfo->num_cb_ short, numchannels);//long block switching Hencoder->psymodel->blockswitch (Coderinfo, Hencoder->psyinfo, numChannels);/* Force block Type */if (Shortctl = = Shortctl_noshort) {for (channel = 0; channel < numchannels; channel++) {Coderinfo[chan Nel].block_type = Only_long_window;}} if (Shortctl = = Shortctl_nolong) {for (channel = 0; channel < numchannels; channel++) {Coderinfo[channel].block_type = on Ly_short_window;}} /* AAC Filterbank, MDCT with overlap and add */for (channel = 0; channel < numchannels; channel++) {int k; Filterbank (Hencoder,&coderinfo[channel],hencoder->samplebuff[channel],hencoder->freqbuff[channel], hencoder->overlapbuff[channel],moverlapped); if (Coderinfo[channel].block_type = = Only_short_window) {for (k = 0; K & Lt 8; k++) {Specfilter (HENCODER-&GT;FREqbuff[channel]+k*block_len_short,samplerate, BandWidth, Block_len_short);}} else {specfilter (Hencoder->freqbuff[channel], samplerate,bandwidth, Block_len_long);}} /* tmp:build SFB offset table and other stuff */for (channel = 0; channel < numchannels; channel++) {Channelinfo[chann El].msinfo.is_present = 0;if (Coderinfo[channel].block_type = = Only_short_window) {CODERINFO[CHANNEL].MAX_SFB = HENCODER-&GT;SRINFO-&GT;NUM_CB_SHORT;CODERINFO[CHANNEL].NR_OF_SFB = hencoder->srinfo->num_cb_short; Coderinfo[channel].num_window_groups = 1;coderinfo[channel].window_group_length[0] = 8;coderInfo[channel].window_ GROUP_LENGTH[1] = 0;coderinfo[channel].window_group_length[2] = 0;coderinfo[channel].window_group_length[3] = 0; CODERINFO[CHANNEL].WINDOW_GROUP_LENGTH[4] = 0;coderinfo[channel].window_group_length[5] = 0;coderInfo[channel]. WINDOW_GROUP_LENGTH[6] = 0;coderinfo[channel].window_group_length[7] = 0;offset = 0;for (sb = 0; SB < CoderInfo[channel ].NR_OF_SFB; sb++) {Coderinfo[channel].SFB_OFFSET[SB] = Offset;offset + = HENCODER-&GT;SRINFO-&GT;CB_WIDTH_SHORT[SB];} CODERINFO[CHANNEL].SFB_OFFSET[CODERINFO[CHANNEL].NR_OF_SFB] = offset;} else {CODERINFO[CHANNEL].MAX_SFB = HENCODER-&GT;SRINFO-&GT;NUM_CB_LONG;CODERINFO[CHANNEL].NR_OF_SFB = hEncoder-> Srinfo->num_cb_long;coderinfo[channel].num_window_groups = 1;coderinfo[channel].window_group_length[0] = 1;o Ffset = 0;for (sb = 0; sb < CODERINFO[CHANNEL].NR_OF_SFB; sb++) {CODERINFO[CHANNEL].SFB_OFFSET[SB] = Offset;offset + = h ENCODER-&GT;SRINFO-&GT;CB_WIDTH_LONG[SB];} CODERINFO[CHANNEL].SFB_OFFSET[CODERINFO[CHANNEL].NR_OF_SFB] = offset;}} /* Perform TNS Analysis and filtering */for (channel = 0; channel < numchannels; channel++) {if (!channelinfo[channel) . Lfe) && (usetns) {Tnsencode (& coderinfo[channel].tnsinfo), coderinfo[channel].max_sfb,coderinfo[ CHANNEL].MAX_SFB, (Window_type) coderinfo[channel].block_type,coderinfo[channel].sfb_offset,hencoder-> Freqbuff[channel]);} else {coderinfo[channel].tnsinfo.tnsdatapresent = 0; /* TNS not used for LFE */}}for (channel = 0; channel < numchannels; channel++) {if (coderinfo[channel].tnsinfo.tnsdatapr Esent! = 0) && (usetns)) TNSINFO_FOR_LTP = & (Coderinfo[channel].tnsinfo); ELSETNSINFO_FOR_LTP = Null;if ( Channelinfo[channel].present && (!channelinfo[channel].lfe) && (coderinfo[channel].block_type! = Only_short_window) && (mpegversion = = MPEG4) && (Aacobjecttype = = LTP)) {Ltpencode (hencoder,& coderinfo[channel],& (coderinfo[channel].ltpinfo), tnsinfo_for_ltp,hencoder->freqbuff[channel],hencoder- >ltptimebuff[channel]);} else {coderinfo[channel].ltpinfo.global_pred_flag = 0;}}  for (channel = 0; channel < numchannels; channel++) {if (Aacobjecttype = = MAIN) && (!channelinfo[channel].lfe)) {int numpredbands = min (CODERINFO[CHANNEL].MAX_PRED_SFB, CODERINFO[CHANNEL].NR_OF_SFB); Predcalcprediction (Hencoder->freqbuff[channel],coderinfo[channel].requantfreq,coderinfo[channel].block_type NumPredbands, (Coderinfo[channel].block_type==only_short_window)? hencoder->srinfo->cb_width_short:hencoder- >srinfo->cb_width_long,coderinfo,channelinfo,channel);} else {coderinfo[channel].pred_global_flag = 0;}} for (channel = 0; channel < numchannels; channel++) {if (Coderinfo[channel].block_type = = Only_short_window) {Sortforgr Ouping (&coderInfo[channel],&hEncoder->psyInfo[channel],&channelInfo[channel],hEncoder-> Srinfo->cb_width_short,hencoder->freqbuff[channel]);} Calcavgenrg (&coderinfo[channel], Hencoder->freqbuff[channel]);//Reduce LFE Bandwidthif (!channelinfo[ CHANNEL].CPE && channelinfo[channel].lfe) {CODERINFO[CHANNEL].NR_OF_SFB = CODERINFO[CHANNEL].MAX_SFB = 3;}} Msencode (Coderinfo, Channelinfo, Hencoder->freqbuff, Numchannels, allowmidside); for (channel = 0; Channel < Numchannels; channel++) {Calcavgenrg (&coderinfo[channel], Hencoder->freqbuff[channel]);} #ifdef drm/* Loop The quantization until the desired bit-rate is reached */diff = 1; /* To enter while loop */hencoder->aacquantcfg.quality = 120; /* Init Quality setting */while (diff > 0) {/* If too many bits, do it again */#endif/* quantize and code the signal * /for (channel = 0; channel < numchannels; channel++) {if (Coderinfo[channel].block_type = = Only_short_window) {aacquant Ize (&coderinfo[channel], &hencoder->psyinfo[channel],&channelinfo[channel], hEncoder->srInfo- >cb_width_short,hencoder->srinfo->num_cb_short, hencoder->freqbuff[channel],& (hEncoder-> aacquantcfg));} else {aacquantize (&coderinfo[channel], &hencoder->psyinfo[channel],&channelinfo[channel], Hencoder->srinfo->cb_width_long,hencoder->srinfo->num_cb_long, hencoder->freqbuff[channel],& (hencoder->aacquantcfg));}} #ifdef drm/* Write the AAC bitstream */bitstream = Openbitstream (buffersize, OutputBuffer); Writebitstream (Hencoder, Coderinfo, Channelinfo, Bitstream, numchannels);/* Close the Bitstream and Return the number of bytes written */framebytes = Closebitstream (bitstream);/* Now calculate desired bits and compare wit h actual encoded bits */desbits = (int) ((double) numchannels * (hencoder->config.bitrate * frame_len)/Hencoder->sa  mplerate);d iff = ((FRAMEBYTES-1 */CRC */) * 8)-desbits;/* do linear correction according to relative difference */fix = (double) desbits/((FRAMEBYTES-1 */CRC * *) * 8);/* speed up convergence.  A value of 0.92 gives approx up to ten iterations */if (fix > 0.92) fix = 0.92;hencoder->aacquantcfg.quality *= fix;/* Quality should not go lower than 1, set diff to exit Loop */if (hencoder->aacquantcfg.quality <= 1) diff =-1;} #endif//fix MAX_SFB in CPE modefor (channel = 0; channel < numchannels; channel++) {if (channelinfo[channel].present&am p;& (CHANNELINFO[CHANNEL].CPE) && (channelinfo[channel].ch_is_left)) {Coderinfo *cil, *cir;cil = & Coderinfo[channel];cir = &coderinfo[channelinfo[channel].paired_ch];cil->mAX_SFB = CIR-&GT;MAX_SFB = Max (CIL-&GT;MAX_SFB, CIR-&GT;MAX_SFB); CIL-&GT;NR_OF_SFB = CIR-&GT;NR_OF_SFB = Cil->max_ SFB;}} Msreconstruct (Coderinfo, Channelinfo, Numchannels); for (channel = 0; channel < numchannels; channel++) {/* If short Wind ow, reconstruction not needed for prediction */if ((Coderinfo[channel].block_type = = Only_short_window)) {int sind;for (SI nd = 0; sind < Block_len_long; sind++) {Coderinfo[channel].requantfreq[sind] = 0.0;}} else {if ((coderinfo[channel].tnsinfo.tnsdatapresent! = 0) && (usetns)) Tnsdecinfo = & (Coderinfo[channel]. Tnsinfo) Elsetnsdecinfo = Null;if ((!channelinfo[channel].lfe) && (Aacobjecttype = = LTP)) {/* No reconstruction Needed for LFE channel*/ltpreconstruct (&coderinfo[channel], & (Coderinfo[channel].ltpinfo), coderinfo[ CHANNEL].REQUANTFREQ); if (tnsdecinfo! = NULL) tnsdecodefilteronly (& (Coderinfo[channel].tnsinfo), coderInfo[ CHANNEL].NR_OF_SFB,CODERINFO[CHANNEL].MAX_SFB, (Window_type) Coderinfo[channel].block_type, Coderinfo[channel].sfb_offset, Coderinfo[channel].requantfreq); Ifilterbank (Hencoder, &coderInfo[channel], Coderinfo[channel].requantfreq,coderinfo[channel].ltpinfo.time_buffer,coderinfo[channel].ltpinfo.ltp_overlap_ buffer,moverlapped); Ltpupdate (& (Coderinfo[channel].ltpinfo), Coderinfo[channel].ltpinfo.time_buffer,coderinfo[channel]. Ltpinfo.ltp_overlap_buffer,block_len_long);}}} #ifndef drm/* Write the AAC bitstream */bitstream = Openbitstream (buffersize, OutputBuffer); Writebitstream (Hencoder, Coderinfo, Channelinfo, Bitstream, numchannels);/* Close the bitstream and return the number of B Ytes written */framebytes = Closebitstream (bitstream);/* Adjust quality to get correct average bitrate */if (hencoder-> config.bitrate) {double Fix;int desbits = Numchannels * (hencoder->config.bitrate * frame_len)/hEncoder-> Samplerate;int diff = (framebytes * 8)-Desbits;hencoder->bitdiff + = Diff;fix = (double) hencoder->bitdiff/desbits Fix *= 0.01;fix = max (fix, -0.2); fix = min (fix, 0.2); if ((diff > 0) && (fix > 0.0)) | | (diff < 0) && (fix < 0.0))) {hencoder->aacquantcfg.quality *= (1.0-fix); if (Hencoder->aacquantcfg.quality >) hencoder-> aacquantcfg.quality = 300;if (hencoder->aacquantcfg.quality <) hencoder->aacquantcfg.quality = 50;}} #endifreturn Framebytes;}

FAAC source code Analysis of Faacencencode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.