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

📄 encoder.c

📁 音频编码
💻 C
📖 第 1 页 / 共 2 页
字号:
    lame_internal_flags *gfc = gfp->internal_flags;    FLOAT   tot_ener[2][4];    FLOAT   ms_ener_ratio[2] = { .5, .5 };    chgrdata pe, pe_MS;    chgrdata *pe_use;    int     ch, gr;    FLOAT   ms_ratio_next = 0.;    FLOAT   ms_ratio_prev = 0.;    inbuf[0] = inbuf_l;    inbuf[1] = inbuf_r;    if (gfc->lame_encode_frame_init == 0) {        /*first run? */        lame_encode_frame_init(gfp, inbuf);    }    /********************** padding *****************************/    /* padding method as described in      * "MPEG-Layer3 / Bitstream Syntax and Decoding"     * by Martin Sieler, Ralph Sperschneider     *     * note: there is no padding for the very first frame     *     * Robert Hegemann 2000-06-22     */    gfc->padding = FALSE;    if ((gfc->slot_lag -= gfc->frac_SpF) < 0) {        gfc->slot_lag += gfp->out_samplerate;        gfc->padding = TRUE;    }    /****************************************    *   Stage 1: psychoacoustic model       *    ****************************************/    if (gfc->psymodel) {        /* psychoacoustic model         * psy model has a 1 granule (576) delay that we must compensate for         * (mt 6/99).         */        int     ret;        const sample_t *bufp[2]; /* address of beginning of left & right granule */        int     blocktype[2];        ms_ratio_prev = gfc->ms_ratio[gfc->mode_gr - 1];        for (gr = 0; gr < gfc->mode_gr; gr++) {            for (ch = 0; ch < gfc->channels_out; ch++)                bufp[ch] = &inbuf[ch][576 + gr * 576 - FFTOFFSET];            if (gfp->psymodel == PSY_NSPSYTUNE) {                ret = L3psycho_anal_ns(gfp, bufp, gr,                                       &gfc->ms_ratio[gr], &ms_ratio_next,                                       masking_LR, masking_MS,                                       pe[gr], pe_MS[gr], tot_ener[gr], blocktype);            }            else {                ret = L3psycho_anal(gfp, bufp, gr,                                    &gfc->ms_ratio[gr], &ms_ratio_next,                                    masking_LR, masking_MS,                                    pe[gr], pe_MS[gr], tot_ener[gr], blocktype);            }            if (ret != 0)                return -4;            if (gfp->mode == JOINT_STEREO) {                ms_ener_ratio[gr] = tot_ener[gr][2] + tot_ener[gr][3];                if (ms_ener_ratio[gr] > 0)                    ms_ener_ratio[gr] = tot_ener[gr][3] / ms_ener_ratio[gr];            }            /* block type flags */            for (ch = 0; ch < gfc->channels_out; ch++) {                gr_info *cod_info = &gfc->l3_side.tt[gr][ch];                cod_info->block_type = blocktype[ch];                cod_info->mixed_block_flag = 0;            }        }    }    else {        /*no psy model */        memset((char *) masking_LR, 0, sizeof(masking_LR));        memset((char *) masking_MS, 0, sizeof(masking_MS));        for (gr = 0; gr < gfc->mode_gr; gr++)            for (ch = 0; ch < gfc->channels_out; ch++) {                gfc->l3_side.tt[gr][ch].block_type = NORM_TYPE;                gfc->l3_side.tt[gr][ch].mixed_block_flag = 0;                pe_MS[gr][ch] = pe[gr][ch] = 700;            }    }    /* auto-adjust of ATH, useful for low volume */    adjust_ATH(gfc);    /****************************************    *   Stage 2: MDCT                       *    ****************************************/    /* polyphase filtering / mdct */    mdct_sub48(gfc, inbuf[0], inbuf[1]);    /****************************************    *   Stage 3: MS/LR decision             *    ****************************************/    /* Here will be selected MS or LR coding of the 2 stereo channels */    gfc->mode_ext = MPG_MD_LR_LR;    if (gfp->force_ms) {        gfc->mode_ext = MPG_MD_MS_LR;    }    else if (gfp->mode == JOINT_STEREO) {        int     check_ms_stereo = 1;        /* ms_ratio = is scaled, for historical reasons, to look like           a ratio of side_channel / total.           0 = signal is 100% mono           .5 = L & R uncorrelated         */        /* [0] and [1] are the results for the two granules in MPEG-1,         * in MPEG-2 it's only a faked averaging of the same value         * _prev is the value of the last granule of the previous frame         * _next is the value of the first granule of the next frame         */        if (gfp->psymodel == PSY_GPSYCHO) {            FLOAT   ms_ratio_ave1;            FLOAT   ms_ratio_ave2;            FLOAT   threshold1 = 0.35;            FLOAT   threshold2 = 0.45;            /* take an average */            if (gfc->mode_gr == 1) {                /* MPEG2 - no second granule */                ms_ratio_ave1 = 0.33 * (gfc->ms_ratio[0] + ms_ratio_prev + ms_ratio_next);                ms_ratio_ave2 = gfc->ms_ratio[0];            }            else {                ms_ratio_ave1 =                    0.25 * (gfc->ms_ratio[0] + gfc->ms_ratio[1] + ms_ratio_prev + ms_ratio_next);                ms_ratio_ave2 = 0.50 * (gfc->ms_ratio[0] + gfc->ms_ratio[1]);            }            if (ms_ratio_ave1 >= threshold1 || ms_ratio_ave2 >= threshold2)                check_ms_stereo = 0;        }        if (check_ms_stereo) {            FLOAT   sum_pe_MS = 0;            FLOAT   sum_pe_LR = 0;            for (gr = 0; gr < gfc->mode_gr; gr++) {                for (ch = 0; ch < gfc->channels_out; ch++) {                    sum_pe_MS += pe_MS[gr][ch];                    sum_pe_LR += pe[gr][ch];                }            }            /* based on PE: M/S coding would not use much more bits than L/R */            if (((gfp->psymodel == PSY_GPSYCHO) && sum_pe_MS <= 1.07 * sum_pe_LR) ||                ((gfp->psymodel == PSY_NSPSYTUNE) && sum_pe_MS <= 1.00 * sum_pe_LR)) {                gr_info *gi0 = &gfc->l3_side.tt[0][0];                gr_info *gi1 = &gfc->l3_side.tt[gfc->mode_gr - 1][0];                if (gi0[0].block_type == gi0[1].block_type &&                    gi1[0].block_type == gi1[1].block_type) {                    gfc->mode_ext = MPG_MD_MS_LR;                }            }        }    }    /* bit and noise allocation */    if (gfc->mode_ext == MPG_MD_MS_LR) {        masking = &masking_MS; /* use MS masking */        pe_use = &pe_MS;    }    else {        masking = &masking_LR; /* use LR masking */        pe_use = &pe;    }#if defined(HAVE_GTK)    /* copy data for MP3 frame analyzer */    if (gfp->analysis && gfc->pinfo != NULL) {        for (gr = 0; gr < gfc->mode_gr; gr++) {            for (ch = 0; ch < gfc->channels_out; ch++) {                gfc->pinfo->ms_ratio[gr] = gfc->ms_ratio[gr];                gfc->pinfo->ms_ener_ratio[gr] = ms_ener_ratio[gr];                gfc->pinfo->blocktype[gr][ch] = gfc->l3_side.tt[gr][ch].block_type;                gfc->pinfo->pe[gr][ch] = (*pe_use)[gr][ch];                memcpy(gfc->pinfo->xr[gr][ch], &gfc->l3_side.tt[gr][ch].xr, sizeof(FLOAT) * 576);                /* in psymodel, LR and MS data was stored in pinfo.                     switch to MS data: */                if (gfc->mode_ext == MPG_MD_MS_LR) {                    gfc->pinfo->ers[gr][ch] = gfc->pinfo->ers[gr][ch + 2];                    memcpy(gfc->pinfo->energy[gr][ch], gfc->pinfo->energy[gr][ch + 2],                           sizeof(gfc->pinfo->energy[gr][ch]));                }            }        }    }#endif    /****************************************    *   Stage 4: quantization loop          *    ****************************************/    if (gfp->psymodel == PSY_NSPSYTUNE) {        if (gfp->VBR == vbr_off || gfp->VBR == vbr_abr) {            static FLOAT fircoef[9] = {                -0.0207887 * 5, -0.0378413 * 5, -0.0432472 * 5, -0.031183 * 5,                7.79609e-18 * 5, 0.0467745 * 5, 0.10091 * 5, 0.151365 * 5,                0.187098 * 5            };            int     i;            FLOAT   f;            for (i = 0; i < 18; i++)                gfc->nsPsy.pefirbuf[i] = gfc->nsPsy.pefirbuf[i + 1];            f = 0.0;            for (gr = 0; gr < gfc->mode_gr; gr++)                for (ch = 0; ch < gfc->channels_out; ch++)                    f += (*pe_use)[gr][ch];            gfc->nsPsy.pefirbuf[18] = f;            f = gfc->nsPsy.pefirbuf[9];            for (i = 0; i < 9; i++)                f += (gfc->nsPsy.pefirbuf[i] + gfc->nsPsy.pefirbuf[18 - i]) * fircoef[i];            f = (670 * 5 * gfc->mode_gr * gfc->channels_out) / f;            for (gr = 0; gr < gfc->mode_gr; gr++) {                for (ch = 0; ch < gfc->channels_out; ch++) {                    (*pe_use)[gr][ch] *= f;                }            }        }    }    switch (gfp->VBR) {    default:    case vbr_off:        CBR_iteration_loop(gfp, *pe_use, ms_ener_ratio, *masking);        break;    case vbr_mt:    case vbr_rh:    case vbr_mtrh:        VBR_iteration_loop(gfp, *pe_use, ms_ener_ratio, *masking);        break;    case vbr_abr:        ABR_iteration_loop(gfp, *pe_use, ms_ener_ratio, *masking);        break;    }    /****************************************    *   Stage 5: bitstream formatting       *    ****************************************/    /*  write the frame to the bitstream  */    format_bitstream(gfp);    /* copy mp3 bit buffer into array */    mp3count = copy_buffer(gfc, mp3buf, mp3buf_size, 1);    if (gfp->bWriteVbrTag)        AddVbrFrame(gfp);#if defined(HAVE_GTK)    if (gfp->analysis && gfc->pinfo != NULL) {        for (ch = 0; ch < gfc->channels_out; ch++) {            int     j;            for (j = 0; j < FFTOFFSET; j++)                gfc->pinfo->pcmdata[ch][j] = gfc->pinfo->pcmdata[ch][j + gfp->framesize];            for (j = FFTOFFSET; j < 1600; j++) {                gfc->pinfo->pcmdata[ch][j] = inbuf[ch][j - FFTOFFSET];            }        }        set_frame_pinfo(gfp, *masking);    }#endif#ifdef BRHIST    updateStats(gfc);#endif    return mp3count;}

⌨️ 快捷键说明

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