Line data Source code
1 : /*
2 : * SpanDSP - a series of DSP components for telephony
3 : *
4 : * g722_encode.c - The ITU G.722 codec, encode part.
5 : *
6 : * Written by Steve Underwood <steveu@coppice.org>
7 : *
8 : * Copyright (C) 2005 Steve Underwood
9 : *
10 : * All rights reserved.
11 : *
12 : * Despite my general liking of the GPL, I place my own contributions
13 : * to this code in the public domain for the benefit of all mankind -
14 : * even the slimy ones who might try to proprietize my work and use it
15 : * to my detriment.
16 : *
17 : * Based on a single channel 64kbps only G.722 codec which is:
18 : *
19 : ***** Copyright (c) CMU 1993 *****
20 : * Computer Science, Speech Group
21 : * Chengxiang Lu and Alex Hauptmann
22 : *
23 : * $Id: g722_encode.c,v 1.14 2006/07/07 16:37:49 steveu Exp $
24 : *
25 : * Modifications for WebRtc, 2011/04/28, by tlegrand:
26 : * -Removed usage of inttypes.h and tgmath.h
27 : * -Changed to use WebRtc types
28 : * -Added option to run encoder bitexact with ITU-T reference implementation
29 : */
30 :
31 : /*! \file */
32 :
33 : #include <memory.h>
34 : #include <stdio.h>
35 : #include <stdlib.h>
36 :
37 : #include "g722_enc_dec.h"
38 : #include "webrtc/typedefs.h"
39 :
40 : #if !defined(FALSE)
41 : #define FALSE 0
42 : #endif
43 : #if !defined(TRUE)
44 : #define TRUE (!FALSE)
45 : #endif
46 :
47 0 : static __inline int16_t saturate(int32_t amp)
48 : {
49 : int16_t amp16;
50 :
51 : /* Hopefully this is optimised for the common case - not clipping */
52 0 : amp16 = (int16_t) amp;
53 0 : if (amp == amp16)
54 0 : return amp16;
55 0 : if (amp > WEBRTC_INT16_MAX)
56 0 : return WEBRTC_INT16_MAX;
57 0 : return WEBRTC_INT16_MIN;
58 : }
59 : /*- End of function --------------------------------------------------------*/
60 :
61 0 : static void block4(G722EncoderState *s, int band, int d)
62 : {
63 : int wd1;
64 : int wd2;
65 : int wd3;
66 : int i;
67 :
68 : /* Block 4, RECONS */
69 0 : s->band[band].d[0] = d;
70 0 : s->band[band].r[0] = saturate(s->band[band].s + d);
71 :
72 : /* Block 4, PARREC */
73 0 : s->band[band].p[0] = saturate(s->band[band].sz + d);
74 :
75 : /* Block 4, UPPOL2 */
76 0 : for (i = 0; i < 3; i++)
77 0 : s->band[band].sg[i] = s->band[band].p[i] >> 15;
78 0 : wd1 = saturate(s->band[band].a[1] << 2);
79 :
80 0 : wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
81 0 : if (wd2 > 32767)
82 0 : wd2 = 32767;
83 0 : wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
84 0 : wd3 += (s->band[band].a[2]*32512) >> 15;
85 0 : if (wd3 > 12288)
86 0 : wd3 = 12288;
87 0 : else if (wd3 < -12288)
88 0 : wd3 = -12288;
89 0 : s->band[band].ap[2] = wd3;
90 :
91 : /* Block 4, UPPOL1 */
92 0 : s->band[band].sg[0] = s->band[band].p[0] >> 15;
93 0 : s->band[band].sg[1] = s->band[band].p[1] >> 15;
94 0 : wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
95 0 : wd2 = (s->band[band].a[1]*32640) >> 15;
96 :
97 0 : s->band[band].ap[1] = saturate(wd1 + wd2);
98 0 : wd3 = saturate(15360 - s->band[band].ap[2]);
99 0 : if (s->band[band].ap[1] > wd3)
100 0 : s->band[band].ap[1] = wd3;
101 0 : else if (s->band[band].ap[1] < -wd3)
102 0 : s->band[band].ap[1] = -wd3;
103 :
104 : /* Block 4, UPZERO */
105 0 : wd1 = (d == 0) ? 0 : 128;
106 0 : s->band[band].sg[0] = d >> 15;
107 0 : for (i = 1; i < 7; i++)
108 : {
109 0 : s->band[band].sg[i] = s->band[band].d[i] >> 15;
110 0 : wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
111 0 : wd3 = (s->band[band].b[i]*32640) >> 15;
112 0 : s->band[band].bp[i] = saturate(wd2 + wd3);
113 : }
114 :
115 : /* Block 4, DELAYA */
116 0 : for (i = 6; i > 0; i--)
117 : {
118 0 : s->band[band].d[i] = s->band[band].d[i - 1];
119 0 : s->band[band].b[i] = s->band[band].bp[i];
120 : }
121 :
122 0 : for (i = 2; i > 0; i--)
123 : {
124 0 : s->band[band].r[i] = s->band[band].r[i - 1];
125 0 : s->band[band].p[i] = s->band[band].p[i - 1];
126 0 : s->band[band].a[i] = s->band[band].ap[i];
127 : }
128 :
129 : /* Block 4, FILTEP */
130 0 : wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
131 0 : wd1 = (s->band[band].a[1]*wd1) >> 15;
132 0 : wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
133 0 : wd2 = (s->band[band].a[2]*wd2) >> 15;
134 0 : s->band[band].sp = saturate(wd1 + wd2);
135 :
136 : /* Block 4, FILTEZ */
137 0 : s->band[band].sz = 0;
138 0 : for (i = 6; i > 0; i--)
139 : {
140 0 : wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
141 0 : s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
142 : }
143 0 : s->band[band].sz = saturate(s->band[band].sz);
144 :
145 : /* Block 4, PREDIC */
146 0 : s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
147 0 : }
148 : /*- End of function --------------------------------------------------------*/
149 :
150 0 : G722EncoderState* WebRtc_g722_encode_init(G722EncoderState* s,
151 : int rate,
152 : int options) {
153 0 : if (s == NULL)
154 : {
155 0 : if ((s = (G722EncoderState *) malloc(sizeof(*s))) == NULL)
156 0 : return NULL;
157 : }
158 0 : memset(s, 0, sizeof(*s));
159 0 : if (rate == 48000)
160 0 : s->bits_per_sample = 6;
161 0 : else if (rate == 56000)
162 0 : s->bits_per_sample = 7;
163 : else
164 0 : s->bits_per_sample = 8;
165 0 : if ((options & G722_SAMPLE_RATE_8000))
166 0 : s->eight_k = TRUE;
167 0 : if ((options & G722_PACKED) && s->bits_per_sample != 8)
168 0 : s->packed = TRUE;
169 : else
170 0 : s->packed = FALSE;
171 0 : s->band[0].det = 32;
172 0 : s->band[1].det = 8;
173 0 : return s;
174 : }
175 : /*- End of function --------------------------------------------------------*/
176 :
177 0 : int WebRtc_g722_encode_release(G722EncoderState *s)
178 : {
179 0 : free(s);
180 0 : return 0;
181 : }
182 : /*- End of function --------------------------------------------------------*/
183 :
184 : /* WebRtc, tlegrand:
185 : * Only define the following if bit-exactness with reference implementation
186 : * is needed. Will only have any effect if input signal is saturated.
187 : */
188 : //#define RUN_LIKE_REFERENCE_G722
189 : #ifdef RUN_LIKE_REFERENCE_G722
190 : int16_t limitValues (int16_t rl)
191 : {
192 :
193 : int16_t yl;
194 :
195 : yl = (rl > 16383) ? 16383 : ((rl < -16384) ? -16384 : rl);
196 :
197 : return (yl);
198 : }
199 : #endif
200 :
201 0 : size_t WebRtc_g722_encode(G722EncoderState *s, uint8_t g722_data[],
202 : const int16_t amp[], size_t len)
203 : {
204 : static const int q6[32] =
205 : {
206 : 0, 35, 72, 110, 150, 190, 233, 276,
207 : 323, 370, 422, 473, 530, 587, 650, 714,
208 : 786, 858, 940, 1023, 1121, 1219, 1339, 1458,
209 : 1612, 1765, 1980, 2195, 2557, 2919, 0, 0
210 : };
211 : static const int iln[32] =
212 : {
213 : 0, 63, 62, 31, 30, 29, 28, 27,
214 : 26, 25, 24, 23, 22, 21, 20, 19,
215 : 18, 17, 16, 15, 14, 13, 12, 11,
216 : 10, 9, 8, 7, 6, 5, 4, 0
217 : };
218 : static const int ilp[32] =
219 : {
220 : 0, 61, 60, 59, 58, 57, 56, 55,
221 : 54, 53, 52, 51, 50, 49, 48, 47,
222 : 46, 45, 44, 43, 42, 41, 40, 39,
223 : 38, 37, 36, 35, 34, 33, 32, 0
224 : };
225 : static const int wl[8] =
226 : {
227 : -60, -30, 58, 172, 334, 538, 1198, 3042
228 : };
229 : static const int rl42[16] =
230 : {
231 : 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
232 : };
233 : static const int ilb[32] =
234 : {
235 : 2048, 2093, 2139, 2186, 2233, 2282, 2332,
236 : 2383, 2435, 2489, 2543, 2599, 2656, 2714,
237 : 2774, 2834, 2896, 2960, 3025, 3091, 3158,
238 : 3228, 3298, 3371, 3444, 3520, 3597, 3676,
239 : 3756, 3838, 3922, 4008
240 : };
241 : static const int qm4[16] =
242 : {
243 : 0, -20456, -12896, -8968,
244 : -6288, -4240, -2584, -1200,
245 : 20456, 12896, 8968, 6288,
246 : 4240, 2584, 1200, 0
247 : };
248 : static const int qm2[4] =
249 : {
250 : -7408, -1616, 7408, 1616
251 : };
252 : static const int qmf_coeffs[12] =
253 : {
254 : 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
255 : };
256 : static const int ihn[3] = {0, 1, 0};
257 : static const int ihp[3] = {0, 3, 2};
258 : static const int wh[3] = {0, -214, 798};
259 : static const int rh2[4] = {2, 1, 2, 1};
260 :
261 : int dlow;
262 : int dhigh;
263 : int el;
264 : int wd;
265 : int wd1;
266 : int ril;
267 : int wd2;
268 : int il4;
269 : int ih2;
270 : int wd3;
271 : int eh;
272 : int mih;
273 : int i;
274 : size_t j;
275 : /* Low and high band PCM from the QMF */
276 : int xlow;
277 : int xhigh;
278 : size_t g722_bytes;
279 : /* Even and odd tap accumulators */
280 : int sumeven;
281 : int sumodd;
282 : int ihigh;
283 : int ilow;
284 : int code;
285 :
286 0 : g722_bytes = 0;
287 0 : xhigh = 0;
288 0 : for (j = 0; j < len; )
289 : {
290 0 : if (s->itu_test_mode)
291 : {
292 0 : xlow =
293 0 : xhigh = amp[j++] >> 1;
294 : }
295 : else
296 : {
297 0 : if (s->eight_k)
298 : {
299 : /* We shift by 1 to allow for the 15 bit input to the G.722 algorithm. */
300 0 : xlow = amp[j++] >> 1;
301 : }
302 : else
303 : {
304 : /* Apply the transmit QMF */
305 : /* Shuffle the buffer down */
306 0 : for (i = 0; i < 22; i++)
307 0 : s->x[i] = s->x[i + 2];
308 0 : s->x[22] = amp[j++];
309 0 : s->x[23] = amp[j++];
310 :
311 : /* Discard every other QMF output */
312 0 : sumeven = 0;
313 0 : sumodd = 0;
314 0 : for (i = 0; i < 12; i++)
315 : {
316 0 : sumodd += s->x[2*i]*qmf_coeffs[i];
317 0 : sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
318 : }
319 : /* We shift by 12 to allow for the QMF filters (DC gain = 4096), plus 1
320 : to allow for us summing two filters, plus 1 to allow for the 15 bit
321 : input to the G.722 algorithm. */
322 0 : xlow = (sumeven + sumodd) >> 14;
323 0 : xhigh = (sumeven - sumodd) >> 14;
324 :
325 : #ifdef RUN_LIKE_REFERENCE_G722
326 : /* The following lines are only used to verify bit-exactness
327 : * with reference implementation of G.722. Higher precision
328 : * is achieved without limiting the values.
329 : */
330 : xlow = limitValues(xlow);
331 : xhigh = limitValues(xhigh);
332 : #endif
333 : }
334 : }
335 : /* Block 1L, SUBTRA */
336 0 : el = saturate(xlow - s->band[0].s);
337 :
338 : /* Block 1L, QUANTL */
339 0 : wd = (el >= 0) ? el : -(el + 1);
340 :
341 0 : for (i = 1; i < 30; i++)
342 : {
343 0 : wd1 = (q6[i]*s->band[0].det) >> 12;
344 0 : if (wd < wd1)
345 0 : break;
346 : }
347 0 : ilow = (el < 0) ? iln[i] : ilp[i];
348 :
349 : /* Block 2L, INVQAL */
350 0 : ril = ilow >> 2;
351 0 : wd2 = qm4[ril];
352 0 : dlow = (s->band[0].det*wd2) >> 15;
353 :
354 : /* Block 3L, LOGSCL */
355 0 : il4 = rl42[ril];
356 0 : wd = (s->band[0].nb*127) >> 7;
357 0 : s->band[0].nb = wd + wl[il4];
358 0 : if (s->band[0].nb < 0)
359 0 : s->band[0].nb = 0;
360 0 : else if (s->band[0].nb > 18432)
361 0 : s->band[0].nb = 18432;
362 :
363 : /* Block 3L, SCALEL */
364 0 : wd1 = (s->band[0].nb >> 6) & 31;
365 0 : wd2 = 8 - (s->band[0].nb >> 11);
366 0 : wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
367 0 : s->band[0].det = wd3 << 2;
368 :
369 0 : block4(s, 0, dlow);
370 :
371 0 : if (s->eight_k)
372 : {
373 : /* Just leave the high bits as zero */
374 0 : code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
375 : }
376 : else
377 : {
378 : /* Block 1H, SUBTRA */
379 0 : eh = saturate(xhigh - s->band[1].s);
380 :
381 : /* Block 1H, QUANTH */
382 0 : wd = (eh >= 0) ? eh : -(eh + 1);
383 0 : wd1 = (564*s->band[1].det) >> 12;
384 0 : mih = (wd >= wd1) ? 2 : 1;
385 0 : ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
386 :
387 : /* Block 2H, INVQAH */
388 0 : wd2 = qm2[ihigh];
389 0 : dhigh = (s->band[1].det*wd2) >> 15;
390 :
391 : /* Block 3H, LOGSCH */
392 0 : ih2 = rh2[ihigh];
393 0 : wd = (s->band[1].nb*127) >> 7;
394 0 : s->band[1].nb = wd + wh[ih2];
395 0 : if (s->band[1].nb < 0)
396 0 : s->band[1].nb = 0;
397 0 : else if (s->band[1].nb > 22528)
398 0 : s->band[1].nb = 22528;
399 :
400 : /* Block 3H, SCALEH */
401 0 : wd1 = (s->band[1].nb >> 6) & 31;
402 0 : wd2 = 10 - (s->band[1].nb >> 11);
403 0 : wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
404 0 : s->band[1].det = wd3 << 2;
405 :
406 0 : block4(s, 1, dhigh);
407 0 : code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
408 : }
409 :
410 0 : if (s->packed)
411 : {
412 : /* Pack the code bits */
413 0 : s->out_buffer |= (code << s->out_bits);
414 0 : s->out_bits += s->bits_per_sample;
415 0 : if (s->out_bits >= 8)
416 : {
417 0 : g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
418 0 : s->out_bits -= 8;
419 0 : s->out_buffer >>= 8;
420 : }
421 : }
422 : else
423 : {
424 0 : g722_data[g722_bytes++] = (uint8_t) code;
425 : }
426 : }
427 0 : return g722_bytes;
428 : }
429 : /*- End of function --------------------------------------------------------*/
430 : /*- End of file ------------------------------------------------------------*/
|