5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * gsm0610_preprocess.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_preprocess.c,v 1.7 2006/11/19 14:07:24 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 /*
|
|
54 4.2.0 .. 4.2.3 PREPROCESSING SECTION
|
|
55
|
|
56 After A-law to linear conversion (or directly from the
|
|
57 A to D converter) the following scaling is assumed for
|
|
58 input to the RPE-LTP algorithm:
|
|
59
|
|
60 in: 0.1.....................12
|
|
61 S.v.v.v.v.v.v.v.v.v.v.v.v.*.*.*
|
|
62
|
|
63 Where S is the sign bit, v a valid bit, and * a "don't care" bit.
|
|
64 The original signal is called sop[..]
|
|
65
|
|
66 out: 0.1................... 12
|
|
67 S.S.v.v.v.v.v.v.v.v.v.v.v.v.0.0
|
|
68 */
|
|
69
|
|
70 void gsm0610_preprocess(gsm0610_state_t *s, const int16_t amp[GSM0610_FRAME_LEN], int16_t so[GSM0610_FRAME_LEN])
|
|
71 {
|
|
72 int16_t z1;
|
|
73 int16_t mp;
|
|
74 int16_t s1;
|
|
75 int16_t msp;
|
|
76 int16_t SO;
|
|
77 int32_t L_z2;
|
|
78 int32_t L_s2;
|
|
79 int32_t L_temp;
|
|
80 #if !defined(__GNUC__)
|
|
81 int16_t lsp;
|
|
82 #endif
|
|
83 int k;
|
|
84
|
|
85 z1 = s->z1;
|
|
86 L_z2 = s->L_z2;
|
|
87 mp = s->mp;
|
|
88 for (k = 0; k < GSM0610_FRAME_LEN; k++)
|
|
89 {
|
|
90 /* 4.2.1 Downscaling of the input signal */
|
|
91 SO = (amp[k] >> 1) & ~3;
|
|
92
|
|
93 assert(SO >= -0x4000); // downscaled by
|
|
94 assert(SO <= 0x3FFC); // previous routine.
|
|
95
|
|
96 /* 4.2.2 Offset compensation */
|
|
97
|
|
98 /* This part implements a high-pass filter and requires extended
|
|
99 arithmetic precision for the recursive part of this filter.
|
|
100 The input of this procedure is the array so[0...159] and the
|
|
101 output the array sof[ 0...159 ].
|
|
102 */
|
|
103 /* Compute the non-recursive part */
|
|
104 s1 = SO - z1;
|
|
105 z1 = SO;
|
|
106
|
|
107 assert(s1 != INT16_MIN);
|
|
108
|
|
109 /* Compute the recursive part */
|
|
110 L_s2 = s1;
|
|
111 L_s2 <<= 15;
|
|
112
|
|
113 /* Perform a 31 by 16 bits multiplication */
|
|
114 #if defined(__GNUC__)
|
|
115 L_z2 = ((int64_t) L_z2*32735 + 0x4000) >> 15;
|
|
116 /* Alternate (ANSI) version of below line does slightly different rounding:
|
|
117 * L_temp = L_z2 >> 9;
|
|
118 * L_temp += L_temp >> 5;
|
|
119 * L_temp = (++L_temp) >> 1;
|
|
120 * L_z2 = L_z2 - L_temp;
|
|
121 */
|
|
122 L_z2 = gsm_l_add(L_z2, L_s2);
|
|
123 #else
|
|
124 /* This does L_z2 = L_z2 * 0x7FD5/0x8000 + L_s2 */
|
|
125 msp = (int16_t) (L_z2 >> 15);
|
|
126 lsp = (int16_t) (L_z2 - ((int32_t) msp << 15));
|
|
127
|
|
128 L_s2 += gsm_mult_r(lsp, 32735);
|
|
129 L_temp = (int32_t) msp*32735;
|
|
130 L_z2 = gsm_l_add(L_temp, L_s2);
|
|
131 #endif
|
|
132
|
|
133 /* Compute sof[k] with rounding */
|
|
134 L_temp = gsm_l_add(L_z2, 16384);
|
|
135
|
|
136 /* 4.2.3 Preemphasis */
|
|
137 msp = gsm_mult_r(mp, -28180);
|
|
138 mp = (int16_t) (L_temp >> 15);
|
|
139 so[k] = gsm_add(mp, msp);
|
|
140 }
|
|
141 /*endfor*/
|
|
142
|
|
143 s->z1 = z1;
|
|
144 s->L_z2 = L_z2;
|
|
145 s->mp = mp;
|
|
146 }
|
|
147 /*- End of function --------------------------------------------------------*/
|
|
148 /*- End of file ------------------------------------------------------------*/
|