| /* | |
| * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische | |
| * Universitaet Berlin. See the accompanying file "COPYRIGHT" for | |
| * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. | |
| */ | |
| #include <stdio.h> | |
| #include <assert.h> | |
| #include "gsm610_priv.h" | |
| /* | |
| * SHORT TERM ANALYSIS FILTERING SECTION | |
| */ | |
| /* 4.2.8 */ | |
| static void Decoding_of_the_coded_Log_Area_Ratios ( | |
| int16_t * LARc, /* coded log area ratio [0..7] IN */ | |
| int16_t * LARpp) /* out: decoded .. */ | |
| { | |
| register int16_t temp1 ; | |
| /* 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; | |
| * temp1 = GSM_SUB(temp1, temp2) ; | |
| * | |
| * assert(*INVA != MIN_WORD) ; | |
| * | |
| * temp1 = GSM_MULT_R (*INVA, temp1) ; | |
| * *LARpp = GSM_ADD (temp1, temp1) ; | |
| * } | |
| */ | |
| #undef STEP | |
| #define STEP(B, MIC, INVA) \ | |
| temp1 = arith_shift_left (GSM_ADD (*LARc++, MIC), 10) ; \ | |
| temp1 = GSM_SUB (temp1, B * 2) ; \ | |
| temp1 = GSM_MULT_R (INVA, temp1) ; \ | |
| *LARpp++ = GSM_ADD (temp1, temp1) ; | |
| STEP (0, -32, 13107) ; | |
| STEP (0, -32, 13107) ; | |
| STEP (2048, -16, 13107) ; | |
| STEP (-2560, -16, 13107) ; | |
| STEP (94, -8, 19223) ; | |
| STEP (-1792, -8, 17476) ; | |
| STEP (-341, -4, 31454) ; | |
| STEP (-1144, -4, 29708) ; | |
| /* NOTE: the addition of *MIC is used to restore | |
| * the sign of *LARc. | |
| */ | |
| } | |
| /* 4.2.9 */ | |
| /* Computation of the quantized reflection coefficients | |
| */ | |
| /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] | |
| */ | |
| /* | |
| * Within each frame of 160 analyzed speech samples the short term | |
| * analysis and synthesis filters operate with four different sets of | |
| * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) | |
| * and the actual set of decoded LARs (LARpp(j)) | |
| * | |
| * (Initial value: LARpp(j-1)[1..8] = 0.) | |
| */ | |
| static void Coefficients_0_12 ( | |
| register int16_t * LARpp_j_1, | |
| register int16_t * LARpp_j, | |
| register int16_t * LARp) | |
| { | |
| register int i ; | |
| for (i = 1 ; i <= 8 ; i++, LARp++, LARpp_j_1++, LARpp_j++) | |
| { *LARp = GSM_ADD (SASR_W (*LARpp_j_1, 2), SASR_W (*LARpp_j, 2)) ; | |
| *LARp = GSM_ADD (*LARp, SASR_W (*LARpp_j_1, 1)) ; | |
| } | |
| } | |
| static void Coefficients_13_26 ( | |
| register int16_t * LARpp_j_1, | |
| register int16_t * LARpp_j, | |
| register int16_t * LARp) | |
| { | |
| register int i ; | |
| for (i = 1 ; i <= 8 ; i++, LARpp_j_1++, LARpp_j++, LARp++) | |
| *LARp = GSM_ADD (SASR_W (*LARpp_j_1, 1), SASR_W (*LARpp_j, 1)) ; | |
| } | |
| static void Coefficients_27_39 ( | |
| register int16_t * LARpp_j_1, | |
| register int16_t * LARpp_j, | |
| register int16_t * LARp) | |
| { | |
| register int i ; | |
| for (i = 1 ; i <= 8 ; i++, LARpp_j_1++, LARpp_j++, LARp++) | |
| { *LARp = GSM_ADD (SASR_W (*LARpp_j_1, 2), SASR_W (*LARpp_j, 2)) ; | |
| *LARp = GSM_ADD (*LARp, SASR_W (*LARpp_j, 1)) ; | |
| } | |
| } | |
| static void Coefficients_40_159 ( | |
| register int16_t * LARpp_j, | |
| register int16_t * LARp) | |
| { | |
| register int i ; | |
| for (i = 1 ; i <= 8 ; i++, LARp++, LARpp_j++) | |
| *LARp = *LARpp_j ; | |
| } | |
| /* 4.2.9.2 */ | |
| static void LARp_to_rp ( | |
| register int16_t * LARp) /* [0..7] IN/OUT */ | |
| /* | |
| * The input of this procedure is the interpolated LARp[0..7] array. | |
| * The reflection coefficients, rp[i], are used in the analysis | |
| * filter and in the synthesis filter. | |
| */ | |
| { | |
| register int i ; | |
| register int16_t temp ; | |
| for (i = 1 ; i <= 8 ; i++, LARp++) | |
| { /* temp = GSM_ABS(*LARp) ; | |
| * | |
| * if (temp < 11059) temp <<= 1; | |
| * else if (temp < 20070) temp += 11059; | |
| * else temp = GSM_ADD (temp >> 2, 26112) ; | |
| * | |
| * *LARp = *LARp < 0 ? -temp : temp; | |
| */ | |
| if (*LARp < 0) | |
| { temp = *LARp == MIN_WORD ? MAX_WORD : - (*LARp) ; | |
| *LARp = - ((temp < 11059) ? temp << 1 | |
| : ((temp < 20070) ? temp + 11059 | |
| : GSM_ADD ((int16_t) (temp >> 2), (int16_t) 26112))) ; | |
| } | |
| else | |
| { temp = *LARp ; | |
| *LARp = (temp < 11059) ? temp << 1 | |
| : ((temp < 20070) ? temp + 11059 | |
| : GSM_ADD ((int16_t) (temp >> 2), (int16_t) 26112)) ; | |
| } | |
| } | |
| } | |
| /* 4.2.10 */ | |
| static void Short_term_analysis_filtering ( | |
| struct gsm_state * S, | |
| register int16_t * rp, /* [0..7] IN */ | |
| register int k_n, /* k_end - k_start */ | |
| register int16_t * s /* [0..n-1] IN/OUT */ | |
| ) | |
| /* | |
| * This procedure computes the short term residual signal d[..] to be fed | |
| * to the RPE-LTP loop from the s[..] signal and from the local rp[..] | |
| * array (quantized reflection coefficients). As the call of this | |
| * procedure can be done in many ways (see the interpolation of the LAR | |
| * coefficient), it is assumed that the computation begins with index | |
| * k_start (for arrays d[..] and s[..]) and stops with index k_end | |
| * (k_start and k_end are defined in 4.2.9.1). This procedure also | |
| * needs to keep the array u [0..7] in memory for each call. | |
| */ | |
| { | |
| register int16_t * u = S->u ; | |
| register int i ; | |
| register int16_t di, zzz, ui, sav, rpi ; | |
| for ( ; k_n-- ; s++) | |
| { di = sav = *s ; | |
| for (i = 0 ; i < 8 ; i++) | |
| { /* YYY */ | |
| ui = u [i] ; | |
| rpi = rp [i] ; | |
| u [i] = sav ; | |
| zzz = GSM_MULT_R (rpi, di) ; | |
| sav = GSM_ADD (ui, zzz) ; | |
| zzz = GSM_MULT_R (rpi, ui) ; | |
| di = GSM_ADD (di, zzz) ; | |
| } | |
| *s = di ; | |
| } | |
| } | |
| #if defined (USE_FLOAT_MUL) && defined (FAST) | |
| static void Fast_Short_term_analysis_filtering ( | |
| struct gsm_state * S, | |
| register int16_t * rp, /* [0..7] IN */ | |
| register int k_n, /* k_end - k_start */ | |
| register int16_t * s /* [0..n-1] IN/OUT */ | |
| ) | |
| { | |
| register int16_t * u = S->u ; | |
| register int i ; | |
| float uf [8], rpf [8] ; | |
| register float scalef = 3.0517578125e-5 ; | |
| register float sav, di, temp ; | |
| for (i = 0 ; i < 8 ; ++i) | |
| { uf [i] = u [i] ; | |
| rpf [i] = rp [i] * scalef ; | |
| } | |
| for ( ; k_n-- ; s++) | |
| { sav = di = *s ; | |
| for (i = 0 ; i < 8 ; i++) | |
| { register float rpfi = rpf [i] ; | |
| register float ufi = uf [i] ; | |
| uf [i] = sav ; | |
| temp = rpfi * di + ufi ; | |
| di += rpfi * ufi ; | |
| sav = temp ; | |
| } | |
| *s = di ; | |
| } | |
| for (i = 0 ; i < 8 ; i++) u [i] = uf [i] ; | |
| } | |
| #endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ | |
| static void Short_term_synthesis_filtering ( | |
| struct gsm_state * S, | |
| register int16_t * rrp, /* [0..7] IN */ | |
| register int k, /* k_end - k_start */ | |
| register int16_t * wt, /* [0..k-1] IN */ | |
| register int16_t * sr /* [0..k-1] OUT */ | |
| ) | |
| { | |
| register int16_t * v = S->v ; | |
| register int i ; | |
| register int16_t sri, tmp1, tmp2 ; | |
| while (k--) | |
| { sri = *wt++ ; | |
| for (i = 8 ; i-- ; ) | |
| { /* sri = GSM_SUB(sri, gsm_mult_r(rrp[i], v [i])) ; | |
| */ | |
| tmp1 = rrp [i] ; | |
| tmp2 = v [i] ; | |
| tmp2 = (tmp1 == MIN_WORD && tmp2 == MIN_WORD | |
| ? MAX_WORD | |
| : 0x0FFFF & (((int32_t) tmp1 * (int32_t) tmp2 | |
| + 16384) >> 15)) ; | |
| sri = GSM_SUB (sri, tmp2) ; | |
| /* v [i+1] = GSM_ADD (v [i], gsm_mult_r(rrp[i], sri)) ; | |
| */ | |
| tmp1 = (tmp1 == MIN_WORD && sri == MIN_WORD | |
| ? MAX_WORD | |
| : 0x0FFFF & (((int32_t) tmp1 * (int32_t) sri | |
| + 16384) >> 15)) ; | |
| v [i + 1] = GSM_ADD (v [i], tmp1) ; | |
| } | |
| *sr++ = v [0] = sri ; | |
| } | |
| } | |
| #if defined (FAST) && defined (USE_FLOAT_MUL) | |
| static void Fast_Short_term_synthesis_filtering ( | |
| struct gsm_state * S, | |
| register int16_t * rrp, /* [0..7] IN */ | |
| register int k, /* k_end - k_start */ | |
| register int16_t * wt, /* [0..k-1] IN */ | |
| register int16_t * sr /* [0..k-1] OUT */ | |
| ) | |
| { | |
| register int16_t * v = S->v ; | |
| register int i ; | |
| float va [9], rrpa [8] ; | |
| register float scalef = 3.0517578125e-5, temp ; | |
| for (i = 0 ; i < 8 ; ++i) | |
| { va [i] = v [i] ; | |
| rrpa [i] = (float) rrp [i] * scalef ; | |
| } | |
| while (k--) { | |
| register float sri = *wt++ ; | |
| for (i = 8 ; i-- ; ) | |
| { sri -= rrpa [i] * va [i] ; | |
| if (sri < -32768.0) sri = -32768.0 ; | |
| else if (sri > 32767.0) sri = 32767.0 ; | |
| temp = va [i] + rrpa [i] * sri ; | |
| if (temp < -32768.0) temp = -32768.0 ; | |
| else if (temp > 32767.0) temp = 32767.0 ; | |
| va [i+1] = temp ; | |
| } | |
| *sr++ = va [0] = sri ; | |
| } | |
| for (i = 0 ; i < 9 ; ++i) v [i] = va [i] ; | |
| } | |
| #endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ | |
| void Gsm_Short_Term_Analysis_Filter ( | |
| struct gsm_state * S, | |
| int16_t * LARc, /* coded log area ratio [0..7] IN */ | |
| int16_t * s /* signal [0..159] IN/OUT */ | |
| ) | |
| { | |
| int16_t * LARpp_j = S->LARpp [S->j] ; | |
| int16_t * LARpp_j_1 = S->LARpp [S->j ^= 1] ; | |
| int16_t LARp [8] ; | |
| #undef FILTER | |
| #if defined (FAST) && defined (USE_FLOAT_MUL) | |
| # define FILTER (* (S->fast \ | |
| ? Fast_Short_term_analysis_filtering \ | |
| : Short_term_analysis_filtering)) | |
| #else | |
| # define FILTER Short_term_analysis_filtering | |
| #endif | |
| Decoding_of_the_coded_Log_Area_Ratios (LARc, LARpp_j) ; | |
| Coefficients_0_12 (LARpp_j_1, LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 13, s) ; | |
| Coefficients_13_26 (LARpp_j_1, LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 14, s + 13) ; | |
| Coefficients_27_39 (LARpp_j_1, LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 13, s + 27) ; | |
| Coefficients_40_159 (LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 120, s + 40) ; | |
| } | |
| void Gsm_Short_Term_Synthesis_Filter ( | |
| struct gsm_state * S, | |
| int16_t * LARcr, /* received log area ratios [0..7] IN */ | |
| int16_t * wt, /* received d [0..159] IN */ | |
| int16_t * s /* signal s [0..159] OUT */ | |
| ) | |
| { | |
| int16_t * LARpp_j = S->LARpp [S->j] ; | |
| int16_t * LARpp_j_1 = S->LARpp [S->j ^= 1] ; | |
| int16_t LARp [8] ; | |
| #undef FILTER | |
| #if defined (FAST) && defined (USE_FLOAT_MUL) | |
| # define FILTER (* (S->fast \ | |
| ? Fast_Short_term_synthesis_filtering \ | |
| : Short_term_synthesis_filtering)) | |
| #else | |
| # define FILTER Short_term_synthesis_filtering | |
| #endif | |
| Decoding_of_the_coded_Log_Area_Ratios (LARcr, LARpp_j) ; | |
| Coefficients_0_12 (LARpp_j_1, LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 13, wt, s) ; | |
| Coefficients_13_26 (LARpp_j_1, LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 14, wt + 13, s + 13) ; | |
| Coefficients_27_39 (LARpp_j_1, LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 13, wt + 27, s + 27) ; | |
| Coefficients_40_159 (LARpp_j, LARp) ; | |
| LARp_to_rp (LARp) ; | |
| FILTER (S, LARp, 120, wt + 40, s + 40) ; | |
| } |