⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encoder.c

📁 音频编码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	LAME MP3 encoding engine * *	Copyright (c) 1999 Mark Taylor *	Copyright (c) 2000-2002 Takehiro Tominaga *	Copyright (c) 2000-2005 Robert Hegemann *	Copyright (c) 2001 Gabriel Bouvigne *	Copyright (c) 2001 John Dahlstrom * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. *//* $Id: encoder.c,v 1.90.2.1 2005/11/20 14:08:24 bouvigne Exp $ */#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <assert.h>#include "lame.h"#include "util.h"#include "newmdct.h"#include "psymodel.h"#include "quantize.h"#include "quantize_pvt.h"#include "bitstream.h"#include "VbrTag.h"#include "vbrquantize.h"#ifdef WITH_DMALLOC#include <dmalloc.h>#endif/* * auto-adjust of ATH, useful for low volume * Gabriel Bouvigne 3 feb 2001 * * modifies some values in *   gfp->internal_flags->ATH *   (gfc->ATH) */static voidadjust_ATH(lame_internal_flags * const gfc){    FLOAT   gr2_max, max_pow;    if (gfc->ATH->use_adjust == 0) {        gfc->ATH->adjust = 1.0; /* no adjustment */        return;    }    /* jd - 2001 mar 12, 27, jun 30 */    /* loudness based on equal loudness curve; */    /* use granule with maximum combined loudness */    max_pow = gfc->loudness_sq[0][0];    gr2_max = gfc->loudness_sq[1][0];    if (gfc->channels_out == 2) {        max_pow += gfc->loudness_sq[0][1];        gr2_max += gfc->loudness_sq[1][1];    }    else {        max_pow += max_pow;        gr2_max += gr2_max;    }    if (gfc->mode_gr == 2) {        max_pow = Max(max_pow, gr2_max);    }    max_pow *= 0.5; /* max_pow approaches 1.0 for full band noise */    /* jd - 2001 mar 31, jun 30 */    /* user tuning of ATH adjustment region */    max_pow *= gfc->ATH->aa_sensitivity_p;    /*  adjust ATH depending on range of maximum value     */    /* jd - 2001 feb27, mar12,20, jun30, jul22 */    /* continuous curves based on approximation */    /* to GB's original values. */    /* For an increase in approximate loudness, */    /* set ATH adjust to adjust_limit immediately */    /* after a delay of one frame. */    /* For a loudness decrease, reduce ATH adjust */    /* towards adjust_limit gradually. */    /* max_pow is a loudness squared or a power. */    if (max_pow > 0.03125) { /* ((1 - 0.000625)/ 31.98) from curve below */        if (gfc->ATH->adjust >= 1.0) {            gfc->ATH->adjust = 1.0;        }        else {            /* preceding frame has lower ATH adjust; */            /* ascend only to the preceding adjust_limit */            /* in case there is leading low volume */            if (gfc->ATH->adjust < gfc->ATH->adjust_limit) {                gfc->ATH->adjust = gfc->ATH->adjust_limit;            }        }        gfc->ATH->adjust_limit = 1.0;    }    else {      /* adjustment curve */        /* about 32 dB maximum adjust (0.000625) */        FLOAT adj_lim_new = 31.98 * max_pow + 0.000625;        if (gfc->ATH->adjust >= adj_lim_new) { /* descend gradually */            gfc->ATH->adjust *= adj_lim_new * 0.075 + 0.925;            if (gfc->ATH->adjust < adj_lim_new) { /* stop descent */                gfc->ATH->adjust = adj_lim_new;            }        }        else {  /* ascend */            if (gfc->ATH->adjust_limit >= adj_lim_new) {                gfc->ATH->adjust = adj_lim_new;            }            else { /* preceding frame has lower ATH adjust; */                /* ascend only to the preceding adjust_limit */                if (gfc->ATH->adjust < gfc->ATH->adjust_limit) {                    gfc->ATH->adjust = gfc->ATH->adjust_limit;                }            }        }        gfc->ATH->adjust_limit = adj_lim_new;    }}/*********************************************************************** * *  some simple statistics * *  bitrate index 0: free bitrate -> not allowed in VBR mode *  : bitrates, kbps depending on MPEG version *  bitrate index 15: forbidden * *  mode_ext: *  0:  LR *  1:  LR-i *  2:  MS *  3:  MS-i * ***********************************************************************/static voidupdateStats(lame_internal_flags * const gfc){    int     gr, ch;    assert(gfc->bitrate_index < 16u);    assert(gfc->mode_ext < 4u);    /* count bitrate indices */    gfc->bitrate_stereoMode_Hist[gfc->bitrate_index][4]++;    gfc->bitrate_stereoMode_Hist[15][4]++;    /* count 'em for every mode extension in case of 2 channel encoding */    if (gfc->channels_out == 2) {        gfc->bitrate_stereoMode_Hist[gfc->bitrate_index][gfc->mode_ext]++;        gfc->bitrate_stereoMode_Hist[15][gfc->mode_ext]++;    }    for (gr = 0; gr < gfc->mode_gr; ++gr) {        for (ch = 0; ch < gfc->channels_out; ++ch) {            int     bt = gfc->l3_side.tt[gr][ch].block_type;            int     mf = gfc->l3_side.tt[gr][ch].mixed_block_flag;            if (mf)                bt = 4;            gfc->bitrate_blockType_Hist[gfc->bitrate_index][bt]++;            gfc->bitrate_blockType_Hist[gfc->bitrate_index][5]++;            gfc->bitrate_blockType_Hist[15][bt]++;            gfc->bitrate_blockType_Hist[15][5]++;        }    }}static voidlame_encode_frame_init(lame_global_flags * const gfp, const sample_t * inbuf[2]){    lame_internal_flags *gfc = gfp->internal_flags;    int     ch, gr;    if (gfc->lame_encode_frame_init == 0) {        /* prime the MDCT/polyphase filterbank with a short block */        int     i, j;        sample_t primebuff0[286 + 1152 + 576];        sample_t primebuff1[286 + 1152 + 576];        gfc->lame_encode_frame_init = 1;        for (i = 0, j = 0; i < 286 + 576 * (1 + gfc->mode_gr); ++i) {            if (i < 576 * gfc->mode_gr) {                primebuff0[i] = 0;                if (gfc->channels_out == 2)                    primebuff1[i] = 0;            }            else {                primebuff0[i] = inbuf[0][j];                if (gfc->channels_out == 2)                    primebuff1[i] = inbuf[1][j];                ++j;            }        }        /* polyphase filtering / mdct */        for (gr = 0; gr < gfc->mode_gr; gr++) {            for (ch = 0; ch < gfc->channels_out; ch++) {                gfc->l3_side.tt[gr][ch].block_type = SHORT_TYPE;            }        }        mdct_sub48(gfc, primebuff0, primebuff1);        /* check FFT will not use a negative starting offset */#if 576 < FFTOFFSET# error FFTOFFSET greater than 576: FFT uses a negative offset#endif        /* check if we have enough data for FFT */        assert(gfc->mf_size >= (BLKSIZE + gfp->framesize - FFTOFFSET));        /* check if we have enough data for polyphase filterbank */        assert(gfc->mf_size >= (512 + gfp->framesize - 32));    }}/************************************************************************** encodeframe()           Layer 3** encode a single frame*************************************************************************lame_encode_frame()                       gr 0            gr 1inbuf:           |--------------|--------------|--------------|Polyphase (18 windows, each shifted 32)gr 0:window1          <----512---->window18                 <----512---->gr 1:window1                         <----512---->window18                                <----512---->MDCT output:  |--------------|--------------|--------------|FFT's                    <---------1024---------->                                         <---------1024-------->    inbuf = buffer of PCM data size=MP3 framesize    encoder acts on inbuf[ch][0], but output is delayed by MDCTDELAY    so the MDCT coefficints are from inbuf[ch][-MDCTDELAY]    psy-model FFT has a 1 granule delay, so we feed it data for the     next granule.    FFT is centered over granule:  224+576+224    So FFT starts at:   576-224-MDCTDELAY    MPEG2:  FFT ends at:  BLKSIZE+576-224-MDCTDELAY      (1328)    MPEG1:  FFT ends at:  BLKSIZE+2*576-224-MDCTDELAY    (1904)    MPEG2:  polyphase first window:  [0..511]                      18th window:   [544..1055]          (1056)    MPEG1:            36th window:   [1120..1631]         (1632)            data needed:  512+framesize-32    A close look newmdct.c shows that the polyphase filterbank    only uses data from [0..510] for each window.  Perhaps because the window    used by the filterbank is zero for the last point, so Takehiro's    code doesn't bother to compute with it.    FFT starts at 576-224-MDCTDELAY (304)  = 576-FFTOFFSET*/typedef FLOAT chgrdata[2][2];intlame_encode_mp3_frame(       /* Output */                         lame_global_flags * const gfp, /* Context */                         sample_t * inbuf_l, /* Input */                         sample_t * inbuf_r, /* Input */                         unsigned char *mp3buf, /* Output */                         int mp3buf_size){                       /* Output */    int     mp3count;    III_psy_ratio masking_LR[2][2]; /*LR masking & energy */    III_psy_ratio masking_MS[2][2]; /*MS masking & energy */    III_psy_ratio(*masking)[2][2]; /*pointer to selected maskings */    const sample_t *inbuf[2];

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -