blob: 770ade06e1816c58e264031bc19d5fa668c4e794 [file] [log] [blame]
Benny Prijono7ffd7752008-03-17 14:07:53 +00001/* $Id$ */
2/*
3 * Copyright (C)2003-2008 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19/*
20 * Based on implementation found in Carnegie Mellon Speech Group Software
21 * depository (ftp://ftp.cs.cmu.edu/project/fgdata/index.html). No copyright
22 * was claimed in the original source codes.
23 */
24#include <pjmedia/errno.h>
25#include <pj/assert.h>
26#include <pj/pool.h>
27
28#include "g722_dec.h"
29
30#if defined(PJMEDIA_HAS_G722_CODEC) && (PJMEDIA_HAS_G722_CODEC != 0)
31
32#define MODE 1
33
34#define SATURATE(v, max, min) \
35 if (v>max) v = max; \
36 else if (v<min) v = min
37
38extern const int g722_qmf_coeff[24];
39
40static const int qm4[16] =
41{
42 0, -20456, -12896, -8968,
43 -6288, -4240, -2584, -1200,
44 20456, 12896, 8968, 6288,
45 4240, 2584, 1200, 0
46};
47static const int ilb[32] = {
48 2048, 2093, 2139, 2186, 2233, 2282, 2332,
49 2383, 2435, 2489, 2543, 2599, 2656, 2714,
50 2774, 2834, 2896, 2960, 3025, 3091, 3158,
51 3228, 3298, 3371, 3444, 3520, 3597, 3676,
52 3756, 3838, 3922, 4008
53};
54
55
56static int block2l (int il, int detl)
57{
58 int dlt ;
59 int ril, wd2 ;
60
61 /* INVQAL */
62 ril = il >> 2 ;
63 wd2 = qm4[ril] ;
64 dlt = (detl * wd2) >> 15 ;
65
66 return (dlt) ;
67}
68
69
70static int block3l (g722_dec_t *dec, int il)
71{
72 int detl ;
73 int ril, il4, wd, wd1, wd2, wd3, nbpl, depl ;
74 static const int wl[8] = {
75 -60, -30, 58, 172, 334, 538, 1198, 3042
76 };
77 static const int rl42[16] = {
78 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
79 };
80
81 /* LOGSCL */
82 ril = il >> 2 ;
83 il4 = rl42[ril] ;
84 wd = (dec->nbl * 32512) >> 15 ;
85 nbpl = wd + wl[il4] ;
86
87 if (nbpl < 0) nbpl = 0 ;
88 if (nbpl > 18432) nbpl = 18432 ;
89
90 /* SCALEL */
91 wd1 = (nbpl >> 6) & 31 ;
92 wd2 = nbpl >> 11 ;
93 if ((8 - wd2) < 0) wd3 = ilb[wd1] << (wd2 - 8) ;
94 else wd3 = ilb[wd1] >> (8 - wd2) ;
95 depl = wd3 << 2 ;
96
97 /* DELAYA */
98 dec->nbl = nbpl ;
99 /* DELAYL */
100 detl = depl ;
101
102 return (detl) ;
103}
104
105
106static int block4l (g722_dec_t *dec, int dl)
107{
108 int sl = dec->slow ;
109 int i ;
110 int wd, wd1, wd2, wd3, wd4, wd5/*, wd6 */;
111
112 dec->dlt[0] = dl;
113
114 /* RECONS */
115 dec->rlt[0] = sl + dec->dlt[0] ;
116 SATURATE(dec->rlt[0], 32767, -32768);
117
118 /* PARREC */
119 dec->plt[0] = dec->dlt[0] + dec->szl ;
120 SATURATE(dec->plt[0], 32767, -32768);
121
122 /* UPPOL2 */
123 dec->sgl[0] = dec->plt[0] >> 15 ;
124 dec->sgl[1] = dec->plt[1] >> 15 ;
125 dec->sgl[2] = dec->plt[2] >> 15 ;
126
127 wd1 = dec->al[1] << 2;
128 SATURATE(wd1, 32767, -32768);
129
130 if ( dec->sgl[0] == dec->sgl[1] ) wd2 = - wd1 ;
131 else wd2 = wd1 ;
132 if (wd2 > 32767) wd2 = 32767;
133 wd2 = wd2 >> 7 ;
134
135 if ( dec->sgl[0] == dec->sgl[2] ) wd3 = 128 ;
136 else wd3 = - 128 ;
137
138 wd4 = wd2 + wd3 ;
139 wd5 = (dec->al[2] * 32512) >> 15 ;
140
141 dec->apl[2] = wd4 + wd5 ;
142 SATURATE(dec->apl[2], 12288, -12288);
143
144 /* UPPOL1 */
145 dec->sgl[0] = dec->plt[0] >> 15 ;
146 dec->sgl[1] = dec->plt[1] >> 15 ;
147
148 if ( dec->sgl[0] == dec->sgl[1] ) wd1 = 192 ;
149 else wd1 = - 192 ;
150
151 wd2 = (dec->al[1] * 32640) >> 15 ;
152
153 dec->apl[1] = wd1 + wd2 ;
154 SATURATE(dec->apl[1], 32767, -32768);
155
156 wd3 = (15360 - dec->apl[2]) ;
157 SATURATE(wd3, 32767, -32768);
158 if ( dec->apl[1] > wd3) dec->apl[1] = wd3 ;
159 if ( dec->apl[1] < -wd3) dec->apl[1] = -wd3 ;
160
161 /* UPZERO */
162 if ( dec->dlt[0] == 0 ) wd1 = 0 ;
163 else wd1 = 128 ;
164
165 dec->sgl[0] = dec->dlt[0] >> 15 ;
166
167 for ( i = 1; i < 7; i++ ) {
168 dec->sgl[i] = dec->dlt[i] >> 15 ;
169 if ( dec->sgl[i] == dec->sgl[0] ) wd2 = wd1 ;
170 else wd2 = - wd1 ;
171 wd3 = (dec->bl[i] * 32640) >> 15 ;
172 dec->bpl[i] = wd2 + wd3 ;
173 SATURATE(dec->bpl[i], 32767, -32768);
174 }
175
176 /* DELAYA */
177 for ( i = 6; i > 0; i-- ) {
178 dec->dlt[i] = dec->dlt[i-1] ;
179 dec->bl[i] = dec->bpl[i] ;
180 }
181
182 for ( i = 2; i > 0; i-- ) {
183 dec->rlt[i] = dec->rlt[i-1] ;
184 dec->plt[i] = dec->plt[i-1] ;
185 dec->al[i] = dec->apl[i] ;
186 }
187
188 /* FILTEP */
189 wd1 = dec->rlt[1] << 1;
190 SATURATE(wd1, 32767, -32768);
191 wd1 = ( dec->al[1] * wd1 ) >> 15 ;
192
193 wd2 = dec->rlt[2] << 1;
194 SATURATE(wd2, 32767, -32768);
195 wd2 = ( dec->al[2] * wd2 ) >> 15 ;
196
197 dec->spl = wd1 + wd2 ;
198 SATURATE(dec->spl, 32767, -32768);
199
200 /* FILTEZ */
201 dec->szl = 0 ;
202 for (i=6; i>0; i--) {
203 wd = dec->dlt[i] << 1;
204 SATURATE(wd, 32767, -32768);
205 dec->szl += (dec->bl[i] * wd) >> 15 ;
206 SATURATE(dec->szl, 32767, -32768);
207 }
208
209 /* PREDIC */
210 sl = dec->spl + dec->szl ;
211 SATURATE(sl, 32767, -32768);
212
213 return (sl) ;
214}
215
216static int block5l (int ilr, int sl, int detl, int mode)
217{
218 int yl ;
219 int ril, dl, wd2 = 0;
220 static const int qm5[32] = {
221 -280, -280, -23352, -17560,
222 -14120, -11664, -9752, -8184,
223 -6864, -5712, -4696, -3784,
224 -2960, -2208, -1520, -880,
225 23352, 17560, 14120, 11664,
226 9752, 8184, 6864, 5712,
227 4696, 3784, 2960, 2208,
228 1520, 880, 280, -280
229 };
230 static const int qm6[64] = {
231 -136, -136, -136, -136,
232 -24808, -21904, -19008, -16704,
233 -14984, -13512, -12280, -11192,
234 -10232, -9360, -8576, -7856,
235 -7192, -6576, -6000, -5456,
236 -4944, -4464, -4008, -3576,
237 -3168, -2776, -2400, -2032,
238 -1688, -1360, -1040, -728,
239 24808, 21904, 19008, 16704,
240 14984, 13512, 12280, 11192,
241 10232, 9360, 8576, 7856,
242 7192, 6576, 6000, 5456,
243 4944, 4464, 4008, 3576,
244 3168, 2776, 2400, 2032,
245 1688, 1360, 1040, 728,
246 432, 136, -432, -136
247 };
248
249 /* INVQBL */
250 if (mode == 1) {
251 ril = ilr ;
252 wd2 = qm6[ril] ;
253 }
254
255 if (mode == 2) {
256 ril = ilr >> 1 ;
257 wd2 = qm5[ril] ;
258 }
259
260 if (mode == 3) {
261 ril = ilr >> 2 ;
262 wd2 = qm4[ril] ;
263 }
264
265 dl = (detl * wd2 ) >> 15 ;
266
267 /* RECONS */
268 yl = sl + dl ;
269 SATURATE(yl, 32767, -32768);
270
271 return (yl) ;
272}
273
274static int block6l (int yl)
275{
276 int rl ;
277
278 rl = yl ;
279 SATURATE(rl, 16383, -16384);
280
281 return (rl) ;
282}
283
284static int block2h (int ih, int deth)
285{
286 int dh ;
287 int wd2 ;
288 static const int qm2[4] = {-7408, -1616, 7408, 1616} ;
289
290 /* INVQAH */
291 wd2 = qm2[ih] ;
292 dh = (deth * wd2) >> 15 ;
293
294 return (dh) ;
295}
296
297static int block3h (g722_dec_t *dec, int ih)
298{
299 int deth ;
300 int ih2, wd, wd1, wd2, wd3, nbph, deph ;
301 static const int wh[3] = {0, -214, 798} ;
302 static const int rh2[4] = {2, 1, 2, 1} ;
303
304 /* LOGSCH */
305 ih2 = rh2[ih] ;
306 wd = (dec->nbh * 32512) >> 15 ;
307 nbph = wd + wh[ih2] ;
308
309 if (nbph < 0) nbph = 0 ;
310 if (nbph > 22528) nbph = 22528 ;
311
312
313 /* SCALEH */
314 wd1 = (nbph >> 6) & 31 ;
315 wd2 = nbph >> 11 ;
316 if ((10 - wd2) < 0) wd3 = ilb[wd1] << (wd2 - 10) ;
317 else wd3 = ilb[wd1] >> (10 - wd2) ;
318 deph = wd3 << 2 ;
319
320 /* DELAYA */
321 dec->nbh = nbph ;
322
323 /* DELAYH */
324 deth = deph ;
325
326 return (deth) ;
327}
328
329static int block4h (g722_dec_t *dec, int d)
330{
331 int sh = dec->shigh;
332 int i ;
333 int wd, wd1, wd2, wd3, wd4, wd5/*, wd6 */;
334
335 dec->dh[0] = d;
336
337 /* RECONS */
338 dec->rh[0] = sh + dec->dh[0] ;
339 SATURATE(dec->rh[0], 32767, -32768);
340
341 /* PARREC */
342 dec->ph[0] = dec->dh[0] + dec->szh ;
343 SATURATE(dec->ph[0], 32767, -32768);
344
345 /* UPPOL2 */
346 dec->sgh[0] = dec->ph[0] >> 15 ;
347 dec->sgh[1] = dec->ph[1] >> 15 ;
348 dec->sgh[2] = dec->ph[2] >> 15 ;
349
350 wd1 = dec->ah[1] << 2;
351 SATURATE(wd1, 32767, -32768);
352
353 if ( dec->sgh[0] == dec->sgh[1] ) wd2 = - wd1 ;
354 else wd2 = wd1 ;
355 if (wd2 > 32767) wd2 = 32767;
356
357 wd2 = wd2 >> 7 ;
358
359 if ( dec->sgh[0] == dec->sgh[2] ) wd3 = 128 ;
360 else wd3 = - 128 ;
361
362 wd4 = wd2 + wd3 ;
363 wd5 = (dec->ah[2] * 32512) >> 15 ;
364
365 dec->aph[2] = wd4 + wd5 ;
366 SATURATE(dec->aph[2], 12288, -12288);
367
368 /* UPPOL1 */
369 dec->sgh[0] = dec->ph[0] >> 15 ;
370 dec->sgh[1] = dec->ph[1] >> 15 ;
371
372 if ( dec->sgh[0] == dec->sgh[1] ) wd1 = 192 ;
373 else wd1 = - 192 ;
374
375 wd2 = (dec->ah[1] * 32640) >> 15 ;
376
377 dec->aph[1] = wd1 + wd2 ;
378 SATURATE(dec->aph[1], 32767, -32768);
379 //dec->aph[2]?
380 //if (aph[2] > 32767) aph[2] = 32767;
381 //if (aph[2] < -32768) aph[2] = -32768;
382
383 wd3 = (15360 - dec->aph[2]) ;
384 SATURATE(wd3, 32767, -32768);
385 if ( dec->aph[1] > wd3) dec->aph[1] = wd3 ;
386 if ( dec->aph[1] < -wd3) dec->aph[1] = -wd3 ;
387
388 /* UPZERO */
389 if ( dec->dh[0] == 0 ) wd1 = 0 ;
390 if ( dec->dh[0] != 0 ) wd1 = 128 ;
391
392 dec->sgh[0] = dec->dh[0] >> 15 ;
393
394 for ( i = 1; i < 7; i++ ) {
395 dec->sgh[i] = dec->dh[i] >> 15 ;
396 if ( dec->sgh[i] == dec->sgh[0] ) wd2 = wd1 ;
397 else wd2 = - wd1 ;
398 wd3 = (dec->bh[i] * 32640) >> 15 ;
399 dec->bph[i] = wd2 + wd3 ;
400 }
401
402 /* DELAYA */
403 for ( i = 6; i > 0; i-- ) {
404 dec->dh[i] = dec->dh[i-1] ;
405 dec->bh[i] = dec->bph[i] ;
406 }
407
408 for ( i = 2; i > 0; i-- ) {
409 dec->rh[i] = dec->rh[i-1] ;
410 dec->ph[i] = dec->ph[i-1] ;
411 dec->ah[i] = dec->aph[i] ;
412 }
413
414 /* FILTEP */
415 wd1 = dec->rh[1] << 1 ;
416 SATURATE(wd1, 32767, -32768);
417 wd1 = ( dec->ah[1] * wd1 ) >> 15 ;
418
419 wd2 = dec->rh[2] << 1;
420 SATURATE(wd2, 32767, -32768);
421 wd2 = ( dec->ah[2] * wd2 ) >> 15 ;
422
423 dec->sph = wd1 + wd2 ;
424 SATURATE(dec->sph, 32767, -32768);
425
426 /* FILTEZ */
427 dec->szh = 0 ;
428 for (i=6; i>0; i--) {
429 wd = dec->dh[i] << 1;
430 SATURATE(wd, 32767, -32768);
431 dec->szh += (dec->bh[i] * wd) >> 15 ;
432 SATURATE(dec->szh, 32767, -32768);
433 }
434
435 /* PREDIC */
436 sh = dec->sph + dec->szh ;
437 SATURATE(sh, 32767, -32768);
438
439 return (sh) ;
440}
441
442static int block5h (int dh, int sh)
443{
444 int rh ;
445
446 rh = dh + sh;
447 SATURATE(rh, 16383, -16384);
448
449 return (rh) ;
450}
451
452void rx_qmf(g722_dec_t *dec, int rl, int rh, int *xout1, int *xout2)
453{
454 int i;
455
456 pj_memmove(&dec->xd[1], dec->xd, 11*sizeof(dec->xd[0]));
457 pj_memmove(&dec->xs[1], dec->xs, 11*sizeof(dec->xs[0]));
458
459 /* RECA */
460 dec->xd[0] = rl - rh ;
461 if (dec->xd[0] > 16383) dec->xd[0] = 16383;
462 else if (dec->xd[0] < -16384) dec->xd[0] = -16384;
463
464 /* RECB */
465 dec->xs[0] = rl + rh ;
466 if (dec->xs[0] > 16383) dec->xs[0] = 16383;
467 else if (dec->xs[0] < -16384) dec->xs[0] = -16384;
468
469 /* ACCUMC */
470 *xout1 = 0;
471 for (i=0; i<12; ++i) *xout1 += dec->xd[i] * g722_qmf_coeff[2*i];
472 *xout1 = *xout1 >> 12 ;
473 if (*xout1 > 16383) *xout1 = 16383 ;
474 else if (*xout1 < -16384) *xout1 = -16384 ;
475
476 /* ACCUMD */
477 *xout2 = 0;
478 for (i=0; i<12; ++i) *xout2 += dec->xs[i] * g722_qmf_coeff[2*i+1];
479 *xout2 = *xout2 >> 12 ;
480 if (*xout2 > 16383) *xout2 = 16383 ;
481 else if (*xout2 < -16384) *xout2 = -16384 ;
482}
483
484
485PJ_DEF(pj_status_t) g722_dec_init(g722_dec_t *dec)
486{
487 PJ_ASSERT_RETURN(dec, PJ_EINVAL);
488
489 pj_bzero(dec, sizeof(g722_dec_t));
490
491 dec->detlow = 32;
492 dec->dethigh = 8;
493
494 return PJ_SUCCESS;
495}
496
497PJ_DEF(pj_status_t) g722_dec_decode( g722_dec_t *dec,
498 void *in,
499 pj_size_t in_size,
500 pj_int16_t out[],
501 pj_size_t *nsamples)
502{
503 unsigned i;
504 int ilowr, ylow, rlow, dlowt;
505 int ihigh, rhigh, dhigh;
506 int pcm1, pcm2;
507 pj_uint8_t *in_ = (pj_uint8_t*) in;
508
509 PJ_ASSERT_RETURN(dec && in && in_size && out && nsamples, PJ_EINVAL);
510 PJ_ASSERT_RETURN(*nsamples >= (in_size << 1), PJ_ETOOSMALL);
511
512 for(i = 0; i < in_size; ++i) {
513 ilowr = in_[i] & 63;
514 ihigh = (in_[i] >> 6) & 3;
515
516 /* low band decoder */
517 ylow = block5l (ilowr, dec->slow, dec->detlow, MODE) ;
518 rlow = block6l (ylow) ;
519 dlowt = block2l (ilowr, dec->detlow) ;
520 dec->detlow = block3l (dec, ilowr) ;
521 dec->slow = block4l (dec, dlowt) ;
522 /* rlow <= output low band pcm */
523
524 /* high band decoder */
525 dhigh = block2h (ihigh, dec->dethigh) ;
526 rhigh = block5h (dhigh, dec->shigh) ;
527 dec->dethigh = block3h (dec, ihigh) ;
528 dec->shigh = block4h (dec, dhigh) ;
529 /* rhigh <= output high band pcm */
530
531 rx_qmf(dec, rlow, rhigh, &pcm1, &pcm2);
Nanang Izzuddinee340b32008-10-06 18:42:13 +0000532 out[i*2] = (pj_int16_t)(pcm1 << 2);
533 out[i*2+1] = (pj_int16_t)(pcm2 << 2);
Benny Prijono7ffd7752008-03-17 14:07:53 +0000534 }
535
536 *nsamples = in_size << 1;
537
538 return PJ_SUCCESS;
539}
540
541PJ_DEF(pj_status_t) g722_dec_deinit(g722_dec_t *dec)
542{
543 pj_bzero(dec, sizeof(g722_dec_t));
544
545 return PJ_SUCCESS;
546}
547
548#endif