Mercurial > hg > audiostuff
comparison intercom/gsm/short_te.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/short_term.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 /* | |
18 * SHORT TERM ANALYSIS FILTERING SECTION | |
19 */ | |
20 | |
21 /* 4.2.8 */ | |
22 | |
23 static void Decoding_of_the_coded_Log_Area_Ratios P2((LARc, LARpp), word * LARc, /* coded log area ratio [0..7] IN */ | |
24 word * LARpp) | |
25 { /* out: decoded .. */ | |
26 register word temp1; | |
27 /* register word temp2; -> This is unused */ | |
28 register long ltmp; /* for GSM_ADD */ | |
29 | |
30 /* This procedure requires for efficient implementation | |
31 * two tables. | |
32 * | |
33 * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) | |
34 * MIC[1..8] = minimum value of the LARc[1..8] | |
35 */ | |
36 | |
37 /* Compute the LARpp[1..8] | |
38 */ | |
39 | |
40 /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { | |
41 * | |
42 * temp1 = GSM_ADD( *LARc, *MIC ) << 10; | |
43 * temp2 = *B << 1; | |
44 * temp1 = GSM_SUB( temp1, temp2 ); | |
45 * | |
46 * assert(*INVA != MIN_WORD); | |
47 * | |
48 * temp1 = GSM_MULT_R( *INVA, temp1 ); | |
49 * *LARpp = GSM_ADD( temp1, temp1 ); | |
50 * } | |
51 */ | |
52 | |
53 #ifdef STEP | |
54 #undef STEP | |
55 #endif | |
56 | |
57 #define STEP( B, MIC, INVA ) \ | |
58 temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ | |
59 temp1 = GSM_SUB( temp1, B << 1 ); \ | |
60 temp1 = GSM_MULT_R( INVA, temp1 ); \ | |
61 *LARpp++ = GSM_ADD( temp1, temp1 ); | |
62 | |
63 STEP(0, -32, 13107); | |
64 STEP(0, -32, 13107); | |
65 STEP(2048, -16, 13107); | |
66 STEP(-2560, -16, 13107); | |
67 | |
68 STEP(94, -8, 19223); | |
69 STEP(-1792, -8, 17476); | |
70 STEP(-341, -4, 31454); | |
71 STEP(-1144, -4, 29708); | |
72 | |
73 /* NOTE: the addition of *MIC is used to restore | |
74 * the sign of *LARc. | |
75 */ | |
76 } | |
77 | |
78 /* 4.2.9 */ | |
79 /* Computation of the quantized reflection coefficients | |
80 */ | |
81 | |
82 /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] | |
83 */ | |
84 | |
85 /* | |
86 * Within each frame of 160 analyzed speech samples the short term | |
87 * analysis and synthesis filters operate with four different sets of | |
88 * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) | |
89 * and the actual set of decoded LARs (LARpp(j)) | |
90 * | |
91 * (Initial value: LARpp(j-1)[1..8] = 0.) | |
92 */ | |
93 | |
94 static void Coefficients_0_12 P3((LARpp_j_1, LARpp_j, LARp), | |
95 register word * LARpp_j_1, | |
96 register word * LARpp_j, register word * LARp) | |
97 { | |
98 register int i; | |
99 register longword ltmp; | |
100 | |
101 for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { | |
102 *LARp = GSM_ADD(SASR(*LARpp_j_1, 2), SASR(*LARpp_j, 2)); | |
103 *LARp = GSM_ADD(*LARp, SASR(*LARpp_j_1, 1)); | |
104 } | |
105 } | |
106 | |
107 static void Coefficients_13_26 P3((LARpp_j_1, LARpp_j, LARp), | |
108 register word * LARpp_j_1, | |
109 register word * LARpp_j, register word * LARp) | |
110 { | |
111 register int i; | |
112 register longword ltmp; | |
113 for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { | |
114 *LARp = GSM_ADD(SASR(*LARpp_j_1, 1), SASR(*LARpp_j, 1)); | |
115 } | |
116 } | |
117 | |
118 static void Coefficients_27_39 P3((LARpp_j_1, LARpp_j, LARp), | |
119 register word * LARpp_j_1, | |
120 register word * LARpp_j, register word * LARp) | |
121 { | |
122 register int i; | |
123 register longword ltmp; | |
124 | |
125 for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { | |
126 *LARp = GSM_ADD(SASR(*LARpp_j_1, 2), SASR(*LARpp_j, 2)); | |
127 *LARp = GSM_ADD(*LARp, SASR(*LARpp_j, 1)); | |
128 } | |
129 } | |
130 | |
131 | |
132 static void Coefficients_40_159 P2((LARpp_j, LARp), | |
133 register word * LARpp_j, register word * LARp) | |
134 { | |
135 register int i; | |
136 | |
137 for (i = 1; i <= 8; i++, LARp++, LARpp_j++) | |
138 *LARp = *LARpp_j; | |
139 } | |
140 | |
141 /* 4.2.9.2 */ | |
142 | |
143 static void LARp_to_rp P1((LARp), register word * LARp) | |
144 { /* [0..7] IN/OUT */ | |
145 /* | |
146 * The input of this procedure is the interpolated LARp[0..7] array. | |
147 * The reflection coefficients, rp[i], are used in the analysis | |
148 * filter and in the synthesis filter. | |
149 */ | |
150 register int i; | |
151 register word temp; | |
152 register longword ltmp; | |
153 | |
154 for (i = 1; i <= 8; i++, LARp++) { | |
155 | |
156 /* temp = GSM_ABS( *LARp ); | |
157 * | |
158 * if (temp < 11059) temp <<= 1; | |
159 * else if (temp < 20070) temp += 11059; | |
160 * else temp = GSM_ADD( temp >> 2, 26112 ); | |
161 * | |
162 * *LARp = *LARp < 0 ? -temp : temp; | |
163 */ | |
164 | |
165 if (*LARp < 0) { | |
166 temp = *LARp == MIN_WORD ? MAX_WORD : -(*LARp); | |
167 *LARp = -((temp < 11059) ? temp << 1 | |
168 : ((temp < 20070) ? temp + 11059 : GSM_ADD(temp >> 2, 26112))); | |
169 } else { | |
170 temp = *LARp; | |
171 *LARp = (temp < 11059) ? temp << 1 | |
172 : ((temp < 20070) ? temp + 11059 : GSM_ADD(temp >> 2, 26112)); | |
173 } | |
174 } | |
175 } | |
176 | |
177 | |
178 /* 4.2.10 */ | |
179 static void Short_term_analysis_filtering P4((S, rp, k_n, s), struct gsm_state *S, register word * rp, /* [0..7] IN */ | |
180 register int k_n, /* k_end - k_start */ | |
181 register word * s /* [0..n-1] IN/OUT */ | |
182 ) | |
183 /* | |
184 * This procedure computes the short term residual signal d[..] to be fed | |
185 * to the RPE-LTP loop from the s[..] signal and from the local rp[..] | |
186 * array (quantized reflection coefficients). As the call of this | |
187 * procedure can be done in many ways (see the interpolation of the LAR | |
188 * coefficient), it is assumed that the computation begins with index | |
189 * k_start (for arrays d[..] and s[..]) and stops with index k_end | |
190 * (k_start and k_end are defined in 4.2.9.1). This procedure also | |
191 * needs to keep the array u[0..7] in memory for each call. | |
192 */ | |
193 { | |
194 register word *u = S->u; | |
195 register int i; | |
196 register word di, zzz, ui, sav, rpi; | |
197 register longword ltmp; | |
198 | |
199 for (; k_n--; s++) { | |
200 | |
201 di = sav = *s; | |
202 | |
203 for (i = 0; i < 8; i++) { /* YYY */ | |
204 | |
205 ui = u[i]; | |
206 rpi = rp[i]; | |
207 u[i] = sav; | |
208 | |
209 zzz = GSM_MULT_R(rpi, di); | |
210 sav = GSM_ADD(ui, zzz); | |
211 | |
212 zzz = GSM_MULT_R(rpi, ui); | |
213 di = GSM_ADD(di, zzz); | |
214 } | |
215 | |
216 *s = di; | |
217 } | |
218 } | |
219 | |
220 #if defined(USE_FLOAT_MUL) && defined(FAST) | |
221 | |
222 static void Fast_Short_term_analysis_filtering P4((S, rp, k_n, s), struct gsm_state *S, register word * rp, /* [0..7] IN */ | |
223 register int k_n, /* k_end - k_start */ | |
224 register word * s /* [0..n-1] IN/OUT */ | |
225 ) | |
226 { | |
227 register word *u = S->u; | |
228 register int i; | |
229 | |
230 float uf[8], rpf[8]; | |
231 | |
232 register float scalef = 3.0517578125e-5; | |
233 register float sav, di, temp; | |
234 | |
235 for (i = 0; i < 8; ++i) { | |
236 uf[i] = u[i]; | |
237 rpf[i] = rp[i] * scalef; | |
238 } | |
239 for (; k_n--; s++) { | |
240 sav = di = *s; | |
241 for (i = 0; i < 8; ++i) { | |
242 register float rpfi = rpf[i]; | |
243 register float ufi = uf[i]; | |
244 | |
245 uf[i] = sav; | |
246 temp = rpfi * di + ufi; | |
247 di += rpfi * ufi; | |
248 sav = temp; | |
249 } | |
250 *s = di; | |
251 } | |
252 for (i = 0; i < 8; ++i) | |
253 u[i] = uf[i]; | |
254 } | |
255 #endif /* ! (defined (USE_FLOAT_MUL) && defined (FAST)) */ | |
256 | |
257 static void Short_term_synthesis_filtering P5((S, rrp, k, wt, sr), struct gsm_state *S, register word * rrp, /* [0..7] IN */ | |
258 register int k, /* k_end - k_start */ | |
259 register word * wt, /* [0..k-1] IN */ | |
260 register word * sr /* [0..k-1] OUT */ | |
261 ) | |
262 { | |
263 register word *v = S->v; | |
264 register int i; | |
265 register word sri, tmp1, tmp2; | |
266 register longword ltmp; /* for GSM_ADD & GSM_SUB */ | |
267 | |
268 while (k--) { | |
269 sri = *wt++; | |
270 for (i = 8; i--;) { | |
271 | |
272 /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); | |
273 */ | |
274 tmp1 = rrp[i]; | |
275 tmp2 = v[i]; | |
276 tmp2 = (tmp1 == MIN_WORD && tmp2 == MIN_WORD | |
277 ? MAX_WORD | |
278 : 0x0FFFF & (((longword) tmp1 * (longword) tmp2 | |
279 + 16384) >> 15)); | |
280 | |
281 sri = GSM_SUB(sri, tmp2); | |
282 | |
283 /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); | |
284 */ | |
285 tmp1 = (tmp1 == MIN_WORD && sri == MIN_WORD | |
286 ? MAX_WORD | |
287 : 0x0FFFF & (((longword) tmp1 * (longword) sri + 16384) >> 15)); | |
288 | |
289 v[i + 1] = GSM_ADD(v[i], tmp1); | |
290 } | |
291 *sr++ = v[0] = sri; | |
292 } | |
293 } | |
294 | |
295 | |
296 #if defined(FAST) && defined(USE_FLOAT_MUL) | |
297 | |
298 static void Fast_Short_term_synthesis_filtering P5((S, rrp, k, wt, sr), struct gsm_state *S, register word * rrp, /* [0..7] IN */ | |
299 register int k, /* k_end - k_start */ | |
300 register word * wt, /* [0..k-1] IN */ | |
301 register word * sr /* [0..k-1] OUT */ | |
302 ) | |
303 { | |
304 register word *v = S->v; | |
305 register int i; | |
306 | |
307 float va[9], rrpa[8]; | |
308 register float scalef = 3.0517578125e-5, temp; | |
309 | |
310 for (i = 0; i < 8; ++i) { | |
311 va[i] = v[i]; | |
312 rrpa[i] = (float) rrp[i] * scalef; | |
313 } | |
314 while (k--) { | |
315 register float sri = *wt++; | |
316 for (i = 8; i--;) { | |
317 sri -= rrpa[i] * va[i]; | |
318 if (sri < -32768.) | |
319 sri = -32768.; | |
320 else if (sri > 32767.) | |
321 sri = 32767.; | |
322 | |
323 temp = va[i] + rrpa[i] * sri; | |
324 if (temp < -32768.) | |
325 temp = -32768.; | |
326 else if (temp > 32767.) | |
327 temp = 32767.; | |
328 va[i + 1] = temp; | |
329 } | |
330 *sr++ = va[0] = sri; | |
331 } | |
332 for (i = 0; i < 9; ++i) | |
333 v[i] = va[i]; | |
334 } | |
335 | |
336 #endif /* defined(FAST) && defined(USE_FLOAT_MUL) */ | |
337 | |
338 void Gsm_Short_Term_Analysis_Filter P3((S, LARc, s), struct gsm_state *S, word * LARc, /* coded log area ratio [0..7] IN */ | |
339 word * s /* signal [0..159] IN/OUT */ | |
340 ) | |
341 { | |
342 word *LARpp_j = S->LARpp[S->j]; | |
343 word *LARpp_j_1 = S->LARpp[S->j ^= 1]; | |
344 | |
345 word LARp[8]; | |
346 | |
347 #ifdef FILTER | |
348 #undef FILTER | |
349 #endif | |
350 | |
351 #if defined(FAST) && defined(USE_FLOAT_MUL) | |
352 # define FILTER (* (S->fast \ | |
353 ? Fast_Short_term_analysis_filtering \ | |
354 : Short_term_analysis_filtering )) | |
355 | |
356 #else | |
357 # define FILTER Short_term_analysis_filtering | |
358 #endif | |
359 | |
360 Decoding_of_the_coded_Log_Area_Ratios(LARc, LARpp_j); | |
361 | |
362 Coefficients_0_12(LARpp_j_1, LARpp_j, LARp); | |
363 LARp_to_rp(LARp); | |
364 FILTER(S, LARp, 13, s); | |
365 | |
366 Coefficients_13_26(LARpp_j_1, LARpp_j, LARp); | |
367 LARp_to_rp(LARp); | |
368 FILTER(S, LARp, 14, s + 13); | |
369 | |
370 Coefficients_27_39(LARpp_j_1, LARpp_j, LARp); | |
371 LARp_to_rp(LARp); | |
372 FILTER(S, LARp, 13, s + 27); | |
373 | |
374 Coefficients_40_159(LARpp_j, LARp); | |
375 LARp_to_rp(LARp); | |
376 FILTER(S, LARp, 120, s + 40); | |
377 } | |
378 | |
379 void Gsm_Short_Term_Synthesis_Filter P4((S, LARcr, wt, s), struct gsm_state *S, word * LARcr, /* received log area ratios [0..7] IN */ | |
380 word * wt, /* received d [0..159] IN */ | |
381 word * s /* signal s [0..159] OUT */ | |
382 ) | |
383 { | |
384 word *LARpp_j = S->LARpp[S->j]; | |
385 word *LARpp_j_1 = S->LARpp[S->j ^= 1]; | |
386 | |
387 word LARp[8]; | |
388 | |
389 #ifdef FILTER | |
390 #undef FILTER | |
391 #endif | |
392 | |
393 #if defined(FAST) && defined(USE_FLOAT_MUL) | |
394 | |
395 # define FILTER (* (S->fast \ | |
396 ? Fast_Short_term_synthesis_filtering \ | |
397 : Short_term_synthesis_filtering )) | |
398 #else | |
399 # define FILTER Short_term_synthesis_filtering | |
400 #endif | |
401 | |
402 Decoding_of_the_coded_Log_Area_Ratios(LARcr, LARpp_j); | |
403 | |
404 Coefficients_0_12(LARpp_j_1, LARpp_j, LARp); | |
405 LARp_to_rp(LARp); | |
406 FILTER(S, LARp, 13, wt, s); | |
407 | |
408 Coefficients_13_26(LARpp_j_1, LARpp_j, LARp); | |
409 LARp_to_rp(LARp); | |
410 FILTER(S, LARp, 14, wt + 13, s + 13); | |
411 | |
412 Coefficients_27_39(LARpp_j_1, LARpp_j, LARp); | |
413 LARp_to_rp(LARp); | |
414 FILTER(S, LARp, 13, wt + 27, s + 27); | |
415 | |
416 Coefficients_40_159(LARpp_j, LARp); | |
417 LARp_to_rp(LARp); | |
418 FILTER(S, LARp, 120, wt + 40, s + 40); | |
419 } |