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

📄 monopred.c

📁 网络MPEG4IP流媒体开发源代码
💻 C
字号:
/************************* MPEG-2 NBC Audio Decoder ************************** *                                                                           *"This software module was originally developed byBernd Edler and Hendrik Fuchs, University of Hannover in the course ofdevelopment of the MPEG-2 NBC/MPEG-4 Audio standard ISO/IEC 13818-7,14496-1,2 and 3. This software module is an implementation of a part of one or moreMPEG-2 NBC/MPEG-4 Audio tools as specified by the MPEG-2 NBC/MPEG-4Audio standard. ISO/IEC  gives users of the MPEG-2 NBC/MPEG-4 Audiostandards free license to this software module or modifications thereof for use inhardware or software products claiming conformance to the MPEG-2 NBC/MPEG-4Audio  standards. Those intending to use this software module in hardware orsoftware products are advised that this use may infringe existing patents.The original developer of this software module and his/her company, the subsequenteditors and their companies, and ISO/IEC have no liability for use of this softwaremodule or modifications thereof in an implementation. Copyright is not released fornon MPEG-2 NBC/MPEG-4 Audio conforming products.The original developerretains full right to use the code for his/her  own purpose, assign or donate thecode to a third party and to inhibit third party from using the code for nonMPEG-2 NBC/MPEG-4 Audio conforming products. This copyright notice mustbe included in all copies or derivative works."Copyright(c)1996. *                                                                           * ****************************************************************************//* * $Id$ *//*********************************************************************************** * MONOPRED                                    * *                                         * *  Contains the core functions for an intra channel (or mono) predictor       * *  using a backward adaptive lattice predictor.                   * *                                         * *  init_pred_stat():   initialisation of all predictor parameters     * *  monopred():     calculation of a predicted value from          * *              preceeding (quantised) samples             * *  predict():      carry out prediction for all spectral lines    * *  predict_reset():    carry out cyclic predictor reset mechanism     * *              (long blocks) resp. full reset (short blocks)      * *                                         * *  Internal Functions:                            * *    reset_pred_state():   reset the predictor state variables        * *                                         * **********************************************************************************/#include "all.h"#include "util.h"#define GRAD PRED_ORDER#define ALPHA PRED_ALPHA#define A PRED_A#define B PRED_B/* this works for all float values, * but does not conform to IEEE conventions of * round to nearest, even *//* Schuyler's bug fix */static void flt_round(float *pf){    int flg;    u_int32_t tmp;    float *pt = (float *)&tmp;    *pt = *pf;    flg = tmp & (u_int32_t)0x00008000;    tmp &= (u_int32_t)0xffff0000;    *pf = *pt;    /* round 1/2 lsb toward infinity */    if (flg) {        tmp &= (u_int32_t)0xff800000;       /* extract exponent and sign */        tmp |= (u_int32_t)0x00010000;       /* insert 1 lsb */        *pf += *pt;                     /* add 1 lsb and elided one */        tmp &= (u_int32_t)0xff800000;       /* extract exponent and sign */        *pf -= *pt;                     /* subtract elided one */    }}/* This only works for 1.0 < float < 2.0 - 2^-24 ! * * Comparison of the performance of the two rounding routines: *      old (above) new (below) * Max error    0.00385171  0.00179992 * RMS error    0.00194603  0.00109221 *//* New bug fixed version */static void inv_table_flt_round(float *ftmp){    int exp;    double mnt;    float descale;    mnt = frexp((double)*ftmp, &exp);    descale = (float)ldexp(1.0, exp + 15);    *ftmp += descale;    *ftmp -= descale;}static void make_inv_tables(faacDecHandle hDecoder){    int i;    u_int32_t tmp1, tmp;    float *pf = (float *)&tmp;    float ftmp;    *pf = 1.0;    tmp1 = tmp;             /* float 1.0 */    for (i=0; i<128; i++) {        tmp = tmp1 + (i<<16);       /* float 1.m, 7 msb only */        ftmp = B / *pf;        inv_table_flt_round(&ftmp); /* round to 16 bits */        hDecoder->mnt_table[i] = ftmp;        /* printf("%3d %08x %f\n", i, tmp, ftmp); */    }    for (i=0; i<256; i++) {        tmp = (i<<23);          /* float 1.0 * 2^exp */        if (*pf > MINVAR) {            ftmp = 1.0f / *pf;        } else {            ftmp = 0;        }        hDecoder->exp_table[i] = ftmp;        /* printf("%3d %08x %g\n", i, tmp, ftmp); */    }}/* Bug-fixed version (big-little endian problem) */static void inv_quant_pred_state(TMP_PRED_STATUS *tmp_psp, PRED_STATUS *psp){    int i;    short *p2;    u_int32_t *p1_tmp;    p1_tmp = (u_int32_t *)tmp_psp;    p2 = (short *) psp;    for (i=0; i<MAX_PRED_BINS*6; i++)        p1_tmp[i] = ((u_int32_t)p2[i])<<16;}#define FAST_QUANT/* Bug-fixed version (big-little endian problem) */static void quant_pred_state(PRED_STATUS *psp, TMP_PRED_STATUS *tmp_psp){    int i;    short *p1;    u_int32_t *p2_tmp;#ifdef  FAST_QUANT    p1 = (short *) psp;    p2_tmp = (u_int32_t *)tmp_psp;    for (i=0; i<MAX_PRED_BINS*6;i++)      p1[i] = (short) (p2_tmp[i]>>16);#else    int j;    for (i=0; i<MAX_PRED_BINS; i++) {    p1 = (short *) &psp[i];      p2_tmp = (u_int32_t *)tmp_psp;  for (j=0; j<6; j++)        p1[j] = (short) (p2_tmp[i]>>16);    }#endif}/******************************************************************************** *** FUNCTION: reset_pred_state()                       * ***                                        * ***    reset predictor state variables                     * ***                                        * ********************************************************************************/void reset_pred_state(PRED_STATUS *psp){    psp->r[0] = Q_ZERO;    psp->r[1] = Q_ZERO;    psp->kor[0] = Q_ZERO;    psp->kor[1] = Q_ZERO;    psp->var[0] = Q_ONE;    psp->var[1] = Q_ONE;}/******************************************************************************** *** FUNCTION: init_pred_stat()                         * ***                                        * ***    initialisation of all predictor parameter               * ***                                        * ********************************************************************************/void init_pred_stat(faacDecHandle hDecoder, PRED_STATUS *psp, int first_time){    /* Initialisation */    if (first_time) {        make_inv_tables(hDecoder);    }    reset_pred_state(psp);}void init_pred(faacDecHandle hDecoder, PRED_STATUS **sp_status, int channels){    int i, ch;    for (ch = 0; ch < channels; ch++) {        for (i = 0; i < LN2; i++) {            init_pred_stat(hDecoder, &sp_status[ch][i], ((ch==0)&&(i==0)));        }    }}/******************************************************************************** *** FUNCTION: monopred()                           * ***                                        * ***    calculation of a predicted value from preceeding (quantised) samples    * ***    using a second order backward adaptive lattice predictor with full  * ***    LMS adaption algorithm for calculation of predictor coefficients    * ***                                        * ***    parameters: pc: pointer to this quantised sample        * ***            psp:    pointer to structure with predictor status  * ***            pred_flag:  1 if prediction is used         * ***                                        * ********************************************************************************/static void monopred(faacDecHandle hDecoder, Float *pc, PRED_STATUS *psp, TMP_PRED_STATUS *pst, int pred_flag){    float qc = *pc;     /* quantized coef */    float pv;           /* predicted value */    float dr1;          /* difference in the R-branch */    float e0,e1;        /* "partial" prediction errors (E-branch) */    float r0,r1;        /* content of delay elements */    float k1,k2;        /* predictor coefficients */    float *R = pst->r;      /* content of delay elements */    float *KOR = pst->kor;  /* estimates of correlations */    float *VAR = pst->var;  /* estimates of variances */    u_int32_t tmp;    int i, j;    r0=R[0];    r1=R[1];    /* Calculation of predictor coefficients to be used for the     * calculation of the current predicted value based on previous     * block's state     */    /* the test, division and rounding is be pre-computed in the tables     * equivalent calculation is:     * k1 = (VAR[1-1]>MINVAR) ? KOR[1-1]/VAR[1-1]*B : 0.0F;     * k2 = (VAR[2-1]>MINVAR) ? KOR[2-1]/VAR[2-1]*B : 0.0F;     */    tmp = psp->var[1-1];    j = (tmp >> 7);    i = tmp & 0x7f;    k1 = KOR[1-1] * hDecoder->exp_table[j] * hDecoder->mnt_table[i];    tmp = psp->var[2-1];    j = (tmp >> 7);    i = tmp & 0x7f;    k2 = KOR[2-1] * hDecoder->exp_table[j] * hDecoder->mnt_table[i];    /* Predicted value */    pv  = k1*r0 + k2*r1;    flt_round(&pv);    if (pred_flag)        *pc = qc + pv;/* printf("P1: %8.2f %8.2f\n", pv, *pc); */    /* Calculate state for use in next block */    /* E-Branch:     *  Calculate the partial prediction errors using the old predictor coefficients     *  and the old r-values in order to reconstruct the predictor status of the     *  previous step     */    e0 = *pc;    e1 = e0-k1*r0;    /* Difference in the R-Branch:     *  Calculate the difference in the R-Branch using the old predictor coefficients and     *  the old partial prediction errors as calculated above in order to reconstruct the     *  predictor status of the previous step     */    dr1 = k1*e0;    /* Adaption of variances and correlations for predictor coefficients:     *  These calculations are based on the predictor status of the previous step and give     *  the new estimates of variances and correlations used for the calculations of the     *  new predictor coefficients to be used for calculating the current predicted value     */    VAR[1-1] = ALPHA*VAR[1-1]+(0.5F)*(r0*r0 + e0*e0);   /* float const */    KOR[1-1] = ALPHA*KOR[1-1] + r0*e0;    VAR[2-1] = ALPHA*VAR[2-1]+(0.5F)*(r1*r1 + e1*e1);   /* float const */    KOR[2-1] = ALPHA*KOR[2-1] + r1*e1;    /* Summation and delay in the R-Branch => new R-values */    r1 = A*(r0-dr1);    r0 = A*e0;    R[0]=r0;    R[1]=r1;}/******************************************************************************** *** FUNCTION: predict()                            * ***                                        * ***    carry out prediction for all allowed spectral lines         * ***                                        * ********************************************************************************/int predict(faacDecHandle hDecoder, Info* info, int profile, int *lpflag, PRED_STATUS *psp, Float *coef){    int j, k, b, to, flag0;    int *top;    if (hDecoder->mc_info.object_type != AACMAIN) {        if (*lpflag == 0) {            /* prediction calculations not required */            return 0;        }        else {            return -1;        }    }    if (info->islong) {        TMP_PRED_STATUS tmp_ps[MAX_PRED_BINS];        inv_quant_pred_state(tmp_ps, psp);        b = 0;        k = 0;        top = info->sbk_sfb_top[b];        flag0 = *lpflag++;        for (j = 0; j < pred_max_bands(hDecoder); j++) {            to = *top++;            if (flag0 && *lpflag++) {                for ( ; k < to; k++) {                    monopred(hDecoder, &coef[k], &psp[k], &tmp_ps[k], 1);                }            } else {                for ( ; k < to; k++) {                    monopred(hDecoder, &coef[k], &psp[k], &tmp_ps[k], 0);                }            }        }        quant_pred_state(psp, tmp_ps);    }    return 0;}/******************************************************************************** *** FUNCTION: predict_reset()                          * ***                                        * ***    carry out cyclic predictor reset mechanism (long blocks)        * ***    resp. full reset (short blocks)                     * ***                                        * ********************************************************************************/int predict_reset(faacDecHandle hDecoder, Info* info, int *prstflag, PRED_STATUS **psp,                   int firstCh, int lastCh, int *last_rstgrp_num){    int j, prstflag0, prstgrp, ch;    prstgrp = 0;    if (info->islong) {        prstflag0 = *prstflag++;        if (prstflag0) {            /* for loop modified because of bit-reversed group number */            for (j=0; j<LEN_PRED_RSTGRP-1; j++) {                prstgrp |= prstflag[j];                prstgrp <<= 1;            }            prstgrp |= prstflag[LEN_PRED_RSTGRP-1];            if ( (prstgrp<1) || (prstgrp>30) ) {                return -1;            }            for (ch=firstCh; ch<=lastCh; ch++) {                /* check if two consecutive reset group numbers are incremented by one                   (this is a poor check, but we don't have much alternatives) */                if ((hDecoder->warn_flag) && (last_rstgrp_num[ch] < 30) && (last_rstgrp_num[ch] != 0)) {                    if ((last_rstgrp_num[ch] + 1) != prstgrp) {                        hDecoder->warn_flag = 0;                    }                }                last_rstgrp_num[ch] = prstgrp;                for (j=prstgrp-1; j<LN2; j+=30) {                    reset_pred_state(&psp[ch][j]);                }            }        } /* end predictor reset */    } /* end islong */    else { /* short blocks */        /* complete prediction reset in all bins */        for (ch=firstCh; ch<=lastCh; ch++) {            last_rstgrp_num[ch] = 0;            for (j=0; j<LN2; j++)                reset_pred_state(&psp[ch][j]);        }    }    return 0;}

⌨️ 快捷键说明

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