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 }

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.