encoder.c

Go to the documentation of this file.
00001 /*
00002  *      LAME MP3 encoding engine
00003  *
00004  *      Copyright (c) 1999 Mark Taylor
00005  *      Copyright (c) 2000-2002 Takehiro Tominaga
00006  *      Copyright (c) 2000-2005 Robert Hegemann
00007  *      Copyright (c) 2001 Gabriel Bouvigne
00008  *      Copyright (c) 2001 John Dahlstrom
00009  *
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Library General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the
00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00023  * Boston, MA 02111-1307, USA.
00024  */
00025 
00026 /* $Id: encoder.c,v 1.99 2007/07/24 17:46:10 bouvigne Exp $ */
00027 
00028 #ifdef HAVE_CONFIG_H
00029 #include <config.h>
00030 #endif
00031 
00032 
00033 #include "lame.h"
00034 #include "machine.h"
00035 #include "encoder.h"
00036 #include "util.h"
00037 #include "lame_global_flags.h"
00038 #include "newmdct.h"
00039 #include "psymodel.h"
00040 #include "lame-analysis.h"
00041 #include "bitstream.h"
00042 #include "VbrTag.h"
00043 #include "quantize_pvt.h"
00044 
00045 
00046 
00047 /*
00048  * auto-adjust of ATH, useful for low volume
00049  * Gabriel Bouvigne 3 feb 2001
00050  *
00051  * modifies some values in
00052  *   gfp->internal_flags->ATH
00053  *   (gfc->ATH)
00054  */
00055 static void
00056 adjust_ATH(lame_internal_flags const *const gfc)
00057 {
00058     FLOAT   gr2_max, max_pow;
00059 
00060     if (gfc->ATH->use_adjust == 0) {
00061         gfc->ATH->adjust = 1.0; /* no adjustment */
00062         return;
00063     }
00064 
00065     /* jd - 2001 mar 12, 27, jun 30 */
00066     /* loudness based on equal loudness curve; */
00067     /* use granule with maximum combined loudness */
00068     max_pow = gfc->loudness_sq[0][0];
00069     gr2_max = gfc->loudness_sq[1][0];
00070     if (gfc->channels_out == 2) {
00071         max_pow += gfc->loudness_sq[0][1];
00072         gr2_max += gfc->loudness_sq[1][1];
00073     }
00074     else {
00075         max_pow += max_pow;
00076         gr2_max += gr2_max;
00077     }
00078     if (gfc->mode_gr == 2) {
00079         max_pow = Max(max_pow, gr2_max);
00080     }
00081     max_pow *= 0.5;     /* max_pow approaches 1.0 for full band noise */
00082 
00083     /* jd - 2001 mar 31, jun 30 */
00084     /* user tuning of ATH adjustment region */
00085     max_pow *= gfc->ATH->aa_sensitivity_p;
00086 
00087     /*  adjust ATH depending on range of maximum value
00088      */
00089 
00090     /* jd - 2001 feb27, mar12,20, jun30, jul22 */
00091     /* continuous curves based on approximation */
00092     /* to GB's original values. */
00093     /* For an increase in approximate loudness, */
00094     /* set ATH adjust to adjust_limit immediately */
00095     /* after a delay of one frame. */
00096     /* For a loudness decrease, reduce ATH adjust */
00097     /* towards adjust_limit gradually. */
00098     /* max_pow is a loudness squared or a power. */
00099     if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */
00100         if (gfc->ATH->adjust >= 1.0) {
00101             gfc->ATH->adjust = 1.0;
00102         }
00103         else {
00104             /* preceding frame has lower ATH adjust; */
00105             /* ascend only to the preceding adjust_limit */
00106             /* in case there is leading low volume */
00107             if (gfc->ATH->adjust < gfc->ATH->adjust_limit) {
00108                 gfc->ATH->adjust = gfc->ATH->adjust_limit;
00109             }
00110         }
00111         gfc->ATH->adjust_limit = 1.0;
00112     }
00113     else {              /* adjustment curve */
00114         /* about 32 dB maximum adjust (0.000625) */
00115         FLOAT const adj_lim_new = 31.98 * max_pow + 0.000625;
00116         if (gfc->ATH->adjust >= adj_lim_new) { /* descend gradually */
00117             gfc->ATH->adjust *= adj_lim_new * 0.075 + 0.925;
00118             if (gfc->ATH->adjust < adj_lim_new) { /* stop descent */
00119                 gfc->ATH->adjust = adj_lim_new;
00120             }
00121         }
00122         else {          /* ascend */
00123             if (gfc->ATH->adjust_limit >= adj_lim_new) {
00124                 gfc->ATH->adjust = adj_lim_new;
00125             }
00126             else {      /* preceding frame has lower ATH adjust; */
00127                 /* ascend only to the preceding adjust_limit */
00128                 if (gfc->ATH->adjust < gfc->ATH->adjust_limit) {
00129                     gfc->ATH->adjust = gfc->ATH->adjust_limit;
00130                 }
00131             }
00132         }
00133         gfc->ATH->adjust_limit = adj_lim_new;
00134     }
00135 }
00136 
00137 /***********************************************************************
00138  *
00139  *  some simple statistics
00140  *
00141  *  bitrate index 0: free bitrate -> not allowed in VBR mode
00142  *  : bitrates, kbps depending on MPEG version
00143  *  bitrate index 15: forbidden
00144  *
00145  *  mode_ext:
00146  *  0:  LR
00147  *  1:  LR-i
00148  *  2:  MS
00149  *  3:  MS-i
00150  *
00151  ***********************************************************************/
00152 
00153 static void
00154 updateStats(lame_internal_flags * const gfc)
00155 {
00156     int     gr, ch;
00157     assert(gfc->bitrate_index < 16u);
00158     assert(gfc->mode_ext < 4u);
00159 
00160     /* count bitrate indices */
00161     gfc->bitrate_stereoMode_Hist[gfc->bitrate_index][4]++;
00162     gfc->bitrate_stereoMode_Hist[15][4]++;
00163 
00164     /* count 'em for every mode extension in case of 2 channel encoding */
00165     if (gfc->channels_out == 2) {
00166         gfc->bitrate_stereoMode_Hist[gfc->bitrate_index][gfc->mode_ext]++;
00167         gfc->bitrate_stereoMode_Hist[15][gfc->mode_ext]++;
00168     }
00169     for (gr = 0; gr < gfc->mode_gr; ++gr) {
00170         for (ch = 0; ch < gfc->channels_out; ++ch) {
00171             int     bt = gfc->l3_side.tt[gr][ch].block_type;
00172             if (gfc->l3_side.tt[gr][ch].mixed_block_flag)
00173                 bt = 4;
00174             gfc->bitrate_blockType_Hist[gfc->bitrate_index][bt]++;
00175             gfc->bitrate_blockType_Hist[gfc->bitrate_index][5]++;
00176             gfc->bitrate_blockType_Hist[15][bt]++;
00177             gfc->bitrate_blockType_Hist[15][5]++;
00178         }
00179     }
00180 }
00181 
00182 
00183 
00184 
00185 static void
00186 lame_encode_frame_init(lame_global_flags const *const gfp, const sample_t * inbuf[2])
00187 {
00188     lame_internal_flags *const gfc = gfp->internal_flags;
00189 
00190     int     ch, gr;
00191 
00192     if (gfc->lame_encode_frame_init == 0) {
00193         /* prime the MDCT/polyphase filterbank with a short block */
00194         int     i, j;
00195         sample_t primebuff0[286 + 1152 + 576];
00196         sample_t primebuff1[286 + 1152 + 576];
00197         gfc->lame_encode_frame_init = 1;
00198         for (i = 0, j = 0; i < 286 + 576 * (1 + gfc->mode_gr); ++i) {
00199             if (i < 576 * gfc->mode_gr) {
00200                 primebuff0[i] = 0;
00201                 if (gfc->channels_out == 2)
00202                     primebuff1[i] = 0;
00203             }
00204             else {
00205                 primebuff0[i] = inbuf[0][j];
00206                 if (gfc->channels_out == 2)
00207                     primebuff1[i] = inbuf[1][j];
00208                 ++j;
00209             }
00210         }
00211         /* polyphase filtering / mdct */
00212         for (gr = 0; gr < gfc->mode_gr; gr++) {
00213             for (ch = 0; ch < gfc->channels_out; ch++) {
00214                 gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE;
00215             }
00216         }
00217         mdct_sub48(gfc, primebuff0, primebuff1);
00218 
00219         /* check FFT will not use a negative starting offset */
00220 #if 576 < FFTOFFSET
00221 # error FFTOFFSET greater than 576: FFT uses a negative offset
00222 #endif
00223         /* check if we have enough data for FFT */
00224         assert(gfc->mf_size >= (BLKSIZE + gfp->framesize - FFTOFFSET));
00225         /* check if we have enough data for polyphase filterbank */
00226         assert(gfc->mf_size >= (512 + gfp->framesize - 32));
00227     }
00228 
00229 }
00230 
00231 
00232 
00233 
00234 
00235 
00236 
00237 /************************************************************************
00238 *
00239 * encodeframe()           Layer 3
00240 *
00241 * encode a single frame
00242 *
00243 ************************************************************************
00244 lame_encode_frame()
00245 
00246 
00247                        gr 0            gr 1
00248 inbuf:           |--------------|--------------|--------------|
00249 
00250 
00251 Polyphase (18 windows, each shifted 32)
00252 gr 0:
00253 window1          <----512---->
00254 window18                 <----512---->
00255 
00256 gr 1:
00257 window1                         <----512---->
00258 window18                                <----512---->
00259 
00260 
00261 
00262 MDCT output:  |--------------|--------------|--------------|
00263 
00264 FFT's                    <---------1024---------->
00265                                          <---------1024-------->
00266 
00267 
00268 
00269     inbuf = buffer of PCM data size=MP3 framesize
00270     encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
00271     so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
00272 
00273     psy-model FFT has a 1 granule delay, so we feed it data for the 
00274     next granule.
00275     FFT is centered over granule:  224+576+224
00276     So FFT starts at:   576-224-MDCTDELAY
00277 
00278     MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY      (1328)
00279     MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)
00280 
00281     MPEG2:  polyphase first window:  [0..511]
00282                       18th window:   [544..1055]          (1056)
00283     MPEG1:            36th window:   [1120..1631]         (1632)
00284             data needed:  512+framesize-32
00285 
00286     A close look newmdct.c shows that the polyphase filterbank
00287     only uses data from [0..510] for each window.  Perhaps because the window
00288     used by the filterbank is zero for the last point, so Takehiro's
00289     code doesn't bother to compute with it.
00290 
00291     FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET
00292 
00293 */
00294 
00295 typedef FLOAT chgrdata[2][2];
00296 
00297 
00298 int
00299 lame_encode_mp3_frame(       /* Output */
00300                          lame_global_flags * const gfp, /* Context */
00301                          sample_t const *inbuf_l, /* Input */
00302                          sample_t const *inbuf_r, /* Input */
00303                          unsigned char *mp3buf, /* Output */
00304                          int mp3buf_size)
00305 {                       /* Output */
00306     int     mp3count;
00307     III_psy_ratio masking_LR[2][2]; /*LR masking & energy */
00308     III_psy_ratio masking_MS[2][2]; /*MS masking & energy */
00309     III_psy_ratio(*masking)[2][2]; /*pointer to selected maskings */
00310     const sample_t *inbuf[2];
00311     lame_internal_flags *const gfc = gfp->internal_flags;
00312 
00313     FLOAT   tot_ener[2][4];
00314     FLOAT   ms_ener_ratio[2] = { .5, .5 };
00315     chgrdata pe = { {0., 0.}, {0., 0.} }, pe_MS = { {
00316     0., 0.}, {
00317     0., 0.}};
00318     chgrdata *pe_use;
00319 
00320     int     ch, gr;
00321 
00322     FLOAT   ms_ratio_next = 0.;
00323     FLOAT   ms_ratio_prev = 0.;
00324 
00325 
00326     inbuf[0] = inbuf_l;
00327     inbuf[1] = inbuf_r;
00328 
00329     if (gfc->lame_encode_frame_init == 0) {
00330         /*first run? */
00331         lame_encode_frame_init(gfp, inbuf);
00332 
00333     }
00334 
00335 
00336     /********************** padding *****************************/
00337     /* padding method as described in 
00338      * "MPEG-Layer3 / Bitstream Syntax and Decoding"
00339      * by Martin Sieler, Ralph Sperschneider
00340      *
00341      * note: there is no padding for the very first frame
00342      *
00343      * Robert Hegemann 2000-06-22
00344      */
00345     gfc->padding = FALSE;
00346     if ((gfc->slot_lag -= gfc->frac_SpF) < 0) {
00347         gfc->slot_lag += gfp->out_samplerate;
00348         gfc->padding = TRUE;
00349     }
00350 
00351 
00352 
00353     /****************************************
00354     *   Stage 1: psychoacoustic model       *
00355     ****************************************/
00356 
00357     if (gfc->psymodel) {
00358         /* psychoacoustic model
00359          * psy model has a 1 granule (576) delay that we must compensate for
00360          * (mt 6/99).
00361          */
00362         int     ret;
00363         const sample_t *bufp[2]; /* address of beginning of left & right granule */
00364         int     blocktype[2];
00365 
00366         ms_ratio_prev = gfc->ms_ratio[gfc->mode_gr - 1];
00367         for (gr = 0; gr < gfc->mode_gr; gr++) {
00368 
00369             for (ch = 0; ch < gfc->channels_out; ch++)
00370                 bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET];
00371 
00372             if (gfp->psymodel == PSY_NSPSYTUNE) {
00373                 ret = L3psycho_anal_ns(gfp, bufp, gr,
00374                                        masking_LR, masking_MS,
00375                                        pe[gr], pe_MS[gr], tot_ener[gr], blocktype);
00376             }
00377             else {
00378                 ret = L3psycho_anal(gfp, bufp, gr,
00379                                     &gfc->ms_ratio[gr], &ms_ratio_next,
00380                                     masking_LR, masking_MS,
00381                                     pe[gr], pe_MS[gr], tot_ener[gr], blocktype);
00382             }
00383             if (ret != 0)
00384                 return -4;
00385 
00386             if (gfp->mode == JOINT_STEREO) {
00387                 ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];
00388                 if (ms_ener_ratio[gr] > 0)
00389                     ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];
00390             }
00391 
00392             /* block type flags */
00393             for (ch = 0; ch < gfc->channels_out; ch++) {
00394                 gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
00395                 cod_info->block_type = blocktype[ch];
00396                 cod_info->mixed_block_flag = 0;
00397             }
00398         }
00399     }
00400     else {
00401         /*no psy model */
00402         memset((char *) masking_LR, 0, sizeof(masking_LR));
00403         memset((char *) masking_MS, 0, sizeof(masking_MS));
00404         for (gr = 0; gr < gfc->mode_gr; gr++)
00405             for (ch = 0; ch < gfc->channels_out; ch++) {
00406                 gfc->l3_side.tt[gr][ch].block_type = NORM_TYPE;
00407                 gfc->l3_side.tt[gr][ch].mixed_block_flag = 0;
00408                 pe_MS[gr][ch] = pe[gr][ch] = 700;
00409             }
00410     }
00411 
00412 
00413 
00414     /* auto-adjust of ATH, useful for low volume */
00415     adjust_ATH(gfc);
00416 
00417 
00418     /****************************************
00419     *   Stage 2: MDCT                       *
00420     ****************************************/
00421 
00422     /* polyphase filtering / mdct */
00423     mdct_sub48(gfc, inbuf[0], inbuf[1]);
00424 
00425 
00426     /****************************************
00427     *   Stage 3: MS/LR decision             *
00428     ****************************************/
00429 
00430     /* Here will be selected MS or LR coding of the 2 stereo channels */
00431     gfc->mode_ext = MPG_MD_LR_LR;
00432 
00433     if (gfp->force_ms) {
00434         gfc->mode_ext = MPG_MD_MS_LR;
00435     }
00436     else if (gfp->mode == JOINT_STEREO) {
00437         int     check_ms_stereo = 1;
00438         /* ms_ratio = is scaled, for historical reasons, to look like
00439            a ratio of side_channel / total.
00440            0 = signal is 100% mono
00441            .5 = L & R uncorrelated
00442          */
00443 
00444         /* [0] and [1] are the results for the two granules in MPEG-1,
00445          * in MPEG-2 it's only a faked averaging of the same value
00446          * _prev is the value of the last granule of the previous frame
00447          * _next is the value of the first granule of the next frame
00448          */
00449         if (gfp->psymodel == PSY_GPSYCHO) {
00450             FLOAT   ms_ratio_ave1;
00451             FLOAT   ms_ratio_ave2;
00452             FLOAT const threshold1 = 0.35;
00453             FLOAT const threshold2 = 0.45;
00454 
00455             /* take an average */
00456             if (gfc->mode_gr == 1) {
00457                 /* MPEG2 - no second granule */
00458                 ms_ratio_ave1 = 0.33 * (gfc->ms_ratio[0] + ms_ratio_prev + ms_ratio_next);
00459                 ms_ratio_ave2 = gfc->ms_ratio[0];
00460             }
00461             else {
00462                 ms_ratio_ave1 =
00463                     0.25 * (gfc->ms_ratio[0] + gfc->ms_ratio[1] + ms_ratio_prev + ms_ratio_next);
00464                 ms_ratio_ave2 = 0.50 * (gfc->ms_ratio[0] + gfc->ms_ratio[1]);
00465             }
00466 
00467 
00468             if (ms_ratio_ave1 >= threshold1 || ms_ratio_ave2 >= threshold2)
00469                 check_ms_stereo = 0;
00470         }
00471 
00472         if (check_ms_stereo) {
00473             FLOAT   sum_pe_MS = 0;
00474             FLOAT   sum_pe_LR = 0;
00475             for (gr = 0; gr < gfc->mode_gr; gr++) {
00476                 for (ch = 0; ch < gfc->channels_out; ch++) {
00477                     sum_pe_MS += pe_MS[gr][ch];
00478                     sum_pe_LR += pe[gr][ch];
00479                 }
00480             }
00481 
00482             /* based on PE: M/S coding would not use much more bits than L/R */
00483             if (((gfp->psymodel == PSY_GPSYCHO) && sum_pe_MS <= 1.07 * sum_pe_LR) ||
00484                 ((gfp->psymodel == PSY_NSPSYTUNE) && sum_pe_MS <= 1.00 * sum_pe_LR)) {
00485 
00486                 gr_info const *const gi0 = &gfc->l3_side.tt[0][0];
00487                 gr_info const *const gi1 = &gfc->l3_side.tt[gfc->mode_gr - 1][0];
00488 
00489                 if (gi0[0].block_type == gi0[1].block_type &&
00490                     gi1[0].block_type == gi1[1].block_type) {
00491 
00492                     gfc->mode_ext = MPG_MD_MS_LR;
00493                 }
00494             }
00495         }
00496     }
00497 
00498     /* bit and noise allocation */
00499     if (gfc->mode_ext == MPG_MD_MS_LR) {
00500         masking = &masking_MS; /* use MS masking */
00501         pe_use = &pe_MS;
00502     }
00503     else {
00504         masking = &masking_LR; /* use LR masking */
00505         pe_use = &pe;
00506     }
00507 
00508 
00509     /* copy data for MP3 frame analyzer */
00510     if (gfp->analysis && gfc->pinfo != NULL) {
00511         for (gr = 0; gr < gfc->mode_gr; gr++) {
00512             for (ch = 0; ch < gfc->channels_out; ch++) {
00513                 gfc->pinfo->ms_ratio[gr] = gfc->ms_ratio[gr];
00514                 gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr];
00515                 gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type;
00516                 gfc->pinfo->pe[gr][ch] = (*pe_use)[gr][ch];
00517                 memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr, sizeof(FLOAT) * 576);
00518                 /* in psymodel, LR and MS data was stored in pinfo.  
00519                    switch to MS data: */
00520                 if (gfc->mode_ext == MPG_MD_MS_LR) {
00521                     gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2];
00522                     memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2],
00523                            sizeof(gfc->pinfo->energy[gr][ch]));
00524                 }
00525             }
00526         }
00527     }
00528 
00529 
00530     /****************************************
00531     *   Stage 4: quantization loop          *
00532     ****************************************/
00533 
00534     if (gfp->psymodel == PSY_NSPSYTUNE) {
00535         if (gfp->VBR == vbr_off || gfp->VBR == vbr_abr) {
00536             static FLOAT const fircoef[9] = {
00537                 -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5,
00538                 7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5,
00539                 0.187098 * 5
00540             };
00541 
00542             int     i;
00543             FLOAT   f;
00544 
00545             for (i = 0; i < 18; i++)
00546                 gfc->nsPsy.pefirbuf[i] = gfc->nsPsy.pefirbuf[i + 1];
00547 
00548             f = 0.0;
00549             for (gr = 0; gr < gfc->mode_gr; gr++)
00550                 for (ch = 0; ch < gfc->channels_out; ch++)
00551                     f += (*pe_use)[gr][ch];
00552             gfc->nsPsy.pefirbuf[18] = f;
00553 
00554             f = gfc->nsPsy.pefirbuf[9];
00555             for (i = 0; i < 9; i++)
00556                 f += (gfc->nsPsy.pefirbuf[i] + gfc->nsPsy.pefirbuf[18 - i]) * fircoef[i];
00557 
00558             f = (670 * 5 * gfc->mode_gr * gfc->channels_out) / f;
00559             for (gr = 0; gr < gfc->mode_gr; gr++) {
00560                 for (ch = 0; ch < gfc->channels_out; ch++) {
00561                     (*pe_use)[gr][ch] *= f;
00562                 }
00563             }
00564         }
00565     }
00566     gfc->iteration_loop(gfp, *pe_use, ms_ener_ratio, *masking);
00567 
00568 
00569     /****************************************
00570     *   Stage 5: bitstream formatting       *
00571     ****************************************/
00572 
00573 
00574     /*  write the frame to the bitstream  */
00575     (void) format_bitstream(gfp);
00576 
00577     /* copy mp3 bit buffer into array */
00578     mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1);
00579 
00580 
00581     if (gfp->bWriteVbrTag)
00582         AddVbrFrame(gfp);
00583 
00584 
00585     if (gfp->analysis && gfc->pinfo != NULL) {
00586         for (ch = 0; ch < gfc->channels_out; ch++) {
00587             int     j;
00588             for (j = 0; j < FFTOFFSET; j++)
00589                 gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + gfp->framesize];
00590             for (j = FFTOFFSET; j < 1600; j++) {
00591                 gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];
00592             }
00593         }
00594         set_frame_pinfo(gfp, *masking);
00595     }
00596 
00597     updateStats(gfc);
00598 
00599     return mp3count;
00600 }

Generated on Sun Dec 2 11:34:18 2007 for LAME by  doxygen 1.5.2