2
|
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 }
|