comparison spandsp-0.0.6pre17/src/gsm0610_lpc.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * gsm0610_lpc.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 * $Id: gsm0610_lpc.c,v 1.29 2009/02/05 15:57:27 steveu Exp $
29 */
30
31 /*! \file */
32
33 #if defined(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 "floating_fudge.h"
46 #include <stdlib.h>
47 #include <memory.h>
48
49 #include "spandsp/telephony.h"
50 #include "spandsp/fast_convert.h"
51 #include "spandsp/bitstream.h"
52 #include "spandsp/bit_operations.h"
53 #include "spandsp/saturated.h"
54 #include "spandsp/vector_int.h"
55 #include "spandsp/gsm0610.h"
56
57 #include "gsm0610_local.h"
58
59 /* 4.2.4 .. 4.2.7 LPC ANALYSIS SECTION */
60
61 /* The number of left shifts needed to normalize the 32 bit
62 variable x for positive values on the interval
63 with minimum of
64 minimum of 1073741824 (01000000000000000000000000000000) and
65 maximum of 2147483647 (01111111111111111111111111111111)
66 and for negative values on the interval with
67 minimum of -2147483648 (-10000000000000000000000000000000) and
68 maximum of -1073741824 ( -1000000000000000000000000000000).
69
70 In order to normalize the result, the following
71 operation must be done: norm_var1 = x << gsm0610_norm(x);
72
73 (That's 'ffs', only from the left, not the right..)
74 */
75
76 int16_t gsm0610_norm(int32_t x)
77 {
78 assert(x != 0);
79
80 if (x < 0)
81 {
82 if (x <= -1073741824)
83 return 0;
84 /*endif*/
85 x = ~x;
86 }
87 /*endif*/
88 return (int16_t) (30 - top_bit(x));
89 }
90 /*- End of function --------------------------------------------------------*/
91
92 /*
93 (From p. 46, end of section 4.2.5)
94
95 NOTE: The following lines gives [sic] one correct implementation
96 of the div(num, denum) arithmetic operation. Compute div
97 which is the integer division of num by denom: with
98 denom >= num > 0
99 */
100 static int16_t gsm_div(int16_t num, int16_t denom)
101 {
102 int32_t num32;
103 int32_t denom32;
104 int16_t div;
105 int k;
106
107 /* The parameter num sometimes becomes zero.
108 Although this is explicitly guarded against in 4.2.5,
109 we assume that the result should then be zero as well. */
110
111 assert(num >= 0 && denom >= num);
112 if (num == 0)
113 return 0;
114 /*endif*/
115 num32 = num;
116 denom32 = denom;
117 div = 0;
118 k = 15;
119 while (k--)
120 {
121 div <<= 1;
122 num32 <<= 1;
123
124 if (num32 >= denom32)
125 {
126 num32 -= denom32;
127 div++;
128 }
129 /*endif*/
130 }
131 /*endwhile*/
132
133 return div;
134 }
135 /*- End of function --------------------------------------------------------*/
136
137 #if defined(__GNUC__) && defined(SPANDSP_USE_MMX)
138 static void gsm0610_vec_vsraw(const int16_t *p, int n, int bits)
139 {
140 static const int64_t ones = 0x0001000100010001LL;
141
142 if (n == 0)
143 return;
144 /*endif*/
145 #if defined(__x86_64__)
146 __asm__ __volatile__(
147 " leaq -16(%%rsi,%%rax,2),%%rdx;\n" /* edx = top - 16 */
148 " emms;\n"
149 " movd %%ecx,%%mm3;\n"
150 " movq %[ones],%%mm2;\n"
151 " psllw %%mm3,%%mm2;\n"
152 " psrlw $1,%%mm2;\n"
153 " cmpq %%rdx,%%rsi;"
154 " ja 4f;\n"
155
156 " .p2align 2;\n"
157 /* 8 words per iteration */
158 "6:\n"
159 " movq (%%rsi),%%mm0;\n"
160 " movq 8(%%rsi),%%mm1;\n"
161 " paddsw %%mm2,%%mm0;\n"
162 " psraw %%mm3,%%mm0;\n"
163 " paddsw %%mm2,%%mm1;\n"
164 " psraw %%mm3,%%mm1;\n"
165 " movq %%mm0,(%%rsi);\n"
166 " movq %%mm1,8(%%rsi);\n"
167 " addq $16,%%rsi;\n"
168 " cmpq %%rdx,%%rsi;\n"
169 " jbe 6b;\n"
170
171 " .p2align 2;\n"
172 "4:\n"
173 " addq $12,%%rdx;\n" /* now edx = top-4 */
174 " cmpq %%rdx,%%rsi;\n"
175 " ja 3f;\n"
176
177 " .p2align 2;\n"
178 /* do up to 6 words, two per iteration */
179 "5:\n"
180 " movd (%%rsi),%%mm0;\n"
181 " paddsw %%mm2,%%mm0;\n"
182 " psraw %%mm3,%%mm0;\n"
183 " movd %%mm0,(%%rsi);\n"
184 " addq $4,%%rsi;\n"
185 " cmpq %%rdx,%%rsi;\n"
186 " jbe 5b;\n"
187
188 " .p2align 2;\n"
189 "3:\n"
190 " addq $2,%%rdx;\n" /* now edx = top-2 */
191 " cmpq %%rdx,%%rsi;\n"
192 " ja 2f;\n"
193
194 " movzwl (%%rsi),%%eax;\n"
195 " movd %%eax,%%mm0;\n"
196 " paddsw %%mm2,%%mm0;\n"
197 " psraw %%mm3,%%mm0;\n"
198 " movd %%mm0,%%eax;\n"
199 " movw %%ax,(%%rsi);\n"
200
201 " .p2align 2;\n"
202 "2:\n"
203 " emms;\n"
204 :
205 : "S" (p), "a" (n), "c" (bits), [ones] "m" (ones)
206 : "edx"
207 );
208 #else
209 __asm__ __volatile__(
210 " leal -16(%%esi,%%eax,2),%%edx;\n" /* edx = top - 16 */
211 " emms;\n"
212 " movd %%ecx,%%mm3;\n"
213 " movq %[ones],%%mm2;\n"
214 " psllw %%mm3,%%mm2;\n"
215 " psrlw $1,%%mm2;\n"
216 " cmpl %%edx,%%esi;"
217 " ja 4f;\n"
218
219 " .p2align 2;\n"
220 /* 8 words per iteration */
221 "6:\n"
222 " movq (%%esi),%%mm0;\n"
223 " movq 8(%%esi),%%mm1;\n"
224 " paddsw %%mm2,%%mm0;\n"
225 " psraw %%mm3,%%mm0;\n"
226 " paddsw %%mm2,%%mm1;\n"
227 " psraw %%mm3,%%mm1;\n"
228 " movq %%mm0,(%%esi);\n"
229 " movq %%mm1,8(%%esi);\n"
230 " addl $16,%%esi;\n"
231 " cmpl %%edx,%%esi;\n"
232 " jbe 6b;\n"
233
234 " .p2align 2;\n"
235 "4:\n"
236 " addl $12,%%edx;\n" /* now edx = top-4 */
237 " cmpl %%edx,%%esi;\n"
238 " ja 3f;\n"
239
240 " .p2align 2;\n"
241 /* do up to 6 words, two per iteration */
242 "5:\n"
243 " movd (%%esi),%%mm0;\n"
244 " paddsw %%mm2,%%mm0;\n"
245 " psraw %%mm3,%%mm0;\n"
246 " movd %%mm0,(%%esi);\n"
247 " addl $4,%%esi;\n"
248 " cmpl %%edx,%%esi;\n"
249 " jbe 5b;\n"
250
251 " .p2align 2;\n"
252 "3:\n"
253 " addl $2,%%edx;\n" /* now edx = top-2 */
254 " cmpl %%edx,%%esi;\n"
255 " ja 2f;\n"
256
257 " movzwl (%%esi),%%eax;\n"
258 " movd %%eax,%%mm0;\n"
259 " paddsw %%mm2,%%mm0;\n"
260 " psraw %%mm3,%%mm0;\n"
261 " movd %%mm0,%%eax;\n"
262 " movw %%ax,(%%esi);\n"
263
264 " .p2align 2;\n"
265 "2:\n"
266 " emms;\n"
267 :
268 : "S" (p), "a" (n), "c" (bits), [ones] "m" (ones)
269 : "edx"
270 );
271 #endif
272 }
273 /*- End of function --------------------------------------------------------*/
274 #endif
275
276 /* 4.2.4 */
277 static void autocorrelation(int16_t amp[GSM0610_FRAME_LEN], int32_t L_ACF[9])
278 {
279 int k;
280 int16_t smax;
281 int16_t scalauto;
282 #if !(defined(__GNUC__) && defined(SPANDSP_USE_MMX))
283 int i;
284 int temp;
285 int16_t *sp;
286 int16_t sl;
287 #endif
288
289 /* The goal is to compute the array L_ACF[k]. The signal s[i] must
290 be scaled in order to avoid an overflow situation. */
291
292 /* Dynamic scaling of the array s[0..159] */
293 /* Search for the maximum. */
294 #if defined(__GNUC__) && defined(SPANDSP_USE_MMX)
295 smax = saturate(vec_min_maxi16(amp, GSM0610_FRAME_LEN, NULL));
296 #else
297 for (smax = 0, k = 0; k < GSM0610_FRAME_LEN; k++)
298 {
299 temp = saturated_abs16(amp[k]);
300 if (temp > smax)
301 smax = (int16_t) temp;
302 /*endif*/
303 }
304 /*endfor*/
305 #endif
306
307 /* Computation of the scaling factor. */
308 if (smax == 0)
309 {
310 scalauto = 0;
311 }
312 else
313 {
314 assert(smax > 0);
315 scalauto = (int16_t) (4 - gsm0610_norm((int32_t) smax << 16));
316 }
317 /*endif*/
318
319 /* Scaling of the array s[0...159] */
320 #if defined(__GNUC__) && defined(SPANDSP_USE_MMX)
321 if (scalauto > 0)
322 gsm0610_vec_vsraw(amp, GSM0610_FRAME_LEN, scalauto);
323 /*endif*/
324 #else
325 if (scalauto > 0)
326 {
327 for (k = 0; k < GSM0610_FRAME_LEN; k++)
328 amp[k] = gsm_mult_r(amp[k], 16384 >> (scalauto - 1));
329 /*endfor*/
330 }
331 /*endif*/
332 #endif
333
334 /* Compute the L_ACF[..]. */
335 #if defined(__GNUC__) && defined(SPANDSP_USE_MMX)
336 for (k = 0; k < 9; k++)
337 L_ACF[k] = vec_dot_prodi16(amp, amp + k, GSM0610_FRAME_LEN - k) << 1;
338 /*endfor*/
339 #else
340 sp = amp;
341 sl = *sp;
342 L_ACF[0] = ((int32_t) sl*(int32_t) sp[0]);
343 sl = *++sp;
344 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
345 L_ACF[1] = ((int32_t) sl*(int32_t) sp[-1]);
346 sl = *++sp;
347 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
348 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
349 L_ACF[2] = ((int32_t) sl*(int32_t) sp[-2]);
350 sl = *++sp;
351 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
352 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
353 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
354 L_ACF[3] = ((int32_t) sl*(int32_t) sp[-3]);
355 sl = *++sp;
356 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
357 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
358 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
359 L_ACF[3] += ((int32_t) sl*(int32_t) sp[-3]);
360 L_ACF[4] = ((int32_t) sl*(int32_t) sp[-4]);
361 sl = *++sp;
362 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
363 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
364 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
365 L_ACF[3] += ((int32_t) sl*(int32_t) sp[-3]);
366 L_ACF[4] += ((int32_t) sl*(int32_t) sp[-4]);
367 L_ACF[5] = ((int32_t) sl*(int32_t) sp[-5]);
368 sl = *++sp;
369 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
370 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
371 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
372 L_ACF[3] += ((int32_t) sl*(int32_t) sp[-3]);
373 L_ACF[4] += ((int32_t) sl*(int32_t) sp[-4]);
374 L_ACF[5] += ((int32_t) sl*(int32_t) sp[-5]);
375 L_ACF[6] = ((int32_t) sl*(int32_t) sp[-6]);
376 sl = *++sp;
377 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
378 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
379 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
380 L_ACF[3] += ((int32_t) sl*(int32_t) sp[-3]);
381 L_ACF[4] += ((int32_t) sl*(int32_t) sp[-4]);
382 L_ACF[5] += ((int32_t) sl*(int32_t) sp[-5]);
383 L_ACF[6] += ((int32_t) sl*(int32_t) sp[-6]);
384 L_ACF[7] = ((int32_t) sl*(int32_t) sp[-7]);
385 sl = *++sp;
386 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
387 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
388 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
389 L_ACF[3] += ((int32_t) sl*(int32_t) sp[-3]);
390 L_ACF[4] += ((int32_t) sl*(int32_t) sp[-4]);
391 L_ACF[5] += ((int32_t) sl*(int32_t) sp[-5]);
392 L_ACF[6] += ((int32_t) sl*(int32_t) sp[-6]);
393 L_ACF[7] += ((int32_t) sl*(int32_t) sp[-7]);
394 L_ACF[8] = ((int32_t) sl*(int32_t) sp[-8]);
395 for (i = 9; i < GSM0610_FRAME_LEN; i++)
396 {
397 sl = *++sp;
398 L_ACF[0] += ((int32_t) sl*(int32_t) sp[0]);
399 L_ACF[1] += ((int32_t) sl*(int32_t) sp[-1]);
400 L_ACF[2] += ((int32_t) sl*(int32_t) sp[-2]);
401 L_ACF[3] += ((int32_t) sl*(int32_t) sp[-3]);
402 L_ACF[4] += ((int32_t) sl*(int32_t) sp[-4]);
403 L_ACF[5] += ((int32_t) sl*(int32_t) sp[-5]);
404 L_ACF[6] += ((int32_t) sl*(int32_t) sp[-6]);
405 L_ACF[7] += ((int32_t) sl*(int32_t) sp[-7]);
406 L_ACF[8] += ((int32_t) sl*(int32_t) sp[-8]);
407 }
408 /*endfor*/
409 for (k = 0; k < 9; k++)
410 L_ACF[k] <<= 1;
411 /*endfor*/
412 #endif
413 /* Rescaling of the array s[0..159] */
414 if (scalauto > 0)
415 {
416 assert(scalauto <= 4);
417 for (k = 0; k < GSM0610_FRAME_LEN; k++)
418 amp[k] <<= scalauto;
419 /*endfor*/
420 }
421 /*endif*/
422 }
423 /*- End of function --------------------------------------------------------*/
424
425 /* 4.2.5 */
426 static void reflection_coefficients(int32_t L_ACF[9], int16_t r[8])
427 {
428 int i;
429 int m;
430 int n;
431 int16_t temp;
432 int16_t ACF[9];
433 int16_t P[9];
434 int16_t K[9];
435
436 /* Schur recursion with 16 bits arithmetic. */
437 if (L_ACF[0] == 0)
438 {
439 for (i = 8; i--; *r++ = 0)
440 ;
441 /*endfor*/
442 return;
443 }
444 /*endif*/
445
446 assert(L_ACF[0] != 0);
447 temp = gsm0610_norm(L_ACF[0]);
448
449 assert(temp >= 0 && temp < 32);
450
451 /* ? overflow ? */
452 for (i = 0; i <= 8; i++)
453 ACF[i] = (int16_t) ((L_ACF[i] << temp) >> 16);
454 /*endfor*/
455
456 /* Initialize array P[..] and K[..] for the recursion. */
457 for (i = 1; i <= 7; i++)
458 K[i] = ACF[i];
459 /*endfor*/
460 for (i = 0; i <= 8; i++)
461 P[i] = ACF[i];
462 /*endfor*/
463 /* Compute reflection coefficients */
464 for (n = 1; n <= 8; n++, r++)
465 {
466 temp = P[1];
467 temp = saturated_abs16(temp);
468 if (P[0] < temp)
469 {
470 for (i = n; i <= 8; i++)
471 *r++ = 0;
472 /*endfor*/
473 return;
474 }
475 /*endif*/
476
477 *r = gsm_div(temp, P[0]);
478
479 assert(*r >= 0);
480 if (P[1] > 0)
481 *r = -*r; /* r[n] = sub(0, r[n]) */
482 /*endif*/
483 assert(*r != INT16_MIN);
484 if (n == 8)
485 return;
486 /*endif*/
487
488 /* Schur recursion */
489 temp = gsm_mult_r(P[1], *r);
490 P[0] = saturated_add16(P[0], temp);
491
492 for (m = 1; m <= 8 - n; m++)
493 {
494 temp = gsm_mult_r(K[m], *r);
495 P[m] = saturated_add16(P[m + 1], temp);
496
497 temp = gsm_mult_r(P[m + 1], *r);
498 K[m] = saturated_add16(K[m], temp);
499 }
500 /*endfor*/
501 }
502 /*endfor*/
503 }
504 /*- End of function --------------------------------------------------------*/
505
506 /* 4.2.6 */
507 static void transform_to_log_area_ratios(int16_t r[8])
508 {
509 int16_t temp;
510 int i;
511
512 /* The following scaling for r[..] and LAR[..] has been used:
513
514 r[..] = integer (real_r[..]*32768.); -1 <= real_r < 1.
515 LAR[..] = integer (real_LAR[..] * 16384);
516 with -1.625 <= real_LAR <= 1.625
517 */
518
519 /* Computation of the LAR[0..7] from the r[0..7] */
520 for (i = 1; i <= 8; i++, r++)
521 {
522 temp = saturated_abs16(*r);
523 assert(temp >= 0);
524
525 if (temp < 22118)
526 {
527 temp >>= 1;
528 }
529 else if (temp < 31130)
530 {
531 assert(temp >= 11059);
532 temp -= 11059;
533 }
534 else
535 {
536 assert(temp >= 26112);
537 temp -= 26112;
538 temp <<= 2;
539 }
540 /*endif*/
541
542 *r = (*r < 0) ? -temp : temp;
543 assert(*r != INT16_MIN);
544 }
545 /*endfor*/
546 }
547 /*- End of function --------------------------------------------------------*/
548
549 /* 4.2.7 */
550 static void quantization_and_coding(int16_t LAR[8])
551 {
552 int16_t temp;
553
554 /* This procedure needs four tables; the following equations
555 give the optimum scaling for the constants:
556
557 A[0..7] = integer(real_A[0..7] * 1024)
558 B[0..7] = integer(real_B[0..7] * 512)
559 MAC[0..7] = maximum of the LARc[0..7]
560 MIC[0..7] = minimum of the LARc[0..7] */
561
562 #undef STEP
563 #define STEP(A,B,MAC,MIC) \
564 temp = saturated_mul16(A, *LAR); \
565 temp = saturated_add16(temp, B); \
566 temp = saturated_add16(temp, 256); \
567 temp >>= 9; \
568 *LAR = (int16_t) ((temp > MAC) \
569 ? \
570 MAC - MIC \
571 : \
572 ((temp < MIC) ? 0 : temp - MIC)); \
573 LAR++;
574
575 STEP(20480, 0, 31, -32);
576 STEP(20480, 0, 31, -32);
577 STEP(20480, 2048, 15, -16);
578 STEP(20480, -2560, 15, -16);
579
580 STEP(13964, 94, 7, -8);
581 STEP(15360, -1792, 7, -8);
582 STEP( 8534, -341, 3, -4);
583 STEP( 9036, -1144, 3, -4);
584 #undef STEP
585 }
586 /*- End of function --------------------------------------------------------*/
587
588 void gsm0610_lpc_analysis(gsm0610_state_t *s,
589 int16_t amp[GSM0610_FRAME_LEN],
590 int16_t LARc[8])
591 {
592 int32_t L_ACF[9];
593
594 autocorrelation(amp, L_ACF);
595 reflection_coefficients(L_ACF, LARc);
596 transform_to_log_area_ratios(LARc);
597 quantization_and_coding(LARc);
598 }
599 /*- End of function --------------------------------------------------------*/
600 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.