FreeCalypso > hg > gsm-codec-lib
comparison libgsmfr2/short_term.c @ 271:d320a8fa3392
libgsmfr2: integrate short_term.c from libgsm
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 14 Apr 2024 02:32:25 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
270:bee3a94f42a7 | 271:d320a8fa3392 |
---|---|
1 /* | |
2 * This C source file has been adapted from TU-Berlin libgsm source, | |
3 * original notice follows: | |
4 * | |
5 * Copyright 1992 by Jutta Degener and Carsten Bormann, Technische | |
6 * Universitaet Berlin. See the accompanying file "COPYRIGHT" for | |
7 * details. THERE IS ABSOLUTELY NO WARRANTY FOR THIS SOFTWARE. | |
8 */ | |
9 | |
10 #include <stdint.h> | |
11 #include "tw_gsmfr.h" | |
12 #include "typedef.h" | |
13 #include "ed_state.h" | |
14 #include "ed_internal.h" | |
15 | |
16 /* | |
17 * SHORT TERM ANALYSIS FILTERING SECTION | |
18 */ | |
19 | |
20 /* 4.2.8 */ | |
21 | |
22 static void Decoding_of_the_coded_Log_Area_Ratios ( | |
23 const word * LARc, /* coded log area ratio [0..7] IN */ | |
24 word * LARpp) /* out: decoded .. */ | |
25 { | |
26 register word temp1 /* , temp2 */; | |
27 register long ltmp; /* for GSM_ADD */ | |
28 | |
29 /* This procedure requires for efficient implementation | |
30 * two tables. | |
31 * | |
32 * INVA[1..8] = integer( (32768 * 8) / real_A[1..8]) | |
33 * MIC[1..8] = minimum value of the LARc[1..8] | |
34 */ | |
35 | |
36 /* Compute the LARpp[1..8] | |
37 */ | |
38 | |
39 /* for (i = 1; i <= 8; i++, B++, MIC++, INVA++, LARc++, LARpp++) { | |
40 * | |
41 * temp1 = GSM_ADD( *LARc, *MIC ) << 10; | |
42 * temp2 = *B << 1; | |
43 * temp1 = GSM_SUB( temp1, temp2 ); | |
44 * | |
45 * assert(*INVA != MIN_WORD); | |
46 * | |
47 * temp1 = GSM_MULT_R( *INVA, temp1 ); | |
48 * *LARpp = GSM_ADD( temp1, temp1 ); | |
49 * } | |
50 */ | |
51 | |
52 #undef STEP | |
53 #define STEP( B_TIMES_TWO, MIC, INVA ) \ | |
54 temp1 = GSM_ADD( *LARc++, MIC ) << 10; \ | |
55 temp1 = GSM_SUB( temp1, B_TIMES_TWO ); \ | |
56 temp1 = GSM_MULT_R( INVA, temp1 ); \ | |
57 *LARpp++ = GSM_ADD( temp1, temp1 ); | |
58 | |
59 STEP( 0, -32, 13107 ); | |
60 STEP( 0, -32, 13107 ); | |
61 STEP( 4096, -16, 13107 ); | |
62 STEP( -5120, -16, 13107 ); | |
63 | |
64 STEP( 188, -8, 19223 ); | |
65 STEP( -3584, -8, 17476 ); | |
66 STEP( -682, -4, 31454 ); | |
67 STEP( -2288, -4, 29708 ); | |
68 | |
69 /* NOTE: the addition of *MIC is used to restore | |
70 * the sign of *LARc. | |
71 */ | |
72 } | |
73 | |
74 /* 4.2.9 */ | |
75 /* Computation of the quantized reflection coefficients | |
76 */ | |
77 | |
78 /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] | |
79 */ | |
80 | |
81 /* | |
82 * Within each frame of 160 analyzed speech samples the short term | |
83 * analysis and synthesis filters operate with four different sets of | |
84 * coefficients, derived from the previous set of decoded LARs(LARpp(j-1)) | |
85 * and the actual set of decoded LARs (LARpp(j)) | |
86 * | |
87 * (Initial value: LARpp(j-1)[1..8] = 0.) | |
88 */ | |
89 | |
90 static void Coefficients_0_12 ( | |
91 register word * LARpp_j_1, | |
92 register word * LARpp_j, | |
93 register word * LARp) | |
94 { | |
95 register int i; | |
96 register longword ltmp; | |
97 | |
98 for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) { | |
99 *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); | |
100 *LARp = GSM_ADD( *LARp, SASR( *LARpp_j_1, 1)); | |
101 } | |
102 } | |
103 | |
104 static void Coefficients_13_26 ( | |
105 register word * LARpp_j_1, | |
106 register word * LARpp_j, | |
107 register word * LARp) | |
108 { | |
109 register int i; | |
110 register longword ltmp; | |
111 for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { | |
112 *LARp = GSM_ADD( SASR( *LARpp_j_1, 1), SASR( *LARpp_j, 1 )); | |
113 } | |
114 } | |
115 | |
116 static void Coefficients_27_39 ( | |
117 register word * LARpp_j_1, | |
118 register word * LARpp_j, | |
119 register word * LARp) | |
120 { | |
121 register int i; | |
122 register longword ltmp; | |
123 | |
124 for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) { | |
125 *LARp = GSM_ADD( SASR( *LARpp_j_1, 2 ), SASR( *LARpp_j, 2 )); | |
126 *LARp = GSM_ADD( *LARp, SASR( *LARpp_j, 1 )); | |
127 } | |
128 } | |
129 | |
130 static void Coefficients_40_159 ( | |
131 register word * LARpp_j, | |
132 register word * LARp) | |
133 { | |
134 register int i; | |
135 | |
136 for (i = 1; i <= 8; i++, LARp++, LARpp_j++) | |
137 *LARp = *LARpp_j; | |
138 } | |
139 | |
140 /* 4.2.9.2 */ | |
141 | |
142 static void LARp_to_rp ( | |
143 register word * LARp) /* [0..7] IN/OUT */ | |
144 /* | |
145 * The input of this procedure is the interpolated LARp[0..7] array. | |
146 * The reflection coefficients, rp[i], are used in the analysis | |
147 * filter and in the synthesis filter. | |
148 */ | |
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 | |
169 : GSM_ADD( temp >> 2, 26112 ))); | |
170 } else { | |
171 temp = *LARp; | |
172 *LARp = (temp < 11059) ? temp << 1 | |
173 : ((temp < 20070) ? temp + 11059 | |
174 : GSM_ADD( temp >> 2, 26112 )); | |
175 } | |
176 } | |
177 } | |
178 | |
179 /* 4.2.10 */ | |
180 static void Short_term_analysis_filtering ( | |
181 struct gsmfr_0610_state * S, | |
182 register word * rp, /* [0..7] IN */ | |
183 register int k_n, /* k_end - k_start */ | |
184 register word * s /* [0..n-1] IN/OUT */ | |
185 ) | |
186 /* | |
187 * This procedure computes the short term residual signal d[..] to be fed | |
188 * to the RPE-LTP loop from the s[..] signal and from the local rp[..] | |
189 * array (quantized reflection coefficients). As the call of this | |
190 * procedure can be done in many ways (see the interpolation of the LAR | |
191 * coefficient), it is assumed that the computation begins with index | |
192 * k_start (for arrays d[..] and s[..]) and stops with index k_end | |
193 * (k_start and k_end are defined in 4.2.9.1). This procedure also | |
194 * needs to keep the array u[0..7] in memory for each call. | |
195 */ | |
196 { | |
197 register word * u = S->u; | |
198 register int i; | |
199 register word di, zzz, ui, sav, rpi; | |
200 register longword ltmp; | |
201 | |
202 for (; k_n--; s++) { | |
203 | |
204 di = sav = *s; | |
205 | |
206 for (i = 0; i < 8; i++) { /* YYY */ | |
207 | |
208 ui = u[i]; | |
209 rpi = rp[i]; | |
210 u[i] = sav; | |
211 | |
212 zzz = GSM_MULT_R(rpi, di); | |
213 sav = GSM_ADD( ui, zzz); | |
214 | |
215 zzz = GSM_MULT_R(rpi, ui); | |
216 di = GSM_ADD( di, zzz ); | |
217 } | |
218 | |
219 *s = di; | |
220 } | |
221 } | |
222 | |
223 static void Short_term_synthesis_filtering ( | |
224 struct gsmfr_0610_state * S, | |
225 register word * rrp, /* [0..7] IN */ | |
226 register int k, /* k_end - k_start */ | |
227 register word * wt, /* [0..k-1] IN */ | |
228 register word * sr /* [0..k-1] OUT */ | |
229 ) | |
230 { | |
231 register word * v = S->v; | |
232 register int i; | |
233 register word sri, tmp1, tmp2; | |
234 register longword ltmp; /* for GSM_ADD & GSM_SUB */ | |
235 | |
236 while (k--) { | |
237 sri = *wt++; | |
238 for (i = 8; i--;) { | |
239 | |
240 /* sri = GSM_SUB( sri, gsm_mult_r( rrp[i], v[i] ) ); | |
241 */ | |
242 tmp1 = rrp[i]; | |
243 tmp2 = v[i]; | |
244 tmp2 = ( tmp1 == MIN_WORD && tmp2 == MIN_WORD | |
245 ? MAX_WORD | |
246 : 0x0FFFF & (( (longword)tmp1 * (longword)tmp2 | |
247 + 16384) >> 15)) ; | |
248 | |
249 sri = GSM_SUB( sri, tmp2 ); | |
250 | |
251 /* v[i+1] = GSM_ADD( v[i], gsm_mult_r( rrp[i], sri ) ); | |
252 */ | |
253 tmp1 = ( tmp1 == MIN_WORD && sri == MIN_WORD | |
254 ? MAX_WORD | |
255 : 0x0FFFF & (( (longword)tmp1 * (longword)sri | |
256 + 16384) >> 15)) ; | |
257 | |
258 v[i+1] = GSM_ADD( v[i], tmp1); | |
259 } | |
260 *sr++ = v[0] = sri; | |
261 } | |
262 } | |
263 | |
264 void Gsm_Short_Term_Analysis_Filter ( | |
265 struct gsmfr_0610_state * S, | |
266 | |
267 const word * LARc, /* coded log area ratio [0..7] IN */ | |
268 word * s /* signal [0..159] IN/OUT */ | |
269 ) | |
270 { | |
271 word * LARpp_j = S->LARpp[ S->j ]; | |
272 word * LARpp_j_1 = S->LARpp[ S->j ^= 1 ]; | |
273 | |
274 word LARp[8]; | |
275 | |
276 #undef FILTER | |
277 # define FILTER Short_term_analysis_filtering | |
278 | |
279 Decoding_of_the_coded_Log_Area_Ratios( LARc, LARpp_j ); | |
280 | |
281 Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); | |
282 LARp_to_rp( LARp ); | |
283 FILTER( S, LARp, 13, s); | |
284 | |
285 Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); | |
286 LARp_to_rp( LARp ); | |
287 FILTER( S, LARp, 14, s + 13); | |
288 | |
289 Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); | |
290 LARp_to_rp( LARp ); | |
291 FILTER( S, LARp, 13, s + 27); | |
292 | |
293 Coefficients_40_159( LARpp_j, LARp); | |
294 LARp_to_rp( LARp ); | |
295 FILTER( S, LARp, 120, s + 40); | |
296 } | |
297 | |
298 void Gsm_Short_Term_Synthesis_Filter ( | |
299 struct gsmfr_0610_state * S, | |
300 | |
301 const word * LARcr, /* received log area ratios [0..7] IN */ | |
302 word * wt, /* received d [0..159] IN */ | |
303 | |
304 word * s /* signal s [0..159] OUT */ | |
305 ) | |
306 { | |
307 word * LARpp_j = S->LARpp[ S->j ]; | |
308 word * LARpp_j_1 = S->LARpp[ S->j ^=1 ]; | |
309 | |
310 word LARp[8]; | |
311 | |
312 #undef FILTER | |
313 # define FILTER Short_term_synthesis_filtering | |
314 | |
315 Decoding_of_the_coded_Log_Area_Ratios( LARcr, LARpp_j ); | |
316 | |
317 Coefficients_0_12( LARpp_j_1, LARpp_j, LARp ); | |
318 LARp_to_rp( LARp ); | |
319 FILTER( S, LARp, 13, wt, s ); | |
320 | |
321 Coefficients_13_26( LARpp_j_1, LARpp_j, LARp); | |
322 LARp_to_rp( LARp ); | |
323 FILTER( S, LARp, 14, wt + 13, s + 13 ); | |
324 | |
325 Coefficients_27_39( LARpp_j_1, LARpp_j, LARp); | |
326 LARp_to_rp( LARp ); | |
327 FILTER( S, LARp, 13, wt + 27, s + 27 ); | |
328 | |
329 Coefficients_40_159( LARpp_j, LARp ); | |
330 LARp_to_rp( LARp ); | |
331 FILTER(S, LARp, 120, wt + 40, s + 40); | |
332 } |