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