Blame libmp3lame/encoder.c

Packit 47f805
/*
Packit 47f805
 *      LAME MP3 encoding engine
Packit 47f805
 *
Packit 47f805
 *      Copyright (c) 1999 Mark Taylor
Packit 47f805
 *      Copyright (c) 2000-2002 Takehiro Tominaga
Packit 47f805
 *      Copyright (c) 2000-2011 Robert Hegemann
Packit 47f805
 *      Copyright (c) 2001 Gabriel Bouvigne
Packit 47f805
 *      Copyright (c) 2001 John Dahlstrom
Packit 47f805
 *
Packit 47f805
 * This library is free software; you can redistribute it and/or
Packit 47f805
 * modify it under the terms of the GNU Library General Public
Packit 47f805
 * License as published by the Free Software Foundation; either
Packit 47f805
 * version 2 of the License, or (at your option) any later version.
Packit 47f805
 *
Packit 47f805
 * This library is distributed in the hope that it will be useful,
Packit 47f805
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 47f805
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 47f805
 * Library General Public License for more details.
Packit 47f805
 *
Packit 47f805
 * You should have received a copy of the GNU Library General Public
Packit 47f805
 * License along with this library; if not, write to the
Packit 47f805
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 47f805
 * Boston, MA 02111-1307, USA.
Packit 47f805
 */
Packit 47f805
Packit 47f805
/* $Id: encoder.c,v 1.114 2017/08/26 10:54:57 robert Exp $ */
Packit 47f805
Packit 47f805
#ifdef HAVE_CONFIG_H
Packit 47f805
#include <config.h>
Packit 47f805
#endif
Packit 47f805
Packit 47f805
Packit 47f805
#include "lame.h"
Packit 47f805
#include "machine.h"
Packit 47f805
#include "encoder.h"
Packit 47f805
#include "util.h"
Packit 47f805
#include "lame_global_flags.h"
Packit 47f805
#include "newmdct.h"
Packit 47f805
#include "psymodel.h"
Packit 47f805
#include "lame-analysis.h"
Packit 47f805
#include "bitstream.h"
Packit 47f805
#include "VbrTag.h"
Packit 47f805
#include "quantize.h"
Packit 47f805
#include "quantize_pvt.h"
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/*
Packit 47f805
 * auto-adjust of ATH, useful for low volume
Packit 47f805
 * Gabriel Bouvigne 3 feb 2001
Packit 47f805
 *
Packit 47f805
 * modifies some values in
Packit 47f805
 *   gfp->internal_flags->ATH
Packit 47f805
 *   (gfc->ATH)
Packit 47f805
 */
Packit 47f805
static void
Packit 47f805
adjust_ATH(lame_internal_flags const *const gfc)
Packit 47f805
{
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    FLOAT   gr2_max, max_pow;
Packit 47f805
Packit 47f805
    if (gfc->ATH->use_adjust == 0) {
Packit 47f805
        gfc->ATH->adjust_factor = 1.0; /* no adjustment */
Packit 47f805
        return;
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* jd - 2001 mar 12, 27, jun 30 */
Packit 47f805
    /* loudness based on equal loudness curve; */
Packit 47f805
    /* use granule with maximum combined loudness */
Packit 47f805
    max_pow = gfc->ov_psy.loudness_sq[0][0];
Packit 47f805
    gr2_max = gfc->ov_psy.loudness_sq[1][0];
Packit 47f805
    if (cfg->channels_out == 2) {
Packit 47f805
        max_pow += gfc->ov_psy.loudness_sq[0][1];
Packit 47f805
        gr2_max += gfc->ov_psy.loudness_sq[1][1];
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        max_pow += max_pow;
Packit 47f805
        gr2_max += gr2_max;
Packit 47f805
    }
Packit 47f805
    if (cfg->mode_gr == 2) {
Packit 47f805
        max_pow = Max(max_pow, gr2_max);
Packit 47f805
    }
Packit 47f805
    max_pow *= 0.5;     /* max_pow approaches 1.0 for full band noise */
Packit 47f805
Packit 47f805
    /* jd - 2001 mar 31, jun 30 */
Packit 47f805
    /* user tuning of ATH adjustment region */
Packit 47f805
    max_pow *= gfc->ATH->aa_sensitivity_p;
Packit 47f805
Packit 47f805
    /*  adjust ATH depending on range of maximum value
Packit 47f805
     */
Packit 47f805
Packit 47f805
    /* jd - 2001 feb27, mar12,20, jun30, jul22 */
Packit 47f805
    /* continuous curves based on approximation */
Packit 47f805
    /* to GB's original values. */
Packit 47f805
    /* For an increase in approximate loudness, */
Packit 47f805
    /* set ATH adjust to adjust_limit immediately */
Packit 47f805
    /* after a delay of one frame. */
Packit 47f805
    /* For a loudness decrease, reduce ATH adjust */
Packit 47f805
    /* towards adjust_limit gradually. */
Packit 47f805
    /* max_pow is a loudness squared or a power. */
Packit 47f805
    if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */
Packit 47f805
        if (gfc->ATH->adjust_factor >= 1.0) {
Packit 47f805
            gfc->ATH->adjust_factor = 1.0;
Packit 47f805
        }
Packit 47f805
        else {
Packit 47f805
            /* preceding frame has lower ATH adjust; */
Packit 47f805
            /* ascend only to the preceding adjust_limit */
Packit 47f805
            /* in case there is leading low volume */
Packit 47f805
            if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) {
Packit 47f805
                gfc->ATH->adjust_factor = gfc->ATH->adjust_limit;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        gfc->ATH->adjust_limit = 1.0;
Packit 47f805
    }
Packit 47f805
    else {              /* adjustment curve */
Packit 47f805
        /* about 32 dB maximum adjust (0.000625) */
Packit 47f805
        FLOAT const adj_lim_new = 31.98 * max_pow + 0.000625;
Packit 47f805
        if (gfc->ATH->adjust_factor >= adj_lim_new) { /* descend gradually */
Packit 47f805
            gfc->ATH->adjust_factor *= adj_lim_new * 0.075 + 0.925;
Packit 47f805
            if (gfc->ATH->adjust_factor < adj_lim_new) { /* stop descent */
Packit 47f805
                gfc->ATH->adjust_factor = adj_lim_new;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        else {          /* ascend */
Packit 47f805
            if (gfc->ATH->adjust_limit >= adj_lim_new) {
Packit 47f805
                gfc->ATH->adjust_factor = adj_lim_new;
Packit 47f805
            }
Packit 47f805
            else {      /* preceding frame has lower ATH adjust; */
Packit 47f805
                /* ascend only to the preceding adjust_limit */
Packit 47f805
                if (gfc->ATH->adjust_factor < gfc->ATH->adjust_limit) {
Packit 47f805
                    gfc->ATH->adjust_factor = gfc->ATH->adjust_limit;
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        gfc->ATH->adjust_limit = adj_lim_new;
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
/***********************************************************************
Packit 47f805
 *
Packit 47f805
 *  some simple statistics
Packit 47f805
 *
Packit 47f805
 *  bitrate index 0: free bitrate -> not allowed in VBR mode
Packit 47f805
 *  : bitrates, kbps depending on MPEG version
Packit 47f805
 *  bitrate index 15: forbidden
Packit 47f805
 *
Packit 47f805
 *  mode_ext:
Packit 47f805
 *  0:  LR
Packit 47f805
 *  1:  LR-i
Packit 47f805
 *  2:  MS
Packit 47f805
 *  3:  MS-i
Packit 47f805
 *
Packit 47f805
 ***********************************************************************/
Packit 47f805
Packit 47f805
static void
Packit 47f805
updateStats(lame_internal_flags * const gfc)
Packit 47f805
{
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    EncResult_t *eov = &gfc->ov_enc;
Packit 47f805
    int     gr, ch;
Packit 47f805
    assert(0 <= eov->bitrate_index && eov->bitrate_index < 16);
Packit 47f805
    assert(0 <= eov->mode_ext && eov->mode_ext < 4);
Packit 47f805
Packit 47f805
    /* count bitrate indices */
Packit 47f805
    eov->bitrate_channelmode_hist[eov->bitrate_index][4]++;
Packit 47f805
    eov->bitrate_channelmode_hist[15][4]++;
Packit 47f805
Packit 47f805
    /* count 'em for every mode extension in case of 2 channel encoding */
Packit 47f805
    if (cfg->channels_out == 2) {
Packit 47f805
        eov->bitrate_channelmode_hist[eov->bitrate_index][eov->mode_ext]++;
Packit 47f805
        eov->bitrate_channelmode_hist[15][eov->mode_ext]++;
Packit 47f805
    }
Packit 47f805
    for (gr = 0; gr < cfg->mode_gr; ++gr) {
Packit 47f805
        for (ch = 0; ch < cfg->channels_out; ++ch) {
Packit 47f805
            int     bt = gfc->l3_side.tt[gr][ch].block_type;
Packit 47f805
            if (gfc->l3_side.tt[gr][ch].mixed_block_flag)
Packit 47f805
                bt = 4;
Packit 47f805
            eov->bitrate_blocktype_hist[eov->bitrate_index][bt]++;
Packit 47f805
            eov->bitrate_blocktype_hist[eov->bitrate_index][5]++;
Packit 47f805
            eov->bitrate_blocktype_hist[15][bt]++;
Packit 47f805
            eov->bitrate_blocktype_hist[15][5]++;
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
static void
Packit 47f805
lame_encode_frame_init(lame_internal_flags * gfc, const sample_t *const inbuf[2])
Packit 47f805
{
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
Packit 47f805
    int     ch, gr;
Packit 47f805
Packit 47f805
    if (gfc->lame_encode_frame_init == 0) {
Packit 47f805
        sample_t primebuff0[286 + 1152 + 576];
Packit 47f805
        sample_t primebuff1[286 + 1152 + 576];
Packit 47f805
        int const framesize = 576 * cfg->mode_gr;
Packit 47f805
        /* prime the MDCT/polyphase filterbank with a short block */
Packit 47f805
        int     i, j;
Packit 47f805
        gfc->lame_encode_frame_init = 1;
Packit 47f805
        memset(primebuff0, 0, sizeof(primebuff0));
Packit 47f805
        memset(primebuff1, 0, sizeof(primebuff1));
Packit 47f805
        for (i = 0, j = 0; i < 286 + 576 * (1 + cfg->mode_gr); ++i) {
Packit 47f805
            if (i < framesize) {
Packit 47f805
                primebuff0[i] = 0;
Packit 47f805
                if (cfg->channels_out == 2)
Packit 47f805
                    primebuff1[i] = 0;
Packit 47f805
            }
Packit 47f805
            else {
Packit 47f805
                primebuff0[i] = inbuf[0][j];
Packit 47f805
                if (cfg->channels_out == 2)
Packit 47f805
                    primebuff1[i] = inbuf[1][j];
Packit 47f805
                ++j;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        /* polyphase filtering / mdct */
Packit 47f805
        for (gr = 0; gr < cfg->mode_gr; gr++) {
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
                gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        mdct_sub48(gfc, primebuff0, primebuff1);
Packit 47f805
Packit 47f805
        /* check FFT will not use a negative starting offset */
Packit 47f805
#if 576 < FFTOFFSET
Packit 47f805
# error FFTOFFSET greater than 576: FFT uses a negative offset
Packit 47f805
#endif
Packit 47f805
        /* check if we have enough data for FFT */
Packit 47f805
        assert(gfc->sv_enc.mf_size >= (BLKSIZE + framesize - FFTOFFSET));
Packit 47f805
        /* check if we have enough data for polyphase filterbank */
Packit 47f805
        assert(gfc->sv_enc.mf_size >= (512 + framesize - 32));
Packit 47f805
    }
Packit 47f805
Packit 47f805
}
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
/************************************************************************
Packit 47f805
*
Packit 47f805
* encodeframe()           Layer 3
Packit 47f805
*
Packit 47f805
* encode a single frame
Packit 47f805
*
Packit 47f805
************************************************************************
Packit 47f805
lame_encode_frame()
Packit 47f805
Packit 47f805
Packit 47f805
                       gr 0            gr 1
Packit 47f805
inbuf:           |--------------|--------------|--------------|
Packit 47f805
Packit 47f805
Packit 47f805
Polyphase (18 windows, each shifted 32)
Packit 47f805
gr 0:
Packit 47f805
window1          <----512---->
Packit 47f805
window18                 <----512---->
Packit 47f805
Packit 47f805
gr 1:
Packit 47f805
window1                         <----512---->
Packit 47f805
window18                                <----512---->
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
MDCT output:  |--------------|--------------|--------------|
Packit 47f805
Packit 47f805
FFT's                    <---------1024---------->
Packit 47f805
                                         <---------1024-------->
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    inbuf = buffer of PCM data size=MP3 framesize
Packit 47f805
    encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY
Packit 47f805
    so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]
Packit 47f805
Packit 47f805
    psy-model FFT has a 1 granule delay, so we feed it data for the 
Packit 47f805
    next granule.
Packit 47f805
    FFT is centered over granule:  224+576+224
Packit 47f805
    So FFT starts at:   576-224-MDCTDELAY
Packit 47f805
Packit 47f805
    MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY      (1328)
Packit 47f805
    MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)
Packit 47f805
Packit 47f805
    MPEG2:  polyphase first window:  [0..511]
Packit 47f805
                      18th window:   [544..1055]          (1056)
Packit 47f805
    MPEG1:            36th window:   [1120..1631]         (1632)
Packit 47f805
            data needed:  512+framesize-32
Packit 47f805
Packit 47f805
    A close look newmdct.c shows that the polyphase filterbank
Packit 47f805
    only uses data from [0..510] for each window.  Perhaps because the window
Packit 47f805
    used by the filterbank is zero for the last point, so Takehiro's
Packit 47f805
    code doesn't bother to compute with it.
Packit 47f805
Packit 47f805
    FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET
Packit 47f805
Packit 47f805
*/
Packit 47f805
Packit 47f805
typedef FLOAT chgrdata[2][2];
Packit 47f805
Packit 47f805
Packit 47f805
int
Packit 47f805
lame_encode_mp3_frame(       /* Output */
Packit 47f805
                         lame_internal_flags * gfc, /* Context */
Packit 47f805
                         sample_t const *inbuf_l, /* Input */
Packit 47f805
                         sample_t const *inbuf_r, /* Input */
Packit 47f805
                         unsigned char *mp3buf, /* Output */
Packit 47f805
                         int mp3buf_size)
Packit 47f805
{                       /* Output */
Packit 47f805
    SessionConfig_t const *const cfg = &gfc->cfg;
Packit 47f805
    int     mp3count;
Packit 47f805
    III_psy_ratio masking_LR[2][2]; /*LR masking & energy */
Packit 47f805
    III_psy_ratio masking_MS[2][2]; /*MS masking & energy */
Packit 47f805
    const III_psy_ratio (*masking)[2]; /*pointer to selected maskings */
Packit 47f805
    const sample_t *inbuf[2];
Packit 47f805
Packit 47f805
    FLOAT   tot_ener[2][4];
Packit 47f805
    FLOAT   ms_ener_ratio[2] = { .5, .5 };
Packit 47f805
    FLOAT   pe[2][2] = { {0., 0.}, {0., 0.} }, pe_MS[2][2] = { {
Packit 47f805
    0., 0.}, {
Packit 47f805
    0., 0.}};
Packit 47f805
    FLOAT (*pe_use)[2];
Packit 47f805
Packit 47f805
    int     ch, gr;
Packit 47f805
Packit 47f805
    inbuf[0] = inbuf_l;
Packit 47f805
    inbuf[1] = inbuf_r;
Packit 47f805
Packit 47f805
    if (gfc->lame_encode_frame_init == 0) {
Packit 47f805
        /*first run? */
Packit 47f805
        lame_encode_frame_init(gfc, inbuf);
Packit 47f805
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    /********************** padding *****************************/
Packit 47f805
    /* padding method as described in 
Packit 47f805
     * "MPEG-Layer3 / Bitstream Syntax and Decoding"
Packit 47f805
     * by Martin Sieler, Ralph Sperschneider
Packit 47f805
     *
Packit 47f805
     * note: there is no padding for the very first frame
Packit 47f805
     *
Packit 47f805
     * Robert Hegemann 2000-06-22
Packit 47f805
     */
Packit 47f805
    gfc->ov_enc.padding = FALSE;
Packit 47f805
    if ((gfc->sv_enc.slot_lag -= gfc->sv_enc.frac_SpF) < 0) {
Packit 47f805
        gfc->sv_enc.slot_lag += cfg->samplerate_out;
Packit 47f805
        gfc->ov_enc.padding = TRUE;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
Packit 47f805
    /****************************************
Packit 47f805
    *   Stage 1: psychoacoustic model       *
Packit 47f805
    ****************************************/
Packit 47f805
Packit 47f805
    {
Packit 47f805
        /* psychoacoustic model
Packit 47f805
         * psy model has a 1 granule (576) delay that we must compensate for
Packit 47f805
         * (mt 6/99).
Packit 47f805
         */
Packit 47f805
        int     ret;
Packit 47f805
        const sample_t *bufp[2] = {0, 0}; /* address of beginning of left & right granule */
Packit 47f805
        int     blocktype[2];
Packit 47f805
Packit 47f805
        for (gr = 0; gr < cfg->mode_gr; gr++) {
Packit 47f805
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
                bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET];
Packit 47f805
            }
Packit 47f805
            ret = L3psycho_anal_vbr(gfc, bufp, gr,
Packit 47f805
                                    masking_LR, masking_MS,
Packit 47f805
                                    pe[gr], pe_MS[gr], tot_ener[gr], blocktype);
Packit 47f805
            if (ret != 0)
Packit 47f805
                return -4;
Packit 47f805
Packit 47f805
            if (cfg->mode == JOINT_STEREO) {
Packit 47f805
                ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];
Packit 47f805
                if (ms_ener_ratio[gr] > 0)
Packit 47f805
                    ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];
Packit 47f805
            }
Packit 47f805
Packit 47f805
            /* block type flags */
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
                gr_info *const cod_info = &gfc->l3_side.tt[gr][ch];
Packit 47f805
                cod_info->block_type = blocktype[ch];
Packit 47f805
                cod_info->mixed_block_flag = 0;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    /* auto-adjust of ATH, useful for low volume */
Packit 47f805
    adjust_ATH(gfc);
Packit 47f805
Packit 47f805
Packit 47f805
    /****************************************
Packit 47f805
    *   Stage 2: MDCT                       *
Packit 47f805
    ****************************************/
Packit 47f805
Packit 47f805
    /* polyphase filtering / mdct */
Packit 47f805
    mdct_sub48(gfc, inbuf[0], inbuf[1]);
Packit 47f805
Packit 47f805
Packit 47f805
    /****************************************
Packit 47f805
    *   Stage 3: MS/LR decision             *
Packit 47f805
    ****************************************/
Packit 47f805
Packit 47f805
    /* Here will be selected MS or LR coding of the 2 stereo channels */
Packit 47f805
    gfc->ov_enc.mode_ext = MPG_MD_LR_LR;
Packit 47f805
Packit 47f805
    if (cfg->force_ms) {
Packit 47f805
        gfc->ov_enc.mode_ext = MPG_MD_MS_LR;
Packit 47f805
    }
Packit 47f805
    else if (cfg->mode == JOINT_STEREO) {
Packit 47f805
        /* ms_ratio = is scaled, for historical reasons, to look like
Packit 47f805
           a ratio of side_channel / total.
Packit 47f805
           0 = signal is 100% mono
Packit 47f805
           .5 = L & R uncorrelated
Packit 47f805
         */
Packit 47f805
Packit 47f805
        /* [0] and [1] are the results for the two granules in MPEG-1,
Packit 47f805
         * in MPEG-2 it's only a faked averaging of the same value
Packit 47f805
         * _prev is the value of the last granule of the previous frame
Packit 47f805
         * _next is the value of the first granule of the next frame
Packit 47f805
         */
Packit 47f805
Packit 47f805
        FLOAT   sum_pe_MS = 0;
Packit 47f805
        FLOAT   sum_pe_LR = 0;
Packit 47f805
        for (gr = 0; gr < cfg->mode_gr; gr++) {
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
                sum_pe_MS += pe_MS[gr][ch];
Packit 47f805
                sum_pe_LR += pe[gr][ch];
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
Packit 47f805
        /* based on PE: M/S coding would not use much more bits than L/R */
Packit 47f805
        if (sum_pe_MS <= 1.00 * sum_pe_LR) {
Packit 47f805
Packit 47f805
            gr_info const *const gi0 = &gfc->l3_side.tt[0][0];
Packit 47f805
            gr_info const *const gi1 = &gfc->l3_side.tt[cfg->mode_gr - 1][0];
Packit 47f805
Packit 47f805
            if (gi0[0].block_type == gi0[1].block_type && gi1[0].block_type == gi1[1].block_type) {
Packit 47f805
Packit 47f805
                gfc->ov_enc.mode_ext = MPG_MD_MS_LR;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
    /* bit and noise allocation */
Packit 47f805
    if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
Packit 47f805
        masking = (const III_psy_ratio (*)[2])masking_MS; /* use MS masking */
Packit 47f805
        pe_use = pe_MS;
Packit 47f805
    }
Packit 47f805
    else {
Packit 47f805
        masking = (const III_psy_ratio (*)[2])masking_LR; /* use LR masking */
Packit 47f805
        pe_use = pe;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    /* copy data for MP3 frame analyzer */
Packit 47f805
    if (cfg->analysis && gfc->pinfo != NULL) {
Packit 47f805
        for (gr = 0; gr < cfg->mode_gr; gr++) {
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
                gfc->pinfo->ms_ratio[gr] = 0;
Packit 47f805
                gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr];
Packit 47f805
                gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type;
Packit 47f805
                gfc->pinfo->pe[gr][ch] = pe_use[gr][ch];
Packit 47f805
                memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr[0], sizeof(FLOAT) * 576);
Packit 47f805
                /* in psymodel, LR and MS data was stored in pinfo.  
Packit 47f805
                   switch to MS data: */
Packit 47f805
                if (gfc->ov_enc.mode_ext == MPG_MD_MS_LR) {
Packit 47f805
                    gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2];
Packit 47f805
                    memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2],
Packit 47f805
                           sizeof(gfc->pinfo->energy[gr][ch]));
Packit 47f805
                }
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    /****************************************
Packit 47f805
    *   Stage 4: quantization loop          *
Packit 47f805
    ****************************************/
Packit 47f805
Packit 47f805
    if (cfg->vbr == vbr_off || cfg->vbr == vbr_abr) {
Packit 47f805
        static FLOAT const fircoef[9] = {
Packit 47f805
            -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5,
Packit 47f805
            7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5,
Packit 47f805
            0.187098 * 5
Packit 47f805
        };
Packit 47f805
Packit 47f805
        int     i;
Packit 47f805
        FLOAT   f;
Packit 47f805
Packit 47f805
        for (i = 0; i < 18; i++)
Packit 47f805
            gfc->sv_enc.pefirbuf[i] = gfc->sv_enc.pefirbuf[i + 1];
Packit 47f805
Packit 47f805
        f = 0.0;
Packit 47f805
        for (gr = 0; gr < cfg->mode_gr; gr++)
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++)
Packit 47f805
                f += pe_use[gr][ch];
Packit 47f805
        gfc->sv_enc.pefirbuf[18] = f;
Packit 47f805
Packit 47f805
        f = gfc->sv_enc.pefirbuf[9];
Packit 47f805
        for (i = 0; i < 9; i++)
Packit 47f805
            f += (gfc->sv_enc.pefirbuf[i] + gfc->sv_enc.pefirbuf[18 - i]) * fircoef[i];
Packit 47f805
Packit 47f805
        f = (670 * 5 * cfg->mode_gr * cfg->channels_out) / f;
Packit 47f805
        for (gr = 0; gr < cfg->mode_gr; gr++) {
Packit 47f805
            for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
                pe_use[gr][ch] *= f;
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
    }
Packit 47f805
    switch (cfg->vbr)
Packit 47f805
    {
Packit 47f805
    default:
Packit 47f805
    case vbr_off:
Packit 47f805
        CBR_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
Packit 47f805
        break;
Packit 47f805
    case vbr_abr:
Packit 47f805
        ABR_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
Packit 47f805
        break;
Packit 47f805
    case vbr_rh:
Packit 47f805
        VBR_old_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
Packit 47f805
        break;
Packit 47f805
    case vbr_mt:
Packit 47f805
    case vbr_mtrh:
Packit 47f805
        VBR_new_iteration_loop(gfc, (const FLOAT (*)[2])pe_use, ms_ener_ratio, masking);
Packit 47f805
        break;
Packit 47f805
    }
Packit 47f805
Packit 47f805
Packit 47f805
    /****************************************
Packit 47f805
    *   Stage 5: bitstream formatting       *
Packit 47f805
    ****************************************/
Packit 47f805
Packit 47f805
Packit 47f805
    /*  write the frame to the bitstream  */
Packit 47f805
    (void) format_bitstream(gfc);
Packit 47f805
Packit 47f805
    /* copy mp3 bit buffer into array */
Packit 47f805
    mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1);
Packit 47f805
Packit 47f805
Packit 47f805
    if (cfg->write_lame_tag) {
Packit 47f805
        AddVbrFrame(gfc);
Packit 47f805
    }
Packit 47f805
Packit 47f805
    if (cfg->analysis && gfc->pinfo != NULL) {
Packit 47f805
        int     framesize = 576 * cfg->mode_gr;
Packit 47f805
        for (ch = 0; ch < cfg->channels_out; ch++) {
Packit 47f805
            int     j;
Packit 47f805
            for (j = 0; j < FFTOFFSET; j++)
Packit 47f805
                gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + framesize];
Packit 47f805
            for (j = FFTOFFSET; j < 1600; j++) {
Packit 47f805
                gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];
Packit 47f805
            }
Packit 47f805
        }
Packit 47f805
        gfc->sv_qnt.masking_lower = 1.0;
Packit 47f805
Packit 47f805
        set_frame_pinfo(gfc, masking);
Packit 47f805
    }
Packit 47f805
Packit 47f805
    ++gfc->ov_enc.frame_number;
Packit 47f805
Packit 47f805
    updateStats(gfc);
Packit 47f805
Packit 47f805
    return mp3count;
Packit 47f805
}