Mercurial > hg > audiostuff
comparison intercom/gsm/lpc.c @ 2:13be24d74cd2
import intercom-0.4.1
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 09:57:52 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:9cadc470e3da | 2:13be24d74cd2 |
|---|---|
| 1 /* | |
| 2 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische | |
| 3 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for | |
| 4 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. | |
| 5 */ | |
| 6 | |
| 7 /* $Header: /home/kbs/jutta/src/gsm/gsm-1.0/src/RCS/lpc.c,v 1.1 1992/10/28 00:15:50 jutta Exp $ */ | |
| 8 | |
| 9 #include <stdio.h> | |
| 10 #include <assert.h> | |
| 11 | |
| 12 #include "private.h" | |
| 13 | |
| 14 #include "gsm.h" | |
| 15 #include "proto.h" | |
| 16 | |
| 17 #undef P | |
| 18 | |
| 19 /* | |
| 20 * 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION | |
| 21 */ | |
| 22 | |
| 23 /* 4.2.4 */ | |
| 24 | |
| 25 | |
| 26 static void Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ | |
| 27 longword * L_ACF) | |
| 28 { /* [0..8] OUT */ | |
| 29 /* | |
| 30 * The goal is to compute the array L_ACF[k]. The signal s[i] must | |
| 31 * be scaled in order to avoid an overflow situation. | |
| 32 */ | |
| 33 register int k, i; | |
| 34 | |
| 35 word temp, smax, scalauto; | |
| 36 /* longword L_temp; */ | |
| 37 | |
| 38 #ifdef USE_FLOAT_MUL | |
| 39 float float_s[160]; | |
| 40 /* longword L_temp2; */ | |
| 41 #else | |
| 42 longword L_temp2; | |
| 43 #endif | |
| 44 | |
| 45 /* Dynamic scaling of the array s[0..159] | |
| 46 */ | |
| 47 | |
| 48 /* Search for the maximum. | |
| 49 */ | |
| 50 smax = 0; | |
| 51 for (k = 0; k <= 159; k++) { | |
| 52 temp = GSM_ABS(s[k]); | |
| 53 if (temp > smax) | |
| 54 smax = temp; | |
| 55 } | |
| 56 | |
| 57 /* Computation of the scaling factor. | |
| 58 */ | |
| 59 if (smax == 0) | |
| 60 scalauto = 0; | |
| 61 else { | |
| 62 assert(smax > 0); | |
| 63 scalauto = 4 - gsm_norm((longword) smax << 16); /* sub(4,..) */ | |
| 64 } | |
| 65 | |
| 66 /* Scaling of the array s[0...159] | |
| 67 */ | |
| 68 | |
| 69 if (scalauto > 0) { | |
| 70 | |
| 71 # ifdef USE_FLOAT_MUL | |
| 72 # define SCALE(n) \ | |
| 73 case n: for (k = 0; k <= 159; k++) \ | |
| 74 float_s[k] = (float) \ | |
| 75 (s[k] = GSM_MULT_R(s[k], 16384 >> (n-1)));\ | |
| 76 break; | |
| 77 # else | |
| 78 # define SCALE(n) \ | |
| 79 case n: for (k = 0; k <= 159; k++) \ | |
| 80 s[k] = GSM_MULT_R( s[k], 16384 >> (n-1) );\ | |
| 81 break; | |
| 82 # endif /* USE_FLOAT_MUL */ | |
| 83 | |
| 84 switch (scalauto) { | |
| 85 SCALE(1) | |
| 86 SCALE(2) | |
| 87 SCALE(3) | |
| 88 SCALE(4) | |
| 89 } | |
| 90 # undef SCALE | |
| 91 } | |
| 92 # ifdef USE_FLOAT_MUL | |
| 93 else | |
| 94 for (k = 0; k <= 159; k++) | |
| 95 float_s[k] = (float) s[k]; | |
| 96 # endif | |
| 97 | |
| 98 /* Compute the L_ACF[..]. | |
| 99 */ | |
| 100 { | |
| 101 # ifdef USE_FLOAT_MUL | |
| 102 register float *sp = float_s; | |
| 103 register float sl = *sp; | |
| 104 # else | |
| 105 word *sp = s; | |
| 106 word sl = *sp; | |
| 107 # endif | |
| 108 | |
| 109 # define STEP(k) L_ACF[k] += (longword)(sl * sp[ -(k) ]); | |
| 110 # define NEXTI sl = *++sp | |
| 111 | |
| 112 | |
| 113 for (k = 9; k--; L_ACF[k] = 0); | |
| 114 | |
| 115 STEP(0); | |
| 116 NEXTI; | |
| 117 STEP(0); | |
| 118 STEP(1); | |
| 119 NEXTI; | |
| 120 STEP(0); | |
| 121 STEP(1); | |
| 122 STEP(2); | |
| 123 NEXTI; | |
| 124 STEP(0); | |
| 125 STEP(1); | |
| 126 STEP(2); | |
| 127 STEP(3); | |
| 128 NEXTI; | |
| 129 STEP(0); | |
| 130 STEP(1); | |
| 131 STEP(2); | |
| 132 STEP(3); | |
| 133 STEP(4); | |
| 134 NEXTI; | |
| 135 STEP(0); | |
| 136 STEP(1); | |
| 137 STEP(2); | |
| 138 STEP(3); | |
| 139 STEP(4); | |
| 140 STEP(5); | |
| 141 NEXTI; | |
| 142 STEP(0); | |
| 143 STEP(1); | |
| 144 STEP(2); | |
| 145 STEP(3); | |
| 146 STEP(4); | |
| 147 STEP(5); | |
| 148 STEP(6); | |
| 149 NEXTI; | |
| 150 STEP(0); | |
| 151 STEP(1); | |
| 152 STEP(2); | |
| 153 STEP(3); | |
| 154 STEP(4); | |
| 155 STEP(5); | |
| 156 STEP(6); | |
| 157 STEP(7); | |
| 158 | |
| 159 for (i = 8; i <= 159; i++) { | |
| 160 | |
| 161 NEXTI; | |
| 162 | |
| 163 STEP(0); | |
| 164 STEP(1); | |
| 165 STEP(2); | |
| 166 STEP(3); | |
| 167 STEP(4); | |
| 168 STEP(5); | |
| 169 STEP(6); | |
| 170 STEP(7); | |
| 171 STEP(8); | |
| 172 } | |
| 173 | |
| 174 for (k = 9; k--; L_ACF[k] <<= 1); | |
| 175 | |
| 176 } | |
| 177 /* Rescaling of the array s[0..159] | |
| 178 */ | |
| 179 if (scalauto > 0) { | |
| 180 assert(scalauto <= 4); | |
| 181 for (k = 160; k--; *s++ <<= scalauto); | |
| 182 } | |
| 183 } | |
| 184 | |
| 185 #if defined(USE_FLOAT_MUL) && defined(FAST) | |
| 186 | |
| 187 static void Fast_Autocorrelation P2((s, L_ACF), word * s, /* [0..159] IN/OUT */ | |
| 188 longword * L_ACF) | |
| 189 { /* [0..8] OUT */ | |
| 190 register int k, i; | |
| 191 float f_L_ACF[9]; | |
| 192 float scale; | |
| 193 | |
| 194 float s_f[160]; | |
| 195 register float *sf = s_f; | |
| 196 | |
| 197 for (i = 0; i < 160; ++i) | |
| 198 sf[i] = s[i]; | |
| 199 for (k = 0; k <= 8; k++) { | |
| 200 register float L_temp2 = 0; | |
| 201 register float *sfl = sf - k; | |
| 202 for (i = k; i < 160; ++i) | |
| 203 L_temp2 += sf[i] * sfl[i]; | |
| 204 f_L_ACF[k] = L_temp2; | |
| 205 } | |
| 206 scale = MAX_LONGWORD / f_L_ACF[0]; | |
| 207 | |
| 208 for (k = 0; k <= 8; k++) { | |
| 209 L_ACF[k] = f_L_ACF[k] * scale; | |
| 210 } | |
| 211 } | |
| 212 #endif /* defined (USE_FLOAT_MUL) && defined (FAST) */ | |
| 213 | |
| 214 /* 4.2.5 */ | |
| 215 | |
| 216 static void Reflection_coefficients P2((L_ACF, r), longword * L_ACF, /* 0...8 IN */ | |
| 217 register word * r /* 0...7 OUT */ | |
| 218 ) | |
| 219 { | |
| 220 register int i, m, n; | |
| 221 register word temp; | |
| 222 register longword ltmp; | |
| 223 word ACF[9]; /* 0..8 */ | |
| 224 word P[9]; /* 0..8 */ | |
| 225 word K[9]; /* 2..8 */ | |
| 226 | |
| 227 /* Schur recursion with 16 bits arithmetic. | |
| 228 */ | |
| 229 | |
| 230 if (L_ACF[0] == 0) { /* everything is the same. */ | |
| 231 for (i = 8; i--; *r++ = 0); | |
| 232 return; | |
| 233 } | |
| 234 | |
| 235 assert(L_ACF[0] != 0); | |
| 236 temp = gsm_norm(L_ACF[0]); | |
| 237 | |
| 238 assert(temp >= 0 && temp < 32); | |
| 239 | |
| 240 /* ? overflow ? */ | |
| 241 for (i = 0; i <= 8; i++) | |
| 242 ACF[i] = SASR(L_ACF[i] << temp, 16); | |
| 243 | |
| 244 /* Initialize array P[..] and K[..] for the recursion. | |
| 245 */ | |
| 246 | |
| 247 for (i = 1; i <= 7; i++) | |
| 248 K[i] = ACF[i]; | |
| 249 for (i = 0; i <= 8; i++) | |
| 250 P[i] = ACF[i]; | |
| 251 | |
| 252 /* Compute reflection coefficients | |
| 253 */ | |
| 254 for (n = 1; n <= 8; n++, r++) { | |
| 255 | |
| 256 temp = P[1]; | |
| 257 temp = GSM_ABS(temp); | |
| 258 if (P[0] < temp) { | |
| 259 for (i = n; i <= 8; i++) | |
| 260 *r++ = 0; | |
| 261 return; | |
| 262 } | |
| 263 | |
| 264 *r = gsm_div(temp, P[0]); | |
| 265 | |
| 266 assert(*r >= 0); | |
| 267 if (P[1] > 0) | |
| 268 *r = -*r; /* r[n] = sub(0, r[n]) */ | |
| 269 assert(*r != MIN_WORD); | |
| 270 if (n == 8) | |
| 271 return; | |
| 272 | |
| 273 /* Schur recursion | |
| 274 */ | |
| 275 temp = GSM_MULT_R(P[1], *r); | |
| 276 P[0] = GSM_ADD(P[0], temp); | |
| 277 | |
| 278 for (m = 1; m <= 8 - n; m++) { | |
| 279 temp = GSM_MULT_R(K[m], *r); | |
| 280 P[m] = GSM_ADD(P[m + 1], temp); | |
| 281 | |
| 282 temp = GSM_MULT_R(P[m + 1], *r); | |
| 283 K[m] = GSM_ADD(K[m], temp); | |
| 284 } | |
| 285 } | |
| 286 } | |
| 287 | |
| 288 /* 4.2.6 */ | |
| 289 | |
| 290 static void Transformation_to_Log_Area_Ratios P1((r), register word * r /* 0..7 IN/OUT */ | |
| 291 ) | |
| 292 /* | |
| 293 * The following scaling for r[..] and LAR[..] has been used: | |
| 294 * | |
| 295 * r[..] = integer( real_r[..]*32768. ); -1 <= real_r < 1. | |
| 296 * LAR[..] = integer( real_LAR[..] * 16384 ); | |
| 297 * with -1.625 <= real_LAR <= 1.625 | |
| 298 */ | |
| 299 { | |
| 300 register word temp; | |
| 301 register int i; | |
| 302 | |
| 303 | |
| 304 /* Computation of the LAR[0..7] from the r[0..7] | |
| 305 */ | |
| 306 for (i = 1; i <= 8; i++, r++) { | |
| 307 | |
| 308 temp = *r; | |
| 309 temp = GSM_ABS(temp); | |
| 310 assert(temp >= 0); | |
| 311 | |
| 312 if (temp < 22118) { | |
| 313 temp >>= 1; | |
| 314 } else if (temp < 31130) { | |
| 315 assert(temp >= 11059); | |
| 316 temp -= 11059; | |
| 317 } else { | |
| 318 assert(temp >= 26112); | |
| 319 temp -= 26112; | |
| 320 temp <<= 2; | |
| 321 } | |
| 322 | |
| 323 *r = *r < 0 ? -temp : temp; | |
| 324 assert(*r != MIN_WORD); | |
| 325 } | |
| 326 } | |
| 327 | |
| 328 /* 4.2.7 */ | |
| 329 | |
| 330 static void Quantization_and_coding P1((LAR), register word * LAR /* [0..7] IN/OUT */ | |
| 331 ) | |
| 332 { | |
| 333 register word temp; | |
| 334 longword ltmp; | |
| 335 /* ulongword utmp; reported as unused */ | |
| 336 | |
| 337 | |
| 338 /* This procedure needs four tables; the following equations | |
| 339 * give the optimum scaling for the constants: | |
| 340 * | |
| 341 * A[0..7] = integer( real_A[0..7] * 1024 ) | |
| 342 * B[0..7] = integer( real_B[0..7] * 512 ) | |
| 343 * MAC[0..7] = maximum of the LARc[0..7] | |
| 344 * MIC[0..7] = minimum of the LARc[0..7] | |
| 345 */ | |
| 346 | |
| 347 # undef STEP | |
| 348 # define STEP( A, B, MAC, MIC ) \ | |
| 349 temp = GSM_MULT( A, *LAR ); \ | |
| 350 temp = GSM_ADD( temp, B ); \ | |
| 351 temp = GSM_ADD( temp, 256 ); \ | |
| 352 temp = SASR( temp, 9 ); \ | |
| 353 *LAR = temp>MAC ? MAC - MIC : (temp<MIC ? 0 : temp - MIC); \ | |
| 354 LAR++; | |
| 355 | |
| 356 STEP(20480, 0, 31, -32); | |
| 357 STEP(20480, 0, 31, -32); | |
| 358 STEP(20480, 2048, 15, -16); | |
| 359 STEP(20480, -2560, 15, -16); | |
| 360 | |
| 361 STEP(13964, 94, 7, -8); | |
| 362 STEP(15360, -1792, 7, -8); | |
| 363 STEP(8534, -341, 3, -4); | |
| 364 STEP(9036, -1144, 3, -4); | |
| 365 | |
| 366 # undef STEP | |
| 367 } | |
| 368 | |
| 369 void Gsm_LPC_Analysis P3((S, s, LARc), struct gsm_state *S, word * s, /* 0..159 signals IN/OUT */ | |
| 370 word * LARc) | |
| 371 { /* 0..7 LARc's OUT */ | |
| 372 longword L_ACF[9]; | |
| 373 | |
| 374 #if defined(USE_FLOAT_MUL) && defined(FAST) | |
| 375 if (S->fast) | |
| 376 Fast_Autocorrelation(s, L_ACF); | |
| 377 else | |
| 378 #endif | |
| 379 Autocorrelation(s, L_ACF); | |
| 380 Reflection_coefficients(L_ACF, LARc); | |
| 381 Transformation_to_Log_Area_Ratios(LARc); | |
| 382 Quantization_and_coding(LARc); | |
| 383 } |
