File: | gsm0610_short_term.c |
Warning: | line 79, column 5 The result of the left shift is undefined because the left operand is negative |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* | |||||
2 | * SpanDSP - a series of DSP components for telephony | |||||
3 | * | |||||
4 | * gsm0610_short_term.c - GSM 06.10 full rate speech codec. | |||||
5 | * | |||||
6 | * Written by Steve Underwood <steveu@coppice.org> | |||||
7 | * | |||||
8 | * Copyright (C) 2006 Steve Underwood | |||||
9 | * | |||||
10 | * All rights reserved. | |||||
11 | * | |||||
12 | * This program is free software; you can redistribute it and/or modify | |||||
13 | * it under the terms of the GNU Lesser General Public License version 2.1, | |||||
14 | * as published by the Free Software Foundation. | |||||
15 | * | |||||
16 | * This program is distributed in the hope that it will be useful, | |||||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
19 | * GNU Lesser General Public License for more details. | |||||
20 | * | |||||
21 | * You should have received a copy of the GNU Lesser General Public | |||||
22 | * License along with this program; if not, write to the Free Software | |||||
23 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |||||
24 | * | |||||
25 | * This code is based on the widely used GSM 06.10 code available from | |||||
26 | * http://kbs.cs.tu-berlin.de/~jutta/toast.html | |||||
27 | */ | |||||
28 | ||||||
29 | /*! \file */ | |||||
30 | ||||||
31 | #if defined(HAVE_CONFIG_H1) | |||||
32 | #include "config.h" | |||||
33 | #endif | |||||
34 | ||||||
35 | #include <assert.h> | |||||
36 | #include <inttypes.h> | |||||
37 | #if defined(HAVE_TGMATH_H1) | |||||
38 | #include <tgmath.h> | |||||
39 | #endif | |||||
40 | #if defined(HAVE_MATH_H1) | |||||
41 | #include <math.h> | |||||
42 | #endif | |||||
43 | #include "floating_fudge.h" | |||||
44 | #include <stdlib.h> | |||||
45 | ||||||
46 | #include "spandsp/telephony.h" | |||||
47 | #include "spandsp/fast_convert.h" | |||||
48 | #include "spandsp/bitstream.h" | |||||
49 | #include "spandsp/saturated.h" | |||||
50 | #include "spandsp/gsm0610.h" | |||||
51 | ||||||
52 | #include "gsm0610_local.h" | |||||
53 | ||||||
54 | /* SHORT TERM ANALYSIS FILTERING SECTION */ | |||||
55 | ||||||
56 | /* 4.2.8 */ | |||||
57 | static void decode_log_area_ratios(int16_t LARc[8], int16_t *LARpp) | |||||
58 | { | |||||
59 | int16_t temp1; | |||||
60 | ||||||
61 | /* This procedure requires for efficient implementation | |||||
62 | two tables. | |||||
63 | INVA[1..8] = integer((32768*8)/real_A[1..8]) | |||||
64 | MIC[1..8] = minimum value of the LARc[1..8] | |||||
65 | */ | |||||
66 | ||||||
67 | /* Compute the LARpp[1..8] */ | |||||
68 | ||||||
69 | #undef STEP | |||||
70 | #define STEP(B,MIC,INVA)temp1 = sat_add16(*LARc++, MIC) << 10; temp1 = sat_sub16 (temp1, B << 1); temp1 = gsm_mult_r(INVA, temp1); *LARpp ++ = sat_add16(temp1, temp1); \ | |||||
71 | temp1 = sat_add16(*LARc++, MIC) << 10; \ | |||||
72 | temp1 = sat_sub16(temp1, B << 1); \ | |||||
73 | temp1 = gsm_mult_r(INVA, temp1); \ | |||||
74 | *LARpp++ = sat_add16(temp1, temp1); | |||||
75 | ||||||
76 | STEP( 0, -32, 13107)temp1 = sat_add16(*LARc++, -32) << 10; temp1 = sat_sub16 (temp1, 0 << 1); temp1 = gsm_mult_r(13107, temp1); *LARpp ++ = sat_add16(temp1, temp1);; | |||||
77 | STEP( 0, -32, 13107)temp1 = sat_add16(*LARc++, -32) << 10; temp1 = sat_sub16 (temp1, 0 << 1); temp1 = gsm_mult_r(13107, temp1); *LARpp ++ = sat_add16(temp1, temp1);; | |||||
78 | STEP( 2048, -16, 13107)temp1 = sat_add16(*LARc++, -16) << 10; temp1 = sat_sub16 (temp1, 2048 << 1); temp1 = gsm_mult_r(13107, temp1); * LARpp++ = sat_add16(temp1, temp1);; | |||||
79 | STEP(-2560, -16, 13107)temp1 = sat_add16(*LARc++, -16) << 10; temp1 = sat_sub16 (temp1, -2560 << 1); temp1 = gsm_mult_r(13107, temp1); * LARpp++ = sat_add16(temp1, temp1);; | |||||
| ||||||
80 | ||||||
81 | STEP( 94, -8, 19223)temp1 = sat_add16(*LARc++, -8) << 10; temp1 = sat_sub16 (temp1, 94 << 1); temp1 = gsm_mult_r(19223, temp1); *LARpp ++ = sat_add16(temp1, temp1);; | |||||
82 | STEP(-1792, -8, 17476)temp1 = sat_add16(*LARc++, -8) << 10; temp1 = sat_sub16 (temp1, -1792 << 1); temp1 = gsm_mult_r(17476, temp1); * LARpp++ = sat_add16(temp1, temp1);; | |||||
83 | STEP( -341, -4, 31454)temp1 = sat_add16(*LARc++, -4) << 10; temp1 = sat_sub16 (temp1, -341 << 1); temp1 = gsm_mult_r(31454, temp1); * LARpp++ = sat_add16(temp1, temp1);; | |||||
84 | STEP(-1144, -4, 29708)temp1 = sat_add16(*LARc++, -4) << 10; temp1 = sat_sub16 (temp1, -1144 << 1); temp1 = gsm_mult_r(29708, temp1); * LARpp++ = sat_add16(temp1, temp1);; | |||||
85 | ||||||
86 | /* NOTE: the addition of *MIC is used to restore the sign of *LARc. */ | |||||
87 | } | |||||
88 | /*- End of function --------------------------------------------------------*/ | |||||
89 | ||||||
90 | /* 4.2.9 */ | |||||
91 | ||||||
92 | /* Computation of the quantized reflection coefficients */ | |||||
93 | ||||||
94 | /* 4.2.9.1 Interpolation of the LARpp[1..8] to get the LARp[1..8] */ | |||||
95 | ||||||
96 | /* Within each frame of 160 analyzed speech samples the short term | |||||
97 | analysis and synthesis filters operate with four different sets of | |||||
98 | coefficients, derived from the previous set of decoded LARs(LARpp(j - 1)) | |||||
99 | and the actual set of decoded LARs (LARpp(j)) | |||||
100 | ||||||
101 | (Initial value: LARpp(j - 1)[1..8] = 0.) | |||||
102 | */ | |||||
103 | ||||||
104 | static void coefficients_0_12(int16_t *LARpp_j_1, | |||||
105 | int16_t *LARpp_j, | |||||
106 | int16_t *LARp) | |||||
107 | { | |||||
108 | int i; | |||||
109 | ||||||
110 | for (i = 1; i <= 8; i++, LARp++, LARpp_j_1++, LARpp_j++) | |||||
111 | { | |||||
112 | *LARp = sat_add16(*LARpp_j_1 >> 2, *LARpp_j >> 2); | |||||
113 | *LARp = sat_add16(*LARp, *LARpp_j_1 >> 1); | |||||
114 | } | |||||
115 | /*endfor*/ | |||||
116 | } | |||||
117 | /*- End of function --------------------------------------------------------*/ | |||||
118 | ||||||
119 | static void coefficients_13_26(int16_t *LARpp_j_1, | |||||
120 | int16_t *LARpp_j, | |||||
121 | int16_t *LARp) | |||||
122 | { | |||||
123 | int i; | |||||
124 | ||||||
125 | for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) | |||||
126 | *LARp = sat_add16(*LARpp_j_1 >> 1, *LARpp_j >> 1); | |||||
127 | /*endfor*/ | |||||
128 | } | |||||
129 | /*- End of function --------------------------------------------------------*/ | |||||
130 | ||||||
131 | static void coefficients_27_39(int16_t *LARpp_j_1, | |||||
132 | int16_t *LARpp_j, | |||||
133 | int16_t *LARp) | |||||
134 | { | |||||
135 | int i; | |||||
136 | ||||||
137 | for (i = 1; i <= 8; i++, LARpp_j_1++, LARpp_j++, LARp++) | |||||
138 | { | |||||
139 | *LARp = sat_add16(*LARpp_j_1 >> 2, *LARpp_j >> 2); | |||||
140 | *LARp = sat_add16(*LARp, *LARpp_j >> 1); | |||||
141 | } | |||||
142 | /*endfor*/ | |||||
143 | } | |||||
144 | /*- End of function --------------------------------------------------------*/ | |||||
145 | ||||||
146 | static void coefficients_40_159(int16_t *LARpp_j, int16_t *LARp) | |||||
147 | { | |||||
148 | int i; | |||||
149 | ||||||
150 | for (i = 1; i <= 8; i++) | |||||
151 | *LARp++ = *LARpp_j++; | |||||
152 | /*endfor*/ | |||||
153 | } | |||||
154 | /*- End of function --------------------------------------------------------*/ | |||||
155 | ||||||
156 | /* 4.2.9.2 */ | |||||
157 | static void larp_to_rp(int16_t LARp[8]) | |||||
158 | { | |||||
159 | int i; | |||||
160 | int16_t *LARpx; | |||||
161 | int16_t temp; | |||||
162 | ||||||
163 | /* The input to this procedure is the interpolated LARp[0..7] array. | |||||
164 | The reflection coefficients, rp[i], are used in the analysis | |||||
165 | filter and in the synthesis filter. | |||||
166 | */ | |||||
167 | ||||||
168 | LARpx = LARp; | |||||
169 | for (i = 1; i <= 8; i++, LARpx++) | |||||
170 | { | |||||
171 | temp = *LARpx; | |||||
172 | if (temp < 0) | |||||
173 | { | |||||
174 | if (temp == INT16_MIN(-32767-1)) | |||||
175 | temp = INT16_MAX(32767); | |||||
176 | else | |||||
177 | temp = -temp; | |||||
178 | /*endif*/ | |||||
179 | if (temp < 11059) | |||||
180 | temp <<= 1; | |||||
181 | else if (temp < 20070) | |||||
182 | temp += 11059; | |||||
183 | else | |||||
184 | temp = sat_add16(temp >> 2, 26112); | |||||
185 | /*endif*/ | |||||
186 | *LARpx = -temp; | |||||
187 | } | |||||
188 | else | |||||
189 | { | |||||
190 | if (temp < 11059) | |||||
191 | temp <<= 1; | |||||
192 | else if (temp < 20070) | |||||
193 | temp += 11059; | |||||
194 | else | |||||
195 | temp = sat_add16(temp >> 2, 26112); | |||||
196 | /*endif*/ | |||||
197 | *LARpx = temp; | |||||
198 | } | |||||
199 | /*endif*/ | |||||
200 | } | |||||
201 | /*endfor*/ | |||||
202 | } | |||||
203 | /*- End of function --------------------------------------------------------*/ | |||||
204 | ||||||
205 | /* 4.2.10 */ | |||||
206 | static void short_term_analysis_filtering(gsm0610_state_t *s, | |||||
207 | int16_t rp[8], | |||||
208 | int k_n, // k_end - k_start | |||||
209 | int16_t amp[]) // [0..n-1] IN/OUT | |||||
210 | { | |||||
211 | /* This procedure computes the short term residual signal d[..] to be fed | |||||
212 | to the RPE-LTP loop from the s[..] signal and from the local rp[..] | |||||
213 | array (quantized reflection coefficients). As the call of this | |||||
214 | procedure can be done in many ways (see the interpolation of the LAR | |||||
215 | coefficient), it is assumed that the computation begins with index | |||||
216 | k_start (for arrays d[..] and s[..]) and stops with index k_end | |||||
217 | (k_start and k_end are defined in 4.2.9.1). This procedure also | |||||
218 | needs to keep the array u[0..7] in memory for each call. | |||||
219 | */ | |||||
220 | int16_t *u0; | |||||
221 | int16_t *u_top; | |||||
222 | int i; | |||||
223 | int16_t *u; | |||||
224 | int16_t *rpx; | |||||
225 | int32_t di; | |||||
226 | int32_t u_out; | |||||
227 | ||||||
228 | u0 = s->u; | |||||
229 | u_top = u0 + 8; | |||||
230 | ||||||
231 | for (i = 0; i < k_n; i++) | |||||
232 | { | |||||
233 | di = | |||||
234 | u_out = amp[i]; | |||||
235 | for (rpx = rp, u = u0; u < u_top; ) | |||||
236 | { | |||||
237 | int32_t ui; | |||||
238 | int32_t rpi; | |||||
239 | ||||||
240 | ui = *u; | |||||
241 | *u++ = (int16_t) u_out; | |||||
242 | rpi = *rpx++; | |||||
243 | u_out = ui + (((rpi*di) + 0x4000) >> 15); | |||||
244 | di = di + (((rpi*ui) + 0x4000) >> 15); | |||||
245 | u_out = saturate16(u_out); | |||||
246 | di = saturate16(di); | |||||
247 | } | |||||
248 | /*endfor*/ | |||||
249 | amp[i] = (int16_t) di; | |||||
250 | } | |||||
251 | /*endfor*/ | |||||
252 | } | |||||
253 | /*- End of function --------------------------------------------------------*/ | |||||
254 | ||||||
255 | static void short_term_synthesis_filtering(gsm0610_state_t *s, | |||||
256 | int16_t rrp[8], | |||||
257 | int k, // k_end - k_start | |||||
258 | int16_t *wt, // [0..k - 1] | |||||
259 | int16_t *sr) // [0..k - 1] | |||||
260 | { | |||||
261 | int16_t *v; | |||||
262 | int i; | |||||
263 | int16_t sri; | |||||
264 | int16_t tmp1; | |||||
265 | int16_t tmp2; | |||||
266 | ||||||
267 | v = s->v; | |||||
268 | while (k--) | |||||
269 | { | |||||
270 | sri = *wt++; | |||||
271 | for (i = 8; i--; ) | |||||
272 | { | |||||
273 | tmp1 = rrp[i]; | |||||
274 | tmp2 = v[i]; | |||||
275 | tmp2 = ((tmp1 == INT16_MIN(-32767-1) && tmp2 == INT16_MIN(-32767-1)) | |||||
276 | ? | |||||
277 | INT16_MAX(32767) | |||||
278 | : | |||||
279 | (int16_t) (((int32_t) tmp1*(int32_t) tmp2 + 16384) >> 15) & 0xFFFF); | |||||
280 | ||||||
281 | sri = sat_sub16(sri, tmp2); | |||||
282 | ||||||
283 | tmp1 = ((tmp1 == INT16_MIN(-32767-1) && sri == INT16_MIN(-32767-1)) | |||||
284 | ? | |||||
285 | INT16_MAX(32767) | |||||
286 | : | |||||
287 | (int16_t) (((int32_t) tmp1*(int32_t) sri + 16384) >> 15) & 0xFFFF); | |||||
288 | ||||||
289 | v[i + 1] = sat_add16(v[i], tmp1); | |||||
290 | } | |||||
291 | /*endfor*/ | |||||
292 | *sr++ = | |||||
293 | v[0] = sri; | |||||
294 | } | |||||
295 | /*endwhile*/ | |||||
296 | } | |||||
297 | /*- End of function --------------------------------------------------------*/ | |||||
298 | ||||||
299 | void gsm0610_short_term_analysis_filter(gsm0610_state_t *s, | |||||
300 | int16_t LARc[8], | |||||
301 | int16_t amp[GSM0610_FRAME_LEN160]) | |||||
302 | { | |||||
303 | int16_t *LARpp_j; | |||||
304 | int16_t *LARpp_j_1; | |||||
305 | int16_t LARp[8]; | |||||
306 | ||||||
307 | LARpp_j = s->LARpp[s->j]; | |||||
308 | LARpp_j_1 = s->LARpp[s->j ^= 1]; | |||||
309 | ||||||
310 | decode_log_area_ratios(LARc, LARpp_j); | |||||
311 | ||||||
312 | coefficients_0_12(LARpp_j_1, LARpp_j, LARp); | |||||
313 | larp_to_rp(LARp); | |||||
314 | short_term_analysis_filtering(s, LARp, 13, amp); | |||||
315 | ||||||
316 | coefficients_13_26(LARpp_j_1, LARpp_j, LARp); | |||||
317 | larp_to_rp(LARp); | |||||
318 | short_term_analysis_filtering(s, LARp, 14, amp + 13); | |||||
319 | ||||||
320 | coefficients_27_39(LARpp_j_1, LARpp_j, LARp); | |||||
321 | larp_to_rp(LARp); | |||||
322 | short_term_analysis_filtering(s, LARp, 13, amp + 27); | |||||
323 | ||||||
324 | coefficients_40_159(LARpp_j, LARp); | |||||
325 | larp_to_rp(LARp); | |||||
326 | short_term_analysis_filtering(s, LARp, 120, amp + 40); | |||||
327 | } | |||||
328 | /*- End of function --------------------------------------------------------*/ | |||||
329 | ||||||
330 | void gsm0610_short_term_synthesis_filter(gsm0610_state_t *s, | |||||
331 | int16_t LARcr[8], | |||||
332 | int16_t wt[GSM0610_FRAME_LEN160], | |||||
333 | int16_t amp[GSM0610_FRAME_LEN160]) | |||||
334 | { | |||||
335 | int16_t *LARpp_j; | |||||
336 | int16_t *LARpp_j_1; | |||||
337 | int16_t LARp[8]; | |||||
338 | ||||||
339 | LARpp_j = s->LARpp[s->j]; | |||||
340 | LARpp_j_1 = s->LARpp[s->j ^= 1]; | |||||
341 | ||||||
342 | decode_log_area_ratios(LARcr, LARpp_j); | |||||
| ||||||
343 | ||||||
344 | coefficients_0_12(LARpp_j_1, LARpp_j, LARp); | |||||
345 | larp_to_rp(LARp); | |||||
346 | short_term_synthesis_filtering(s, LARp, 13, wt, amp); | |||||
347 | ||||||
348 | coefficients_13_26(LARpp_j_1, LARpp_j, LARp); | |||||
349 | larp_to_rp(LARp); | |||||
350 | short_term_synthesis_filtering(s, LARp, 14, wt + 13, amp + 13); | |||||
351 | ||||||
352 | coefficients_27_39(LARpp_j_1, LARpp_j, LARp); | |||||
353 | larp_to_rp(LARp); | |||||
354 | short_term_synthesis_filtering(s, LARp, 13, wt + 27, amp + 27); | |||||
355 | ||||||
356 | coefficients_40_159(LARpp_j, LARp); | |||||
357 | larp_to_rp(LARp); | |||||
358 | short_term_synthesis_filtering(s, LARp, 120, wt + 40, amp + 40); | |||||
359 | } | |||||
360 | /*- End of function --------------------------------------------------------*/ | |||||
361 | /*- End of file ------------------------------------------------------------*/ |