comparison spandsp-0.0.6pre17/src/gsm0610_decode.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_decode.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_decode.c,v 1.25 2009/02/03 16:28:39 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/saturated.h"
53 #include "spandsp/gsm0610.h"
54
55 #include "gsm0610_local.h"
56
57 /* 4.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */
58
59 static void postprocessing(gsm0610_state_t *s, int16_t amp[])
60 {
61 int k;
62 int16_t msr;
63 int16_t tmp;
64
65 msr = s->msr;
66 for (k = 0; k < GSM0610_FRAME_LEN; k++)
67 {
68 tmp = gsm_mult_r(msr, 28180);
69 /* De-emphasis */
70 msr = saturated_add16(amp[k], tmp);
71 /* Truncation & upscaling */
72 amp[k] = (int16_t) (saturated_add16(msr, msr) & 0xFFF8);
73 }
74 /*endfor*/
75 s->msr = msr;
76 }
77 /*- End of function --------------------------------------------------------*/
78
79 static void decode_a_frame(gsm0610_state_t *s,
80 int16_t amp[GSM0610_FRAME_LEN],
81 gsm0610_frame_t *f)
82 {
83 int j;
84 int k;
85 int16_t erp[40];
86 int16_t wt[GSM0610_FRAME_LEN];
87 int16_t *drp;
88
89 drp = s->dp0 + 120;
90 for (j = 0; j < 4; j++)
91 {
92 gsm0610_rpe_decoding(s, f->xmaxc[j], f->Mc[j], f->xMc[j], erp);
93 gsm0610_long_term_synthesis_filtering(s, f->Nc[j], f->bc[j], erp, drp);
94 for (k = 0; k < 40; k++)
95 wt[j*40 + k] = drp[k];
96 /*endfor*/
97 }
98 /*endfor*/
99
100 gsm0610_short_term_synthesis_filter(s, f->LARc, wt, amp);
101 postprocessing(s, amp);
102 }
103 /*- End of function --------------------------------------------------------*/
104
105 SPAN_DECLARE(int) gsm0610_unpack_none(gsm0610_frame_t *s, const uint8_t c[])
106 {
107 int i;
108 int j;
109 int k;
110
111 i = 0;
112 for (j = 0; j < 8; j++)
113 s->LARc[j] = c[i++];
114 for (j = 0; j < 4; j++)
115 {
116 s->Nc[j] = c[i++];
117 s->bc[j] = c[i++];
118 s->Mc[j] = c[i++];
119 s->xmaxc[j] = c[i++];
120 for (k = 0; k < 13; k++)
121 s->xMc[j][k] = c[i++];
122 }
123 return 76;
124 }
125 /*- End of function --------------------------------------------------------*/
126
127 SPAN_DECLARE(int) gsm0610_unpack_wav49(gsm0610_frame_t *s, const uint8_t c[])
128 {
129 uint16_t sr;
130 int i;
131
132 sr = *c++;
133 s->LARc[0] = sr & 0x3F;
134 sr >>= 6;
135 sr |= (uint16_t) *c++ << 2;
136 s->LARc[1] = sr & 0x3F;
137 sr >>= 6;
138 sr |= (uint16_t) *c++ << 4;
139 s->LARc[2] = sr & 0x1F;
140 sr >>= 5;
141 s->LARc[3] = sr & 0x1F;
142 sr >>= 5;
143 sr |= (uint16_t) *c++ << 2;
144 s->LARc[4] = sr & 0xF;
145 sr >>= 4;
146 s->LARc[5] = sr & 0xF;
147 sr >>= 4;
148 sr |= (uint16_t) *c++ << 2;
149 s->LARc[6] = sr & 0x7;
150 sr >>= 3;
151 s->LARc[7] = sr & 0x7;
152 sr >>= 3;
153
154 for (i = 0; i < 4; i++)
155 {
156 sr |= (uint16_t) *c++ << 4;
157 s->Nc[i] = sr & 0x7F;
158 sr >>= 7;
159 s->bc[i] = sr & 0x3;
160 sr >>= 2;
161 s->Mc[i] = sr & 0x3;
162 sr >>= 2;
163 sr |= (uint16_t) *c++ << 1;
164 s->xmaxc[i] = sr & 0x3F;
165 sr >>= 6;
166 s->xMc[i][0] = sr & 0x7;
167 sr >>= 3;
168 sr = *c++;
169 s->xMc[i][1] = sr & 0x7;
170 sr >>= 3;
171 s->xMc[i][2] = sr & 0x7;
172 sr >>= 3;
173 sr |= (uint16_t) *c++ << 2;
174 s->xMc[i][3] = sr & 0x7;
175 sr >>= 3;
176 s->xMc[i][4] = sr & 0x7;
177 sr >>= 3;
178 s->xMc[i][5] = sr & 0x7;
179 sr >>= 3;
180 sr |= (uint16_t) *c++ << 1;
181 s->xMc[i][6] = sr & 0x7;
182 sr >>= 3;
183 s->xMc[i][7] = sr & 0x7;
184 sr >>= 3;
185 s->xMc[i][8] = sr & 0x7;
186 sr >>= 3;
187 sr = *c++;
188 s->xMc[i][9] = sr & 0x7;
189 sr >>= 3;
190 s->xMc[i][10] = sr & 0x7;
191 sr >>= 3;
192 sr |= (uint16_t) *c++ << 2;
193 s->xMc[i][11] = sr & 0x7;
194 sr >>= 3;
195 s->xMc[i][12] = sr & 0x7;
196 sr >>= 3;
197 }
198
199 s++;
200 sr |= (uint16_t) *c++ << 4;
201 s->LARc[0] = sr & 0x3F;
202 sr >>= 6;
203 s->LARc[1] = sr & 0x3F;
204 sr >>= 6;
205 sr = *c++;
206 s->LARc[2] = sr & 0x1F;
207 sr >>= 5;
208 sr |= (uint16_t) *c++ << 3;
209 s->LARc[3] = sr & 0x1F;
210 sr >>= 5;
211 s->LARc[4] = sr & 0xF;
212 sr >>= 4;
213 sr |= (uint16_t) *c++ << 2;
214 s->LARc[5] = sr & 0xF;
215 sr >>= 4;
216 s->LARc[6] = sr & 0x7;
217 sr >>= 3;
218 s->LARc[7] = sr & 0x7;
219 sr >>= 3;
220
221 for (i = 0; i < 4; i++)
222 {
223 sr = *c++;
224 s->Nc[i] = sr & 0x7F;
225 sr >>= 7;
226 sr |= (uint16_t) *c++ << 1;
227 s->bc[i] = sr & 0x3;
228 sr >>= 2;
229 s->Mc[i] = sr & 0x3;
230 sr >>= 2;
231 sr |= (uint16_t) *c++ << 5;
232 s->xmaxc[i] = sr & 0x3F;
233 sr >>= 6;
234 s->xMc[i][0] = sr & 0x7;
235 sr >>= 3;
236 s->xMc[i][1] = sr & 0x7;
237 sr >>= 3;
238 sr |= (uint16_t) *c++ << 1;
239 s->xMc[i][2] = sr & 0x7;
240 sr >>= 3;
241 s->xMc[i][3] = sr & 0x7;
242 sr >>= 3;
243 s->xMc[i][4] = sr & 0x7;
244 sr >>= 3;
245 sr = *c++;
246 s->xMc[i][5] = sr & 0x7;
247 sr >>= 3;
248 s->xMc[i][6] = sr & 0x7;
249 sr >>= 3;
250 sr |= (uint16_t) *c++ << 2;
251 s->xMc[i][7] = sr & 0x7;
252 sr >>= 3;
253 s->xMc[i][8] = sr & 0x7;
254 sr >>= 3;
255 s->xMc[i][9] = sr & 0x7;
256 sr >>= 3;
257 sr |= (uint16_t) *c++ << 1;
258 s->xMc[i][10] = sr & 0x7;
259 sr >>= 3;
260 s->xMc[i][11] = sr & 0x7;
261 sr >>= 3;
262 s->xMc[i][12] = sr & 0x7;
263 sr >>= 3;
264 }
265 return 65;
266 }
267 /*- End of function --------------------------------------------------------*/
268
269 SPAN_DECLARE(int) gsm0610_unpack_voip(gsm0610_frame_t *s, const uint8_t c[33])
270 {
271 int i;
272
273 s->LARc[0] = (*c++ & 0xF) << 2;
274 s->LARc[0] |= (*c >> 6) & 0x3;
275 s->LARc[1] = *c++ & 0x3F;
276 s->LARc[2] = (*c >> 3) & 0x1F;
277 s->LARc[3] = (*c++ & 0x7) << 2;
278 s->LARc[3] |= (*c >> 6) & 0x3;
279 s->LARc[4] = (*c >> 2) & 0xF;
280 s->LARc[5] = (*c++ & 0x3) << 2;
281 s->LARc[5] |= (*c >> 6) & 0x3;
282 s->LARc[6] = (*c >> 3) & 0x7;
283 s->LARc[7] = *c++ & 0x7;
284
285 for (i = 0; i < 4; i++)
286 {
287 s->Nc[i] = (*c >> 1) & 0x7F;
288 s->bc[i] = (*c++ & 0x1) << 1;
289 s->bc[i] |= (*c >> 7) & 0x1;
290 s->Mc[i] = (*c >> 5) & 0x3;
291 s->xmaxc[i] = (*c++ & 0x1F) << 1;
292 s->xmaxc[i] |= (*c >> 7) & 0x1;
293 s->xMc[i][0] = (*c >> 4) & 0x7;
294 s->xMc[i][1] = (*c >> 1) & 0x7;
295 s->xMc[i][2] = (*c++ & 0x1) << 2;
296 s->xMc[i][2] |= (*c >> 6) & 0x3;
297 s->xMc[i][3] = (*c >> 3) & 0x7;
298 s->xMc[i][4] = *c++ & 0x7;
299 s->xMc[i][5] = (*c >> 5) & 0x7;
300 s->xMc[i][6] = (*c >> 2) & 0x7;
301 s->xMc[i][7] = (*c++ & 0x3) << 1;
302 s->xMc[i][7] |= (*c >> 7) & 0x1;
303 s->xMc[i][8] = (*c >> 4) & 0x7;
304 s->xMc[i][9] = (*c >> 1) & 0x7;
305 s->xMc[i][10] = (*c++ & 0x1) << 2;
306 s->xMc[i][10] |= (*c >> 6) & 0x3;
307 s->xMc[i][11] = (*c >> 3) & 0x7;
308 s->xMc[i][12] = *c++ & 0x7;
309 }
310 return 33;
311 }
312 /*- End of function --------------------------------------------------------*/
313
314 SPAN_DECLARE(int) gsm0610_decode(gsm0610_state_t *s, int16_t amp[], const uint8_t code[], int len)
315 {
316 gsm0610_frame_t frame[2];
317 int bytes;
318 int samples;
319 int i;
320
321 samples = 0;
322 for (i = 0; i < len; i += bytes)
323 {
324 switch (s->packing)
325 {
326 default:
327 case GSM0610_PACKING_NONE:
328 if ((bytes = gsm0610_unpack_none(frame, &code[i])) < 0)
329 return 0;
330 decode_a_frame(s, &amp[samples], frame);
331 samples += GSM0610_FRAME_LEN;
332 break;
333 case GSM0610_PACKING_WAV49:
334 if ((bytes = gsm0610_unpack_wav49(frame, &code[i])) < 0)
335 return 0;
336 decode_a_frame(s, &amp[samples], frame);
337 samples += GSM0610_FRAME_LEN;
338 decode_a_frame(s, &amp[samples], frame + 1);
339 samples += GSM0610_FRAME_LEN;
340 break;
341 case GSM0610_PACKING_VOIP:
342 if ((bytes = gsm0610_unpack_voip(frame, &code[i])) < 0)
343 return 0;
344 decode_a_frame(s, &amp[samples], frame);
345 samples += GSM0610_FRAME_LEN;
346 break;
347 }
348 /*endswitch*/
349 }
350 /*endfor*/
351 return samples;
352 }
353 /*- End of function --------------------------------------------------------*/
354 /*- End of file ------------------------------------------------------------*/

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