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