blob: 84af1550974f16745f356f0ff5ab2121227bbeeb [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
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 *
Henrik Kjellanderb2528562016-03-29 17:47:19 +020010 * Despite my general liking of the GPL, I place my own contributions
niklase@google.com470e71d2011-07-07 08:21:25 +000011 * to this code in the public domain for the benefit of all mankind -
12 * even the slimy ones who might try to proprietize my work and use it
13 * to my detriment.
14 *
15 * Based in part on a single channel G.722 codec which is:
16 *
17 * Copyright (c) CMU 1993
18 * Computer Science, Speech Group
19 * Chengxiang Lu and Alex Hauptmann
20 *
21 * $Id: g722_decode.c,v 1.15 2006/07/07 16:37:49 steveu Exp $
22 *
23 * Modifications for WebRtc, 2011/04/28, by tlegrand:
24 * -Removed usage of inttypes.h and tgmath.h
25 * -Changed to use WebRtc types
26 * -Changed __inline__ to __inline
27 * -Added saturation check on output
28 */
29
30/*! \file */
31
32
henrike@webrtc.org1b8b4c42014-09-03 19:42:16 +000033#include <memory.h>
andresp@webrtc.org262e6762014-09-04 13:28:48 +000034#include <stdio.h>
niklase@google.com470e71d2011-07-07 08:21:25 +000035#include <stdlib.h>
36
niklase@google.com470e71d2011-07-07 08:21:25 +000037#include "g722_enc_dec.h"
Mirko Bonadei71207422017-09-15 13:58:09 +020038#include "typedefs.h" // NOLINT(build/include)
niklase@google.com470e71d2011-07-07 08:21:25 +000039
40#if !defined(FALSE)
41#define FALSE 0
42#endif
43#if !defined(TRUE)
44#define TRUE (!FALSE)
45#endif
46
pbos@webrtc.org0946a562013-04-09 00:28:06 +000047static __inline int16_t saturate(int32_t amp)
niklase@google.com470e71d2011-07-07 08:21:25 +000048{
pbos@webrtc.org0946a562013-04-09 00:28:06 +000049 int16_t amp16;
niklase@google.com470e71d2011-07-07 08:21:25 +000050
51 /* Hopefully this is optimised for the common case - not clipping */
pbos@webrtc.org0946a562013-04-09 00:28:06 +000052 amp16 = (int16_t) amp;
niklase@google.com470e71d2011-07-07 08:21:25 +000053 if (amp == amp16)
54 return amp16;
55 if (amp > WEBRTC_INT16_MAX)
56 return WEBRTC_INT16_MAX;
57 return WEBRTC_INT16_MIN;
58}
59/*- End of function --------------------------------------------------------*/
60
pbos@webrtc.orgeb544462014-12-17 15:23:29 +000061static void block4(G722DecoderState *s, int band, int d);
niklase@google.com470e71d2011-07-07 08:21:25 +000062
pbos@webrtc.orgeb544462014-12-17 15:23:29 +000063static void block4(G722DecoderState *s, int band, int d)
niklase@google.com470e71d2011-07-07 08:21:25 +000064{
65 int wd1;
66 int wd2;
67 int wd3;
68 int i;
69
70 /* Block 4, RECONS */
71 s->band[band].d[0] = d;
72 s->band[band].r[0] = saturate(s->band[band].s + d);
73
74 /* Block 4, PARREC */
75 s->band[band].p[0] = saturate(s->band[band].sz + d);
76
77 /* Block 4, UPPOL2 */
78 for (i = 0; i < 3; i++)
79 s->band[band].sg[i] = s->band[band].p[i] >> 15;
kwibergbc807442016-10-31 02:26:10 -070080 wd1 = saturate(s->band[band].a[1] * 4);
niklase@google.com470e71d2011-07-07 08:21:25 +000081
82 wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
83 if (wd2 > 32767)
84 wd2 = 32767;
85 wd3 = (s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128;
86 wd3 += (wd2 >> 7);
87 wd3 += (s->band[band].a[2]*32512) >> 15;
88 if (wd3 > 12288)
89 wd3 = 12288;
90 else if (wd3 < -12288)
91 wd3 = -12288;
92 s->band[band].ap[2] = wd3;
93
94 /* Block 4, UPPOL1 */
95 s->band[band].sg[0] = s->band[band].p[0] >> 15;
96 s->band[band].sg[1] = s->band[band].p[1] >> 15;
97 wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
98 wd2 = (s->band[band].a[1]*32640) >> 15;
99
100 s->band[band].ap[1] = saturate(wd1 + wd2);
101 wd3 = saturate(15360 - s->band[band].ap[2]);
102 if (s->band[band].ap[1] > wd3)
103 s->band[band].ap[1] = wd3;
104 else if (s->band[band].ap[1] < -wd3)
105 s->band[band].ap[1] = -wd3;
106
107 /* Block 4, UPZERO */
108 wd1 = (d == 0) ? 0 : 128;
109 s->band[band].sg[0] = d >> 15;
110 for (i = 1; i < 7; i++)
111 {
112 s->band[band].sg[i] = s->band[band].d[i] >> 15;
113 wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
114 wd3 = (s->band[band].b[i]*32640) >> 15;
115 s->band[band].bp[i] = saturate(wd2 + wd3);
116 }
117
118 /* Block 4, DELAYA */
119 for (i = 6; i > 0; i--)
120 {
121 s->band[band].d[i] = s->band[band].d[i - 1];
122 s->band[band].b[i] = s->band[band].bp[i];
123 }
Henrik Kjellanderb2528562016-03-29 17:47:19 +0200124
niklase@google.com470e71d2011-07-07 08:21:25 +0000125 for (i = 2; i > 0; i--)
126 {
127 s->band[band].r[i] = s->band[band].r[i - 1];
128 s->band[band].p[i] = s->band[band].p[i - 1];
129 s->band[band].a[i] = s->band[band].ap[i];
130 }
131
132 /* Block 4, FILTEP */
133 wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
134 wd1 = (s->band[band].a[1]*wd1) >> 15;
135 wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
136 wd2 = (s->band[band].a[2]*wd2) >> 15;
137 s->band[band].sp = saturate(wd1 + wd2);
138
139 /* Block 4, FILTEZ */
140 s->band[band].sz = 0;
141 for (i = 6; i > 0; i--)
142 {
143 wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
144 s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
145 }
146 s->band[band].sz = saturate(s->band[band].sz);
147
148 /* Block 4, PREDIC */
149 s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
150}
151/*- End of function --------------------------------------------------------*/
152
pbos@webrtc.orgeb544462014-12-17 15:23:29 +0000153G722DecoderState* WebRtc_g722_decode_init(G722DecoderState* s,
154 int rate,
155 int options) {
Karl Wiberg43766482015-08-27 15:22:11 +0200156 s = s ? s : malloc(sizeof(*s));
niklase@google.com470e71d2011-07-07 08:21:25 +0000157 memset(s, 0, sizeof(*s));
158 if (rate == 48000)
159 s->bits_per_sample = 6;
160 else if (rate == 56000)
161 s->bits_per_sample = 7;
162 else
163 s->bits_per_sample = 8;
164 if ((options & G722_SAMPLE_RATE_8000))
165 s->eight_k = TRUE;
166 if ((options & G722_PACKED) && s->bits_per_sample != 8)
167 s->packed = TRUE;
168 else
169 s->packed = FALSE;
170 s->band[0].det = 32;
171 s->band[1].det = 8;
172 return s;
173}
174/*- End of function --------------------------------------------------------*/
175
pbos@webrtc.orgeb544462014-12-17 15:23:29 +0000176int WebRtc_g722_decode_release(G722DecoderState *s)
niklase@google.com470e71d2011-07-07 08:21:25 +0000177{
178 free(s);
179 return 0;
180}
181/*- End of function --------------------------------------------------------*/
182
Peter Kastingdce40cf2015-08-24 14:52:23 -0700183size_t WebRtc_g722_decode(G722DecoderState *s, int16_t amp[],
184 const uint8_t g722_data[], size_t len)
niklase@google.com470e71d2011-07-07 08:21:25 +0000185{
186 static const int wl[8] = {-60, -30, 58, 172, 334, 538, 1198, 3042 };
pwestin@webrtc.orgebcb6422011-12-22 12:20:06 +0000187 static const int rl42[16] = {0, 7, 6, 5, 4, 3, 2, 1,
188 7, 6, 5, 4, 3, 2, 1, 0 };
niklase@google.com470e71d2011-07-07 08:21:25 +0000189 static const int ilb[32] =
190 {
191 2048, 2093, 2139, 2186, 2233, 2282, 2332,
192 2383, 2435, 2489, 2543, 2599, 2656, 2714,
193 2774, 2834, 2896, 2960, 3025, 3091, 3158,
194 3228, 3298, 3371, 3444, 3520, 3597, 3676,
195 3756, 3838, 3922, 4008
196 };
197 static const int wh[3] = {0, -214, 798};
198 static const int rh2[4] = {2, 1, 2, 1};
199 static const int qm2[4] = {-7408, -1616, 7408, 1616};
Henrik Kjellanderb2528562016-03-29 17:47:19 +0200200 static const int qm4[16] =
niklase@google.com470e71d2011-07-07 08:21:25 +0000201 {
Henrik Kjellanderb2528562016-03-29 17:47:19 +0200202 0, -20456, -12896, -8968,
niklase@google.com470e71d2011-07-07 08:21:25 +0000203 -6288, -4240, -2584, -1200,
204 20456, 12896, 8968, 6288,
205 4240, 2584, 1200, 0
206 };
207 static const int qm5[32] =
208 {
209 -280, -280, -23352, -17560,
210 -14120, -11664, -9752, -8184,
211 -6864, -5712, -4696, -3784,
212 -2960, -2208, -1520, -880,
213 23352, 17560, 14120, 11664,
214 9752, 8184, 6864, 5712,
215 4696, 3784, 2960, 2208,
216 1520, 880, 280, -280
217 };
218 static const int qm6[64] =
219 {
220 -136, -136, -136, -136,
221 -24808, -21904, -19008, -16704,
222 -14984, -13512, -12280, -11192,
223 -10232, -9360, -8576, -7856,
224 -7192, -6576, -6000, -5456,
225 -4944, -4464, -4008, -3576,
226 -3168, -2776, -2400, -2032,
227 -1688, -1360, -1040, -728,
228 24808, 21904, 19008, 16704,
229 14984, 13512, 12280, 11192,
230 10232, 9360, 8576, 7856,
231 7192, 6576, 6000, 5456,
232 4944, 4464, 4008, 3576,
233 3168, 2776, 2400, 2032,
234 1688, 1360, 1040, 728,
235 432, 136, -432, -136
236 };
237 static const int qmf_coeffs[12] =
238 {
239 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
240 };
241
242 int dlowt;
243 int rlow;
244 int ihigh;
245 int dhigh;
246 int rhigh;
247 int xout1;
248 int xout2;
249 int wd1;
250 int wd2;
251 int wd3;
252 int code;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700253 size_t outlen;
niklase@google.com470e71d2011-07-07 08:21:25 +0000254 int i;
Peter Kastingdce40cf2015-08-24 14:52:23 -0700255 size_t j;
niklase@google.com470e71d2011-07-07 08:21:25 +0000256
257 outlen = 0;
258 rhigh = 0;
259 for (j = 0; j < len; )
260 {
261 if (s->packed)
262 {
263 /* Unpack the code bits */
264 if (s->in_bits < s->bits_per_sample)
265 {
266 s->in_buffer |= (g722_data[j++] << s->in_bits);
267 s->in_bits += 8;
268 }
269 code = s->in_buffer & ((1 << s->bits_per_sample) - 1);
270 s->in_buffer >>= s->bits_per_sample;
271 s->in_bits -= s->bits_per_sample;
272 }
273 else
274 {
275 code = g722_data[j++];
276 }
277
278 switch (s->bits_per_sample)
279 {
280 default:
281 case 8:
282 wd1 = code & 0x3F;
283 ihigh = (code >> 6) & 0x03;
284 wd2 = qm6[wd1];
285 wd1 >>= 2;
286 break;
287 case 7:
288 wd1 = code & 0x1F;
289 ihigh = (code >> 5) & 0x03;
290 wd2 = qm5[wd1];
291 wd1 >>= 1;
292 break;
293 case 6:
294 wd1 = code & 0x0F;
295 ihigh = (code >> 4) & 0x03;
296 wd2 = qm4[wd1];
297 break;
298 }
299 /* Block 5L, LOW BAND INVQBL */
300 wd2 = (s->band[0].det*wd2) >> 15;
301 /* Block 5L, RECONS */
302 rlow = s->band[0].s + wd2;
303 /* Block 6L, LIMIT */
304 if (rlow > 16383)
305 rlow = 16383;
306 else if (rlow < -16384)
307 rlow = -16384;
308
309 /* Block 2L, INVQAL */
310 wd2 = qm4[wd1];
311 dlowt = (s->band[0].det*wd2) >> 15;
312
313 /* Block 3L, LOGSCL */
314 wd2 = rl42[wd1];
315 wd1 = (s->band[0].nb*127) >> 7;
316 wd1 += wl[wd2];
317 if (wd1 < 0)
318 wd1 = 0;
319 else if (wd1 > 18432)
320 wd1 = 18432;
321 s->band[0].nb = wd1;
Henrik Kjellanderb2528562016-03-29 17:47:19 +0200322
niklase@google.com470e71d2011-07-07 08:21:25 +0000323 /* Block 3L, SCALEL */
324 wd1 = (s->band[0].nb >> 6) & 31;
325 wd2 = 8 - (s->band[0].nb >> 11);
326 wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
327 s->band[0].det = wd3 << 2;
328
329 block4(s, 0, dlowt);
Henrik Kjellanderb2528562016-03-29 17:47:19 +0200330
niklase@google.com470e71d2011-07-07 08:21:25 +0000331 if (!s->eight_k)
332 {
333 /* Block 2H, INVQAH */
334 wd2 = qm2[ihigh];
335 dhigh = (s->band[1].det*wd2) >> 15;
336 /* Block 5H, RECONS */
337 rhigh = dhigh + s->band[1].s;
338 /* Block 6H, LIMIT */
339 if (rhigh > 16383)
340 rhigh = 16383;
341 else if (rhigh < -16384)
342 rhigh = -16384;
343
344 /* Block 2H, INVQAH */
345 wd2 = rh2[ihigh];
346 wd1 = (s->band[1].nb*127) >> 7;
347 wd1 += wh[wd2];
348 if (wd1 < 0)
349 wd1 = 0;
350 else if (wd1 > 22528)
351 wd1 = 22528;
352 s->band[1].nb = wd1;
Henrik Kjellanderb2528562016-03-29 17:47:19 +0200353
niklase@google.com470e71d2011-07-07 08:21:25 +0000354 /* Block 3H, SCALEH */
355 wd1 = (s->band[1].nb >> 6) & 31;
356 wd2 = 10 - (s->band[1].nb >> 11);
357 wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
358 s->band[1].det = wd3 << 2;
359
360 block4(s, 1, dhigh);
361 }
362
363 if (s->itu_test_mode)
364 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000365 amp[outlen++] = (int16_t) (rlow << 1);
366 amp[outlen++] = (int16_t) (rhigh << 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000367 }
368 else
369 {
370 if (s->eight_k)
371 {
pbos@webrtc.org0946a562013-04-09 00:28:06 +0000372 amp[outlen++] = (int16_t) (rlow << 1);
niklase@google.com470e71d2011-07-07 08:21:25 +0000373 }
374 else
375 {
376 /* Apply the receive QMF */
377 for (i = 0; i < 22; i++)
378 s->x[i] = s->x[i + 2];
379 s->x[22] = rlow + rhigh;
380 s->x[23] = rlow - rhigh;
381
382 xout1 = 0;
383 xout2 = 0;
384 for (i = 0; i < 12; i++)
385 {
386 xout2 += s->x[2*i]*qmf_coeffs[i];
387 xout1 += s->x[2*i + 1]*qmf_coeffs[11 - i];
388 }
389 /* We shift by 12 to allow for the QMF filters (DC gain = 4096), less 1
390 to allow for the 15 bit input to the G.722 algorithm. */
391 /* WebRtc, tlegrand: added saturation */
392 amp[outlen++] = saturate(xout1 >> 11);
393 amp[outlen++] = saturate(xout2 >> 11);
394 }
395 }
396 }
397 return outlen;
398}
399/*- End of function --------------------------------------------------------*/
400/*- End of file ------------------------------------------------------------*/