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

📄 gsm.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 5 页
字号:

        /*  4.2.2   Offset compensation
         * 
         *  This part implements a high-pass filter and requires extended
         *  arithmetic precision for the recursive part of this filter.
         *  The input of this procedure is the array so[0...159] and the
         *  output the array sof[ 0...159 ].
         */
                /*   Compute the non-recursive part
                 */

                s1 = SO - z1;                   /* s1 = gsm_sub( *so, z1 ); */
                z1 = SO;

                pgpAssert(s1 != MIN_WORD);

                /*   Compute the recursive part
                 */
                L_s2 = s1;
                L_s2 <<= 15;

                /*   Execution of a 31 bv 16 bits multiplication
                 */

                msp = SASR( L_z2, 15 );
                lsp = GSM_L_SUB(L_z2,(msp<<15));

                L_s2  += GSM_MULT_R( lsp, 32735 );
                L_temp = (longword)msp * 32735; /* GSM_L_MULT(msp,32735) >> 1;*/
                L_z2   = GSM_L_ADD( L_temp, L_s2 );

                /*    Compute sof[k] with rounding
                 */
                L_temp = GSM_L_ADD( L_z2, 16384 );

        /*   4.2.3  Preemphasis
         */

                msp   = GSM_MULT_R( mp, -28180 );
                mp    = SASR( L_temp, 15 );
                *so++ = GSM_ADD( mp, msp );
        }

        S->z1   = z1;
        S->L_z2 = L_z2;
        S->mp   = mp;
}

/*
 *  4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER
 */

static void Gsm_Coder(
        struct gsm_state        * S,
        word    * s,    /* [0..159] samples                     IN      */
/*
 * The RPE-LTD coder works on a frame by frame basis.  The length of
 * the frame is equal to 160 samples.  Some computations are done
 * once per frame to produce at the output of the coder the
 * LARc[1..8] parameters which are the coded LAR coefficients and
 * also to realize the inverse filtering operation for the entire
 * frame (160 samples of signal d[0..159]).  These parts produce at
 * the output of the coder:
 */
        word    * LARc, /* [0..7] LAR coefficients              OUT     */
/*
 * Procedure 4.2.11 to 4.2.18 are to be executed four times per
 * frame.  That means once for each sub-segment RPE-LTP analysis of
 * 40 samples.  These parts produce at the output of the coder:
 */
        word    * Nc,   /* [0..3] LTP lag                       OUT     */
        word    * bc,   /* [0..3] coded LTP gain                OUT     */
        word    * Mc,   /* [0..3] RPE grid selection            OUT     */
        word    * xmaxc,/* [0..3] Coded maximum amplitude       OUT     */
        word    * xMc   /* [13*4] normalized RPE samples        OUT     */
)
{
        int     k;
        word    * dp  = S->dp0 + 120;   /* [ -120...-1 ] */
        word    * dpp = dp;             /* [ 0...39 ]    */

        static word     e [50] = {0};

        word    so[160];

        Gsm_Preprocess                  (S, s, so);
        Gsm_LPC_Analysis                (so, LARc);
        Gsm_Short_Term_Analysis_Filter  (S, LARc, so);

        for (k = 0; k <= 3; k++, xMc += 13) {

                Gsm_Long_Term_Predictor ( S,
                                         so+k*40, /* d      [0..39] IN  */
                                         dp,      /* dp  [-120..-1] IN  */
                                        e + 5,    /* e      [0..39] OUT */
                                        dpp,      /* dpp    [0..39] OUT */
                                         Nc++,
                                         bc++);

                Gsm_RPE_Encoding        (
                                        e + 5,  /* e      ][0..39][ IN/OUT */
                                          xmaxc++, Mc++, xMc );
                /*
                 * Gsm_Update_of_reconstructed_short_time_residual_signal
                 *                      ( dpp, e + 5, dp );
                 */

                { register int i;
                  for (i = 0; i <= 39; i++)
                        dp[ i ] = GSM_ADD( e[5 + i], dpp[i] );
                }
                dp  += 40;
                dpp += 40;

        }
        (void)memcpy( (char *)S->dp0, (char *)(S->dp0 + 160),
                120 * sizeof(*S->dp0) );
}

/*
 *  4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER
 */

static void Postprocessing(
        struct gsm_state        * S,
        register word           * s)
{
        register int            k;
        register word           msr = S->msr;
        register word           tmp;

        for (k = 160; k--; s++) {
                tmp = GSM_MULT_R( msr, 28180 );
                msr = GSM_ADD(*s, tmp);            /* Deemphasis             */
                *s  = GSM_ADD(msr, msr) & 0xFFF8;  /* Truncation & Upscaling */
        }
        S->msr = msr;
}

static void Gsm_Decoder(
        struct gsm_state        * S,

        word            * LARcr,        /* [0..7]               IN      */

        word            * Ncr,          /* [0..3]               IN      */
        word            * bcr,          /* [0..3]               IN      */
        word            * Mcr,          /* [0..3]               IN      */
        word            * xmaxcr,       /* [0..3]               IN      */
        word            * xMcr,         /* [0..13*4]            IN      */

        word            * s)            /* [0..159]             OUT     */
{
        int             j, k;
        word            erp[40], wt[160];
        word            * drp = S->dp0 + 120;

        for (j=0; j <= 3; j++, xmaxcr++, bcr++, Ncr++, Mcr++, xMcr += 13) {

                Gsm_RPE_Decoding( *xmaxcr, *Mcr, xMcr, erp );
                Gsm_Long_Term_Synthesis_Filtering( S, *Ncr, *bcr, erp, drp );

                for (k = 0; k <= 39; k++) wt[ j * 40 + k ] =  drp[ k ];
        }

        Gsm_Short_Term_Synthesis_Filter( S, LARcr, wt, s );
        Postprocessing(S, s);
}

/*
 *  4.2.4 .. 4.2.7 LPC ANALYSIS SECTION
 */

/* 4.2.4 */


static void Autocorrelation(
        word     * s,           /* [0..159]     IN/OUT  */
        longword * L_ACF)       /* [0..8]       OUT     */
/*
 *  The goal is to compute the array L_ACF[k].  The signal s[i] must
 *  be scaled in order to avoid an overflow situation.
 */
{
        register int    k, i;

        word            temp, smax, scalauto;

        /*  Dynamic scaling of the array  s[0..159]
         */

        /*  Search for the maximum.
         */
        smax = 0;
        for (k = 0; k <= 159; k++) {
                temp = GSM_ABS( s[k] );
                if (temp > smax) smax = temp;
        }

        /*  Computation of the scaling factor.
         */
        if (smax == 0) scalauto = 0;
        else {
                pgpAssert(smax > 0);
                scalauto = 4 - gsm_norm( (longword)smax << 16 );/* sub(4,..) */
        }

        /*  Scaling of the array s[0...159]
         */

        if (scalauto > 0) {

#   define SCALE(n)     \
        case n: for (k = 0; k <= 159; k++) \
                        s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\
                break;

                switch (scalauto) {
                SCALE(1)
                SCALE(2)
                SCALE(3)
                SCALE(4)
                }
# undef SCALE
        }

        /*  Compute the L_ACF[..].
         */
        {
                word  * sp = s;
                word    sl = *sp;

#               define STEP(k)   L_ACF[k] += ((longword)sl * sp[ -(k) ]);

#       define NEXTI     sl = *++sp


        for (k = 9; k--; L_ACF[k] = 0) ;

        STEP (0);
        NEXTI;
        STEP(0); STEP(1);
        NEXTI;
        STEP(0); STEP(1); STEP(2);
        NEXTI;
        STEP(0); STEP(1); STEP(2); STEP(3);
        NEXTI;
        STEP(0); STEP(1); STEP(2); STEP(3); STEP(4);
        NEXTI;
        STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5);
        NEXTI;
        STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6);
        NEXTI;
        STEP(0); STEP(1); STEP(2); STEP(3); STEP(4); STEP(5); STEP(6); STEP(7);

        for (i = 8; i <= 159; i++) {

                NEXTI;

                STEP(0);
                STEP(1); STEP(2); STEP(3); STEP(4);
                STEP(5); STEP(6); STEP(7); STEP(8);
        }

        for (k = 9; k--; L_ACF[k] <<= 1) ;

        }
        /*   Rescaling of the array s[0..159]
         */
        if (scalauto > 0) {
                pgpAssert(scalauto <= 4);
                for (k = 160; k--; *s++ <<= scalauto) ;
        }
}

/* 4.2.5 */

static void Reflection_coefficients(
        longword        * L_ACF,                /* 0...8        IN      */
        register word   * r                     /* 0...7        OUT     */
)
{
        register int    i, m, n;
        register word   temp;
/*      register longword ltmp; */
        word            ACF[9]; /* 0..8 */
        word            P[  9]; /* 0..8 */
        word            K[  9]; /* 2..8 */

        /*  Schur recursion with 16 bits arithmetic.
         */

        if (L_ACF[0] == 0) {
                for (i = 8; i--; *r++ = 0) ;
                return;
        }

        pgpAssert( L_ACF[0] != 0 );
        temp = gsm_norm( L_ACF[0] );

        pgpAssert(temp >= 0 && temp < 32);

        /* ? overflow ? */
        for (i = 0; i <= 8; i++) ACF[i] = SASR( L_ACF[i] << temp, 16 );

        /*   Initialize array P[..] and K[..] for the recursion.
         */

        for (i = 1; i <= 7; i++) K[ i ] = ACF[ i ];
        for (i = 0; i <= 8; i++) P[ i ] = ACF[ i ];

        /*   Compute reflection coefficients
         */
        for (n = 1; n <= 8; n++, r++) {

                temp = P[1];
                temp = GSM_ABS(temp);
                if (P[0] < temp) {
                        for (i = n; i <= 8; i++) *r++ = 0;
                        return;
                }

                *r = gsm_div( temp, P[0] );

                pgpAssert(*r >= 0);
                if (P[1] > 0) *r = -*r;         /* r[n] = sub(0, r[n]) */
                pgpAssert (*r != MIN_WORD);
                if (n == 8) return;

                /*  Schur recursion
                 */
                temp = GSM_MULT_R( P[1], *r );
                P[0] = GSM_ADD( P[0], temp );

                for (m = 1; m <= 8 - n; m++) {
                        temp     = GSM_MULT_R( K[ m   ],    *r );
                        P[m]     = GSM_ADD(    P[ m+1 ],  temp );

                        temp     = GSM_MULT_R( P[ m+1 ],    *r );
                        K[m]     = GSM_ADD(    K[ m   ],  temp );
                }
        }
}

/* 4.2.6 */

static void Transformation_to_Log_Area_Ratios(
        register word   * r                     /* 0..7    IN/OUT */
)
/*
 *  The following scaling for r[..] and LAR[..] has been used:
 *
 *  r[..]   = integer( real_r[..]*32768. ); -1 <= real_r < 1.
 *  LAR[..] = integer( real_LAR[..] * 16384 );
 *  with -1.625 <= real_LAR <= 1.625
 */
{
        register word   temp;
        register int    i;


        /* Computation of the LAR[0..7] from the r[0..7]
         */
        for (i = 1; i <= 8; i++, r++) {

                temp = *r;
                temp = GSM_ABS(temp);
                pgpAssert(temp >= 0);

                if (temp < 22118) {
                        temp >>= 1;
                } else if (temp < 31130) {
                        pgpAssert( temp >= 11059 );
                        temp -= 11059;
                } else {
                        pgpAssert( temp >= 26112 );
                        temp -= 26112;
                        temp <<= 2;
                }

                *r = *r < 0 ? -temp : temp;
                pgpAssert( *r != MIN_WORD );
        }
}

static void Gsm_LPC_Analysis(
        word             * s,           /* 0..159 signals       IN/OUT  */
        word             * LARc)        /* 0..7   LARc's        OUT     */
{
        longword        L_ACF[9];

        Autocorrelation                   (s,     L_ACF );
        Reflection_coefficients           (L_ACF, LARc  );
        Transformation_to_Log_Area_Ratios (LARc);
        Quantization_and_coding           (LARc);
}



/* 4.2.7 */

static void Quantization_and_coding(
        register word * LAR     /* [0..7]       IN/OUT  */
)
{
        register word   temp;
/* longword     ltmp; */


        /*  This procedure needs four tables; the following equations
         *  give the optimum scaling for the constants:
         *
         *  A[0..7] = integer( real_A[0..7] * 1024 )
         *  B[0..7] = integer( real_B[0..7] *  512 )
         *  MAC[0..7] = maximum of the LARc[0..7]
         *  MIC[0..7] = minimum of the LARc[0..7]
         */

#       undef STEP
#       define  STEP( A, B, MAC, MIC )          \
                temp = GSM_MULT( A,   *LAR );   \
                temp = GSM_ADD(  temp,   B );   \
                temp = GSM_ADD(  temp, 256 );   \
                temp = SASR(     temp,   9 );   \
                *LAR  =  temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \
                LAR++;

        STEP(  20480,     0,  31, -32 );
        STEP(  20480,     0,  31, -32 );
        STEP(  20480,  2048,  15, -16 );
        STEP(  20480, -2560,  15, -16 );

        STEP(  13964,    94,   7,  -8 );
        STEP(  15360, -1792,   7,  -8 );
        STEP(   8534,  -341,   3,  -4 );
        STEP(   9036, -1144,   3,  -4 );

#       undef   STEP
}


/*
 *  SHORT TERM ANALYSIS FILTERING SECTION
 */

/* 4.2.8 */

static void Decoding_of_the_coded_Log_Area_Ratios(
        word    * LARc,         /* coded log area ratio [0..7]  IN      */
        word    * LARpp)        /* out: decoded ..                      */
{
        register word   temp1 /* , temp2 */;
/*      register long   ltmp;   /* for GSM_ADD */

        /*  This procedure requires for efficient implementation
         *  two tables.
         *
         *  INVA[1..8] = integer( (32768 * 8) / real_A[1..8])
         *  MIC[1..8]  = minimum value of the LARc[1..8]
         */

        /*  Compute the LARpp[1..8]
         */

        /*      for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) {
         *
         *              temp1  = GSM_ADD( *LARc, *MIC ) << 10;
         *              temp2  = *B << 1;

⌨️ 快捷键说明

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