FreeCalypso > hg > gsm-codec-lib
comparison libgsmfr2/long_term.c @ 267:65d3304502bd
libgsmfr2: integrate long_term.c from libgsm
| author | Mychaela Falconia <falcon@freecalypso.org> | 
|---|---|
| date | Sun, 14 Apr 2024 01:01:19 +0000 | 
| parents | |
| children | 
   comparison
  equal
  deleted
  inserted
  replaced
| 266:8821ffaa93a5 | 267:65d3304502bd | 
|---|---|
| 1 /* | |
| 2 * This C source file has been adapted from TU-Berlin libgsm source, | |
| 3 * original notice follows: | |
| 4 * | |
| 5 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische | |
| 6 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for | |
| 7 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. | |
| 8 */ | |
| 9 | |
| 10 #include <stdint.h> | |
| 11 #include <assert.h> | |
| 12 #include "tw_gsmfr.h" | |
| 13 #include "typedef.h" | |
| 14 #include "ed_state.h" | |
| 15 #include "ed_internal.h" | |
| 16 | |
| 17 /* | |
| 18 * 4.2.11 .. 4.2.12 LONG TERM PREDICTOR (LTP) SECTION | |
| 19 */ | |
| 20 | |
| 21 | |
| 22 /* | |
| 23 * This module computes the LTP gain (bc) and the LTP lag (Nc) | |
| 24 * for the long term analysis filter. This is done by calculating a | |
| 25 * maximum of the cross-correlation function between the current | |
| 26 * sub-segment short term residual signal d[0..39] (output of | |
| 27 * the short term analysis filter; for simplification the index | |
| 28 * of this array begins at 0 and ends at 39 for each sub-segment of the | |
| 29 * RPE-LTP analysis) and the previous reconstructed short term | |
| 30 * residual signal dp[ -120 .. -1 ]. A dynamic scaling must be | |
| 31 * performed to avoid overflow. | |
| 32 */ | |
| 33 | |
| 34 static void Calculation_of_the_LTP_parameters ( | |
| 35 register word * d, /* [0..39] IN */ | |
| 36 register word * dp, /* [-120..-1] IN */ | |
| 37 word * bc_out, /* OUT */ | |
| 38 word * Nc_out /* OUT */ | |
| 39 ) | |
| 40 { | |
| 41 register int k, lambda; | |
| 42 word Nc, bc; | |
| 43 word wt[40]; | |
| 44 | |
| 45 longword L_max, L_power; | |
| 46 word R, S, dmax, scal; | |
| 47 register word temp; | |
| 48 | |
| 49 /* Search of the optimum scaling of d[0..39]. | |
| 50 */ | |
| 51 dmax = 0; | |
| 52 | |
| 53 for (k = 0; k <= 39; k++) { | |
| 54 temp = d[k]; | |
| 55 temp = GSM_ABS( temp ); | |
| 56 if (temp > dmax) dmax = temp; | |
| 57 } | |
| 58 | |
| 59 temp = 0; | |
| 60 if (dmax == 0) scal = 0; | |
| 61 else { | |
| 62 assert(dmax > 0); | |
| 63 temp = gsm_norm( (longword)dmax << 16 ); | |
| 64 } | |
| 65 | |
| 66 if (temp > 6) scal = 0; | |
| 67 else scal = 6 - temp; | |
| 68 | |
| 69 assert(scal >= 0); | |
| 70 | |
| 71 /* Initialization of a working array wt | |
| 72 */ | |
| 73 | |
| 74 for (k = 0; k <= 39; k++) wt[k] = SASR( d[k], scal ); | |
| 75 | |
| 76 /* Search for the maximum cross-correlation and coding of the LTP lag | |
| 77 */ | |
| 78 L_max = 0; | |
| 79 Nc = 40; /* index for the maximum cross-correlation */ | |
| 80 | |
| 81 for (lambda = 40; lambda <= 120; lambda++) { | |
| 82 | |
| 83 # undef STEP | |
| 84 # define STEP(k) (longword)wt[k] * dp[k - lambda] | |
| 85 | |
| 86 register longword L_result; | |
| 87 | |
| 88 L_result = STEP(0) ; L_result += STEP(1) ; | |
| 89 L_result += STEP(2) ; L_result += STEP(3) ; | |
| 90 L_result += STEP(4) ; L_result += STEP(5) ; | |
| 91 L_result += STEP(6) ; L_result += STEP(7) ; | |
| 92 L_result += STEP(8) ; L_result += STEP(9) ; | |
| 93 L_result += STEP(10) ; L_result += STEP(11) ; | |
| 94 L_result += STEP(12) ; L_result += STEP(13) ; | |
| 95 L_result += STEP(14) ; L_result += STEP(15) ; | |
| 96 L_result += STEP(16) ; L_result += STEP(17) ; | |
| 97 L_result += STEP(18) ; L_result += STEP(19) ; | |
| 98 L_result += STEP(20) ; L_result += STEP(21) ; | |
| 99 L_result += STEP(22) ; L_result += STEP(23) ; | |
| 100 L_result += STEP(24) ; L_result += STEP(25) ; | |
| 101 L_result += STEP(26) ; L_result += STEP(27) ; | |
| 102 L_result += STEP(28) ; L_result += STEP(29) ; | |
| 103 L_result += STEP(30) ; L_result += STEP(31) ; | |
| 104 L_result += STEP(32) ; L_result += STEP(33) ; | |
| 105 L_result += STEP(34) ; L_result += STEP(35) ; | |
| 106 L_result += STEP(36) ; L_result += STEP(37) ; | |
| 107 L_result += STEP(38) ; L_result += STEP(39) ; | |
| 108 | |
| 109 if (L_result > L_max) { | |
| 110 | |
| 111 Nc = lambda; | |
| 112 L_max = L_result; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 *Nc_out = Nc; | |
| 117 | |
| 118 L_max <<= 1; | |
| 119 | |
| 120 /* Rescaling of L_max | |
| 121 */ | |
| 122 assert(scal <= 100 && scal >= -100); | |
| 123 L_max = L_max >> (6 - scal); /* sub(6, scal) */ | |
| 124 | |
| 125 assert( Nc <= 120 && Nc >= 40); | |
| 126 | |
| 127 /* Compute the power of the reconstructed short term residual | |
| 128 * signal dp[..] | |
| 129 */ | |
| 130 L_power = 0; | |
| 131 for (k = 0; k <= 39; k++) { | |
| 132 | |
| 133 register longword L_temp; | |
| 134 | |
| 135 L_temp = SASR( dp[k - Nc], 3 ); | |
| 136 L_power += L_temp * L_temp; | |
| 137 } | |
| 138 L_power <<= 1; /* from L_MULT */ | |
| 139 | |
| 140 /* Normalization of L_max and L_power | |
| 141 */ | |
| 142 | |
| 143 if (L_max <= 0) { | |
| 144 *bc_out = 0; | |
| 145 return; | |
| 146 } | |
| 147 if (L_max >= L_power) { | |
| 148 *bc_out = 3; | |
| 149 return; | |
| 150 } | |
| 151 | |
| 152 temp = gsm_norm( L_power ); | |
| 153 | |
| 154 R = SASR( L_max << temp, 16 ); | |
| 155 S = SASR( L_power << temp, 16 ); | |
| 156 | |
| 157 /* Coding of the LTP gain | |
| 158 */ | |
| 159 | |
| 160 /* Table 4.3a must be used to obtain the level DLB[i] for the | |
| 161 * quantization of the LTP gain b to get the coded version bc. | |
| 162 */ | |
| 163 for (bc = 0; bc <= 2; bc++) if (R <= gsm_mult(S, gsm_DLB[bc])) break; | |
| 164 *bc_out = bc; | |
| 165 } | |
| 166 | |
| 167 /* 4.2.12 */ | |
| 168 | |
| 169 static void Long_term_analysis_filtering ( | |
| 170 word bc, /* IN */ | |
| 171 word Nc, /* IN */ | |
| 172 register word * dp, /* previous d [-120..-1] IN */ | |
| 173 register word * d, /* d [0..39] IN */ | |
| 174 register word * dpp, /* estimate [0..39] OUT */ | |
| 175 register word * e /* long term res. signal [0..39] OUT */ | |
| 176 ) | |
| 177 /* | |
| 178 * In this part, we have to decode the bc parameter to compute | |
| 179 * the samples of the estimate dpp[0..39]. The decoding of bc needs the | |
| 180 * use of table 4.3b. The long term residual signal e[0..39] | |
| 181 * is then calculated to be fed to the RPE encoding section. | |
| 182 */ | |
| 183 { | |
| 184 register int k; | |
| 185 register longword ltmp; | |
| 186 | |
| 187 # undef STEP | |
| 188 # define STEP(BP) \ | |
| 189 for (k = 0; k <= 39; k++) { \ | |
| 190 dpp[k] = GSM_MULT_R( BP, dp[k - Nc]); \ | |
| 191 e[k] = GSM_SUB( d[k], dpp[k] ); \ | |
| 192 } | |
| 193 | |
| 194 switch (bc) { | |
| 195 case 0: STEP( 3277 ); break; | |
| 196 case 1: STEP( 11469 ); break; | |
| 197 case 2: STEP( 21299 ); break; | |
| 198 case 3: STEP( 32767 ); break; | |
| 199 } | |
| 200 } | |
| 201 | |
| 202 void Gsm_Long_Term_Predictor ( /* 4x for 160 samples */ | |
| 203 struct gsmfr_0610_state * S, | |
| 204 | |
| 205 word * d, /* [0..39] residual signal IN */ | |
| 206 word * dp, /* [-120..-1] d' IN */ | |
| 207 | |
| 208 word * e, /* [0..39] OUT */ | |
| 209 word * dpp, /* [0..39] OUT */ | |
| 210 word * Nc, /* correlation lag OUT */ | |
| 211 word * bc /* gain factor OUT */ | |
| 212 ) | |
| 213 { | |
| 214 assert( d ); assert( dp ); assert( e ); | |
| 215 assert( dpp); assert( Nc ); assert( bc ); | |
| 216 | |
| 217 Calculation_of_the_LTP_parameters(d, dp, bc, Nc); | |
| 218 Long_term_analysis_filtering( *bc, *Nc, dp, d, dpp, e ); | |
| 219 } | |
| 220 | |
| 221 /* 4.3.2 */ | |
| 222 void Gsm_Long_Term_Synthesis_Filtering ( | |
| 223 struct gsmfr_0610_state * S, | |
| 224 | |
| 225 word Ncr, | |
| 226 word bcr, | |
| 227 register word * erp, /* [0..39] IN */ | |
| 228 register word * drp /* [-120..-1] IN, [-120..40] OUT */ | |
| 229 ) | |
| 230 /* | |
| 231 * This procedure uses the bcr and Ncr parameter to realize the | |
| 232 * long term synthesis filtering. The decoding of bcr needs | |
| 233 * table 4.3b. | |
| 234 */ | |
| 235 { | |
| 236 register longword ltmp; /* for ADD */ | |
| 237 register int k; | |
| 238 word brp, drpp, Nr; | |
| 239 | |
| 240 /* Check the limits of Nr. | |
| 241 */ | |
| 242 Nr = Ncr < 40 || Ncr > 120 ? S->nrp : Ncr; | |
| 243 S->nrp = Nr; | |
| 244 assert(Nr >= 40 && Nr <= 120); | |
| 245 | |
| 246 /* Decoding of the LTP gain bcr | |
| 247 */ | |
| 248 brp = gsm_QLB[ bcr ]; | |
| 249 | |
| 250 /* Computation of the reconstructed short term residual | |
| 251 * signal drp[0..39] | |
| 252 */ | |
| 253 assert(brp != MIN_WORD); | |
| 254 | |
| 255 for (k = 0; k <= 39; k++) { | |
| 256 drpp = GSM_MULT_R( brp, drp[ k - Nr ] ); | |
| 257 drp[k] = GSM_ADD( erp[k], drpp ); | |
| 258 } | |
| 259 | |
| 260 /* | |
| 261 * Update of the reconstructed short term residual signal | |
| 262 * drp[ -1..-120 ] | |
| 263 */ | |
| 264 | |
| 265 for (k = 0; k <= 119; k++) drp[ -120 + k ] = drp[ -80 + k ]; | |
| 266 } | 
