5
|
1 /*
|
|
2 * SpanDSP - a series of DSP components for telephony
|
|
3 *
|
|
4 * gsm0610_local.h - 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_local.h,v 1.6 2006/10/24 13:45:25 steveu Exp $
|
|
29 */
|
|
30
|
|
31 #if !defined(_GSM0610_LOCAL_H_)
|
|
32 #define _GSM0610_LOCAL_H_
|
|
33
|
|
34 #define GSM0610_FRAME_LEN 160
|
|
35
|
|
36 #define GSM0610_MAGIC 0xD
|
|
37
|
|
38 static __inline__ int16_t gsm_add(int16_t a, int16_t b)
|
|
39 {
|
|
40 #if defined(__GNUC__) && defined(__i386__)
|
|
41 __asm__ __volatile__(
|
|
42 " addw %2,%0;\n"
|
|
43 " jno 0f;\n"
|
|
44 " movw $0x7fff,%0;\n"
|
|
45 " adcw $0,%0;\n"
|
|
46 "0:"
|
|
47 : "=r" (a)
|
|
48 : "0" (a), "ir" (b)
|
|
49 : "cc"
|
|
50 );
|
|
51 return a;
|
|
52 #else
|
|
53 int32_t sum;
|
|
54
|
|
55 sum = (int32_t) a + (int32_t) b;
|
|
56 return saturate(sum);
|
|
57 #endif
|
|
58 }
|
|
59 /*- End of function --------------------------------------------------------*/
|
|
60
|
|
61 static __inline__ int32_t gsm_l_add(int32_t a, int32_t b)
|
|
62 {
|
|
63 #if defined(__i386__)
|
|
64 __asm__ __volatile__(
|
|
65 " addl %2,%0;\n"
|
|
66 " jno 0f;\n"
|
|
67 " movl $0x7fffffff,%0;\n"
|
|
68 " adcl $0,%0;\n"
|
|
69 "0:"
|
|
70 : "=r" (a)
|
|
71 : "0" (a), "ir" (b)
|
|
72 : "cc"
|
|
73 );
|
|
74 return a;
|
|
75 #else
|
|
76 uint32_t A;
|
|
77
|
|
78 if (a < 0)
|
|
79 {
|
|
80 if (b >= 0)
|
|
81 return a + b;
|
|
82 /*endif*/
|
|
83 A = (uint32_t) -(a + 1) + (uint32_t) -(b + 1);
|
|
84 return (A >= INT32_MAX) ? INT32_MIN : -(int32_t) A - 2;
|
|
85 }
|
|
86 /*endif*/
|
|
87 if (b <= 0)
|
|
88 return a + b;
|
|
89 /*endif*/
|
|
90 A = (uint32_t) a + (uint32_t) b;
|
|
91 return (A > INT32_MAX) ? INT32_MAX : A;
|
|
92 #endif
|
|
93 }
|
|
94 /*- End of function --------------------------------------------------------*/
|
|
95
|
|
96 static __inline__ int16_t gsm_sub(int16_t a, int16_t b)
|
|
97 {
|
|
98 int32_t diff;
|
|
99
|
|
100 diff = (int32_t) a - (int32_t) b;
|
|
101 return saturate(diff);
|
|
102 }
|
|
103 /*- End of function --------------------------------------------------------*/
|
|
104
|
|
105 static __inline__ int16_t gsm_mult(int16_t a, int16_t b)
|
|
106 {
|
|
107 if (a == INT16_MIN && b == INT16_MIN)
|
|
108 return INT16_MAX;
|
|
109 /*endif*/
|
|
110 return ((int32_t) a * (int32_t) b) >> 15;
|
|
111 }
|
|
112 /*- End of function --------------------------------------------------------*/
|
|
113
|
|
114 static __inline__ int32_t gsm_l_mult(int16_t a, int16_t b)
|
|
115 {
|
|
116 assert (a != INT16_MIN || b != INT16_MIN);
|
|
117 return ((int32_t) a * (int32_t) b) << 1;
|
|
118 }
|
|
119 /*- End of function --------------------------------------------------------*/
|
|
120
|
|
121 static __inline__ int16_t gsm_mult_r(int16_t a, int16_t b)
|
|
122 {
|
|
123 int32_t prod;
|
|
124
|
|
125 if (b == INT16_MIN && a == INT16_MIN)
|
|
126 return INT16_MAX;
|
|
127 /*endif*/
|
|
128 prod = (int32_t) a * (int32_t) b + 16384;
|
|
129 prod >>= 15;
|
|
130 return prod & 0xFFFF;
|
|
131 }
|
|
132 /*- End of function --------------------------------------------------------*/
|
|
133
|
|
134 static __inline__ int16_t gsm_abs(int16_t a)
|
|
135 {
|
|
136 return (a == INT16_MIN) ? INT16_MAX : abs(a);
|
|
137 }
|
|
138 /*- End of function --------------------------------------------------------*/
|
|
139
|
|
140 static __inline__ int16_t gsm_asr(int16_t a, int n)
|
|
141 {
|
|
142 if (n >= 16)
|
|
143 return -(a < 0);
|
|
144 /*endif*/
|
|
145 if (n <= -16)
|
|
146 return 0;
|
|
147 /*endif*/
|
|
148 if (n < 0)
|
|
149 return a << -n;
|
|
150 /*endif*/
|
|
151 return a >> n;
|
|
152 }
|
|
153 /*- End of function --------------------------------------------------------*/
|
|
154
|
|
155 static __inline__ int16_t gsm_asl(int16_t a, int n)
|
|
156 {
|
|
157 if (n >= 16)
|
|
158 return 0;
|
|
159 /*endif*/
|
|
160 if (n <= -16)
|
|
161 return -(a < 0);
|
|
162 /*endif*/
|
|
163 if (n < 0)
|
|
164 return gsm_asr(a, -n);
|
|
165 /*endif*/
|
|
166 return a << n;
|
|
167 }
|
|
168 /*- End of function --------------------------------------------------------*/
|
|
169
|
|
170 extern void gsm0610_long_term_predictor(gsm0610_state_t *s,
|
|
171 int16_t d[40],
|
|
172 int16_t *dp, /* [-120..-1] d' IN */
|
|
173 int16_t e[40],
|
|
174 int16_t dpp[40],
|
|
175 int16_t *Nc,
|
|
176 int16_t *bc);
|
|
177
|
|
178 extern void gsm0610_lpc_analysis(gsm0610_state_t *s,
|
|
179 int16_t amp[160],
|
|
180 int16_t LARc[8]);
|
|
181
|
|
182 extern void gsm0610_preprocess(gsm0610_state_t *s,
|
|
183 const int16_t amp[],
|
|
184 int16_t so[]);
|
|
185
|
|
186 extern void gsm0610_short_term_analysis_filter(gsm0610_state_t *s,
|
|
187 int16_t LARc[8],
|
|
188 int16_t amp[160]);
|
|
189
|
|
190 extern void gsm0610_long_term_synthesis_filtering(gsm0610_state_t *s,
|
|
191 int16_t Ncr,
|
|
192 int16_t bcr,
|
|
193 int16_t erp[40],
|
|
194 int16_t *drp); /* [-120..-1] IN, [0..40] OUT */
|
|
195
|
|
196 extern void gsm0610_rpe_decoding(gsm0610_state_t *s,
|
|
197 int16_t xmaxcr,
|
|
198 int16_t Mcr,
|
|
199 int16_t *xMcr, /* [0..12], 3 bits IN */
|
|
200 int16_t erp[40]);
|
|
201
|
|
202 extern void gsm0610_rpe_encoding(gsm0610_state_t *s,
|
|
203 int16_t *e, /* [-5..-1][0..39][40..44] IN/OUT */
|
|
204 int16_t *xmaxc,
|
|
205 int16_t *Mc,
|
|
206 int16_t xMc[13]);
|
|
207
|
|
208 extern void gsm0610_short_term_synthesis_filter(gsm0610_state_t *s,
|
|
209 int16_t LARcr[8],
|
|
210 int16_t drp[40],
|
|
211 int16_t amp[160]);
|
|
212
|
|
213 extern int16_t gsm0610_norm(int32_t a);
|
|
214
|
|
215 #if defined(__GNUC__) && defined(__i386__)
|
|
216
|
|
217 void gsm0610_vec_vsraw(const int16_t *p, int n, int bits);
|
|
218
|
|
219 int32_t gsm0610_vec_iprod(const int16_t *p, const int16_t *q, int n);
|
|
220
|
|
221 int32_t gsm0610_vec_maxmin(const int16_t *p, int n, int16_t *out);
|
|
222
|
|
223 int32_t gsm0610_max_cross_corr(const int16_t *wt, const int16_t *dp, int16_t *Nc_out);
|
|
224
|
|
225 #endif
|
|
226
|
|
227 #endif
|
|
228
|
|
229 /*- End of include ---------------------------------------------------------*/
|