comparison spandsp-0.0.3/spandsp-0.0.3/src/g722_decode.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * g722_decode.c - The ITU G.722 codec, decode part.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2005 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 * Based in part on a single channel G.722 codec which is:
26 *
27 * Copyright (c) CMU 1993
28 * Computer Science, Speech Group
29 * Chengxiang Lu and Alex Hauptmann
30 *
31 * $Id: g722_decode.c,v 1.18 2006/11/19 14:07:24 steveu Exp $
32 */
33
34 /*! \file */
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include <inttypes.h>
41 #include <memory.h>
42 #include <stdlib.h>
43 #if defined(HAVE_TGMATH_H)
44 #include <tgmath.h>
45 #endif
46 #if defined(HAVE_MATH_H)
47 #include <math.h>
48 #endif
49
50 #include "spandsp/telephony.h"
51 #include "spandsp/dc_restore.h"
52 #include "spandsp/g722.h"
53
54 static void block4(g722_decode_state_t *s, int band, int d);
55
56 static void block4(g722_decode_state_t *s, int band, int d)
57 {
58 int wd1;
59 int wd2;
60 int wd3;
61 int i;
62
63 /* Block 4, RECONS */
64 s->band[band].d[0] = d;
65 s->band[band].r[0] = saturate(s->band[band].s + d);
66
67 /* Block 4, PARREC */
68 s->band[band].p[0] = saturate(s->band[band].sz + d);
69
70 /* Block 4, UPPOL2 */
71 for (i = 0; i < 3; i++)
72 s->band[band].sg[i] = s->band[band].p[i] >> 15;
73 wd1 = saturate(s->band[band].a[1] << 2);
74
75 wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
76 if (wd2 > 32767)
77 wd2 = 32767;
78 wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
79 wd3 += (wd2 >> 7);
80 wd3 += (s->band[band].a[2]*32512) >> 15;
81 if (wd3 > 12288)
82 wd3 = 12288;
83 else if (wd3 < -12288)
84 wd3 = -12288;
85 s->band[band].ap[2] = wd3;
86
87 /* Block 4, UPPOL1 */
88 s->band[band].sg[0] = s->band[band].p[0] >> 15;
89 s->band[band].sg[1] = s->band[band].p[1] >> 15;
90 wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
91 wd2 = (s->band[band].a[1]*32640) >> 15;
92
93 s->band[band].ap[1] = saturate(wd1 + wd2);
94 wd3 = saturate(15360 - s->band[band].ap[2]);
95 if (s->band[band].ap[1] > wd3)
96 s->band[band].ap[1] = wd3;
97 else if (s->band[band].ap[1] < -wd3)
98 s->band[band].ap[1] = -wd3;
99
100 /* Block 4, UPZERO */
101 wd1 = (d == 0) ? 0 : 128;
102 s->band[band].sg[0] = d >> 15;
103 for (i = 1; i < 7; i++)
104 {
105 s->band[band].sg[i] = s->band[band].d[i] >> 15;
106 wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
107 wd3 = (s->band[band].b[i]*32640) >> 15;
108 s->band[band].bp[i] = saturate(wd2 + wd3);
109 }
110
111 /* Block 4, DELAYA */
112 for (i = 6; i > 0; i--)
113 {
114 s->band[band].d[i] = s->band[band].d[i - 1];
115 s->band[band].b[i] = s->band[band].bp[i];
116 }
117
118 for (i = 2; i > 0; i--)
119 {
120 s->band[band].r[i] = s->band[band].r[i - 1];
121 s->band[band].p[i] = s->band[band].p[i - 1];
122 s->band[band].a[i] = s->band[band].ap[i];
123 }
124
125 /* Block 4, FILTEP */
126 wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
127 wd1 = (s->band[band].a[1]*wd1) >> 15;
128 wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
129 wd2 = (s->band[band].a[2]*wd2) >> 15;
130 s->band[band].sp = saturate(wd1 + wd2);
131
132 /* Block 4, FILTEZ */
133 s->band[band].sz = 0;
134 for (i = 6; i > 0; i--)
135 {
136 wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
137 s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
138 }
139 s->band[band].sz = saturate(s->band[band].sz);
140
141 /* Block 4, PREDIC */
142 s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
143 }
144 /*- End of function --------------------------------------------------------*/
145
146 g722_decode_state_t *g722_decode_init(g722_decode_state_t *s, int rate, int options)
147 {
148 if (s == NULL)
149 {
150 if ((s = (g722_decode_state_t *) malloc(sizeof(*s))) == NULL)
151 return NULL;
152 }
153 memset(s, 0, sizeof(*s));
154 if (rate == 48000)
155 s->bits_per_sample = 6;
156 else if (rate == 56000)
157 s->bits_per_sample = 7;
158 else
159 s->bits_per_sample = 8;
160 if ((options & G722_SAMPLE_RATE_8000))
161 s->eight_k = TRUE;
162 if ((options & G722_PACKED) && s->bits_per_sample != 8)
163 s->packed = TRUE;
164 else
165 s->packed = FALSE;
166 s->band[0].det = 32;
167 s->band[1].det = 8;
168 return s;
169 }
170 /*- End of function --------------------------------------------------------*/
171
172 int g722_decode_release(g722_decode_state_t *s)
173 {
174 free(s);
175 return 0;
176 }
177 /*- End of function --------------------------------------------------------*/
178
179 int g722_decode(g722_decode_state_t *s, int16_t amp[], const uint8_t g722_data[], int len)
180 {
181 static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
182 static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0 };
183 static const int ilb[32] =
184 {
185 2048, 2093, 2139, 2186, 2233, 2282, 2332,
186 2383, 2435, 2489, 2543, 2599, 2656, 2714,
187 2774, 2834, 2896, 2960, 3025, 3091, 3158,
188 3228, 3298, 3371, 3444, 3520, 3597, 3676,
189 3756, 3838, 3922, 4008
190 };
191 static const int wh[3] = {0, -214, 798};
192 static const int rh2[4] = {2, 1, 2, 1};
193 static const int qm2[4] = {-7408, -1616, 7408, 1616};
194 static const int qm4[16] =
195 {
196 0, -20456, -12896, -8968,
197 -6288, -4240, -2584, -1200,
198 20456, 12896, 8968, 6288,
199 4240, 2584, 1200, 0
200 };
201 static const int qm5[32] =
202 {
203 -280, -280, -23352, -17560,
204 -14120, -11664, -9752, -8184,
205 -6864, -5712, -4696, -3784,
206 -2960, -2208, -1520, -880,
207 23352, 17560, 14120, 11664,
208 9752, 8184, 6864, 5712,
209 4696, 3784, 2960, 2208,
210 1520, 880, 280, -280
211 };
212 static const int qm6[64] =
213 {
214 -136, -136, -136, -136,
215 -24808, -21904, -19008, -16704,
216 -14984, -13512, -12280, -11192,
217 -10232, -9360, -8576, -7856,
218 -7192, -6576, -6000, -5456,
219 -4944, -4464, -4008, -3576,
220 -3168, -2776, -2400, -2032,
221 -1688, -1360, -1040, -728,
222 24808, 21904, 19008, 16704,
223 14984, 13512, 12280, 11192,
224 10232, 9360, 8576, 7856,
225 7192, 6576, 6000, 5456,
226 4944, 4464, 4008, 3576,
227 3168, 2776, 2400, 2032,
228 1688, 1360, 1040, 728,
229 432, 136, -432, -136
230 };
231 static const int qmf_coeffs[12] =
232 {
233 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
234 };
235
236 int dlowt;
237 int rlow;
238 int ihigh;
239 int dhigh;
240 int rhigh;
241 int xout1;
242 int xout2;
243 int wd1;
244 int wd2;
245 int wd3;
246 int code;
247 int outlen;
248 int i;
249 int j;
250
251 outlen = 0;
252 rhigh = 0;
253 for (j = 0; j < len; )
254 {
255 if (s->packed)
256 {
257 /* Unpack the code bits */
258 if (s->in_bits < s->bits_per_sample)
259 {
260 s->in_buffer |= (g722_data[j++] << s->in_bits);
261 s->in_bits += 8;
262 }
263 code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
264 s->in_buffer >>= s->bits_per_sample;
265 s->in_bits -= s->bits_per_sample;
266 }
267 else
268 {
269 code = g722_data[j++];
270 }
271
272 switch (s->bits_per_sample)
273 {
274 default:
275 case 8:
276 wd1 = code & 0x3F;
277 ihigh = (code >> 6) & 0x03;
278 wd2 = qm6[wd1];
279 wd1 >>= 2;
280 break;
281 case 7:
282 wd1 = code & 0x1F;
283 ihigh = (code >> 5) & 0x03;
284 wd2 = qm5[wd1];
285 wd1 >>= 1;
286 break;
287 case 6:
288 wd1 = code & 0x0F;
289 ihigh = (code >> 4) & 0x03;
290 wd2 = qm4[wd1];
291 break;
292 }
293 /* Block 5L, LOW BAND INVQBL */
294 wd2 = (s->band[0].det*wd2) >> 15;
295 /* Block 5L, RECONS */
296 rlow = s->band[0].s + wd2;
297 /* Block 6L, LIMIT */
298 if (rlow > 16383)
299 rlow = 16383;
300 else if (rlow < -16384)
301 rlow = -16384;
302
303 /* Block 2L, INVQAL */
304 wd2 = qm4[wd1];
305 dlowt = (s->band[0].det*wd2) >> 15;
306
307 /* Block 3L, LOGSCL */
308 wd2 = rl42[wd1];
309 wd1 = (s->band[0].nb*127) >> 7;
310 wd1 += wl[wd2];
311 if (wd1 < 0)
312 wd1 = 0;
313 else if (wd1 > 18432)
314 wd1 = 18432;
315 s->band[0].nb = wd1;
316
317 /* Block 3L, SCALEL */
318 wd1 = (s->band[0].nb >> 6) & 31;
319 wd2 = 8 - (s->band[0].nb >> 11);
320 wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
321 s->band[0].det = wd3 << 2;
322
323 block4(s, 0, dlowt);
324
325 if (!s->eight_k)
326 {
327 /* Block 2H, INVQAH */
328 wd2 = qm2[ihigh];
329 dhigh = (s->band[1].det*wd2) >> 15;
330 /* Block 5H, RECONS */
331 rhigh = dhigh + s->band[1].s;
332 /* Block 6H, LIMIT */
333 if (rhigh > 16383)
334 rhigh = 16383;
335 else if (rhigh < -16384)
336 rhigh = -16384;
337
338 /* Block 2H, INVQAH */
339 wd2 = rh2[ihigh];
340 wd1 = (s->band[1].nb*127) >> 7;
341 wd1 += wh[wd2];
342 if (wd1 < 0)
343 wd1 = 0;
344 else if (wd1 > 22528)
345 wd1 = 22528;
346 s->band[1].nb = wd1;
347
348 /* Block 3H, SCALEH */
349 wd1 = (s->band[1].nb >> 6) & 31;
350 wd2 = 10 - (s->band[1].nb >> 11);
351 wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
352 s->band[1].det = wd3 << 2;
353
354 block4(s, 1, dhigh);
355 }
356
357 if (s->itu_test_mode)
358 {
359 amp[outlen++] = (int16_t) (rlow << 1);
360 amp[outlen++] = (int16_t) (rhigh << 1);
361 }
362 else
363 {
364 if (s->eight_k)
365 {
366 amp[outlen++] = (int16_t) rlow;
367 }
368 else
369 {
370 /* Apply the receive QMF */
371 for (i = 0; i < 22; i++)
372 s->x[i] = s->x[i + 2];
373 s->x[22] = rlow + rhigh;
374 s->x[23] = rlow - rhigh;
375
376 xout1 = 0;
377 xout2 = 0;
378 for (i = 0; i < 12; i++)
379 {
380 xout2 += s->x[2*i]*qmf_coeffs[i];
381 xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
382 }
383 amp[outlen++] = (int16_t) (xout1 >> 12);
384 amp[outlen++] = (int16_t) (xout2 >> 12);
385 }
386 }
387 }
388 return outlen;
389 }
390 /*- End of function --------------------------------------------------------*/
391 /*- End of file ------------------------------------------------------------*/

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