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 "typedefs.h"  // NOLINT(build/include)
39 
40 #if !defined(FALSE)
41 #define FALSE 0
42 #endif
43 #if !defined(TRUE)
44 #define TRUE (!FALSE)
45 #endif
46 
saturate(int32_t amp)47 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     amp16 = (int16_t) amp;
53     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 
block4(G722EncoderState * s,int band,int d)61 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     s->band[band].d[0] = d;
70     s->band[band].r[0] = saturate(s->band[band].s + d);
71 
72     /* Block 4, PARREC */
73     s->band[band].p[0] = saturate(s->band[band].sz + d);
74 
75     /* Block 4, UPPOL2 */
76     for (i = 0;  i < 3;  i++)
77         s->band[band].sg[i] = s->band[band].p[i] >> 15;
78     wd1 = saturate(s->band[band].a[1] * 4);
79 
80     wd2 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  -wd1  :  wd1;
81     if (wd2 > 32767)
82         wd2 = 32767;
83     wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2])  ?  128  :  -128);
84     wd3 += (s->band[band].a[2]*32512) >> 15;
85     if (wd3 > 12288)
86         wd3 = 12288;
87     else if (wd3 < -12288)
88         wd3 = -12288;
89     s->band[band].ap[2] = wd3;
90 
91     /* Block 4, UPPOL1 */
92     s->band[band].sg[0] = s->band[band].p[0] >> 15;
93     s->band[band].sg[1] = s->band[band].p[1] >> 15;
94     wd1 = (s->band[band].sg[0] == s->band[band].sg[1])  ?  192  :  -192;
95     wd2 = (s->band[band].a[1]*32640) >> 15;
96 
97     s->band[band].ap[1] = saturate(wd1 + wd2);
98     wd3 = saturate(15360 - s->band[band].ap[2]);
99     if (s->band[band].ap[1] > wd3)
100         s->band[band].ap[1] = wd3;
101     else if (s->band[band].ap[1] < -wd3)
102         s->band[band].ap[1] = -wd3;
103 
104     /* Block 4, UPZERO */
105     wd1 = (d == 0)  ?  0  :  128;
106     s->band[band].sg[0] = d >> 15;
107     for (i = 1;  i < 7;  i++)
108     {
109         s->band[band].sg[i] = s->band[band].d[i] >> 15;
110         wd2 = (s->band[band].sg[i] == s->band[band].sg[0])  ?  wd1  :  -wd1;
111         wd3 = (s->band[band].b[i]*32640) >> 15;
112         s->band[band].bp[i] = saturate(wd2 + wd3);
113     }
114 
115     /* Block 4, DELAYA */
116     for (i = 6;  i > 0;  i--)
117     {
118         s->band[band].d[i] = s->band[band].d[i - 1];
119         s->band[band].b[i] = s->band[band].bp[i];
120     }
121 
122     for (i = 2;  i > 0;  i--)
123     {
124         s->band[band].r[i] = s->band[band].r[i - 1];
125         s->band[band].p[i] = s->band[band].p[i - 1];
126         s->band[band].a[i] = s->band[band].ap[i];
127     }
128 
129     /* Block 4, FILTEP */
130     wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
131     wd1 = (s->band[band].a[1]*wd1) >> 15;
132     wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
133     wd2 = (s->band[band].a[2]*wd2) >> 15;
134     s->band[band].sp = saturate(wd1 + wd2);
135 
136     /* Block 4, FILTEZ */
137     s->band[band].sz = 0;
138     for (i = 6;  i > 0;  i--)
139     {
140         wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
141         s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
142     }
143     s->band[band].sz = saturate(s->band[band].sz);
144 
145     /* Block 4, PREDIC */
146     s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
147 }
148 /*- End of function --------------------------------------------------------*/
149 
WebRtc_g722_encode_init(G722EncoderState * s,int rate,int options)150 G722EncoderState* WebRtc_g722_encode_init(G722EncoderState* s,
151                                           int rate,
152                                           int options) {
153     if (s == NULL)
154     {
155         if ((s = (G722EncoderState *) malloc(sizeof(*s))) == NULL)
156             return NULL;
157     }
158     memset(s, 0, sizeof(*s));
159     if (rate == 48000)
160         s->bits_per_sample = 6;
161     else if (rate == 56000)
162         s->bits_per_sample = 7;
163     else
164         s->bits_per_sample = 8;
165     if ((options & G722_SAMPLE_RATE_8000))
166         s->eight_k = TRUE;
167     if ((options & G722_PACKED)  &&  s->bits_per_sample != 8)
168         s->packed = TRUE;
169     else
170         s->packed = FALSE;
171     s->band[0].det = 32;
172     s->band[1].det = 8;
173     return s;
174 }
175 /*- End of function --------------------------------------------------------*/
176 
WebRtc_g722_encode_release(G722EncoderState * s)177 int WebRtc_g722_encode_release(G722EncoderState *s)
178 {
179     free(s);
180     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
limitValues(int16_t rl)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 
WebRtc_g722_encode(G722EncoderState * s,uint8_t g722_data[],const int16_t amp[],size_t len)201 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     g722_bytes = 0;
287     xhigh = 0;
288     for (j = 0;  j < len;  )
289     {
290         if (s->itu_test_mode)
291         {
292             xlow =
293             xhigh = amp[j++] >> 1;
294         }
295         else
296         {
297             if (s->eight_k)
298             {
299                 /* We shift by 1 to allow for the 15 bit input to the G.722 algorithm. */
300                 xlow = amp[j++] >> 1;
301             }
302             else
303             {
304                 /* Apply the transmit QMF */
305                 /* Shuffle the buffer down */
306                 for (i = 0;  i < 22;  i++)
307                     s->x[i] = s->x[i + 2];
308                 s->x[22] = amp[j++];
309                 s->x[23] = amp[j++];
310 
311                 /* Discard every other QMF output */
312                 sumeven = 0;
313                 sumodd = 0;
314                 for (i = 0;  i < 12;  i++)
315                 {
316                     sumodd += s->x[2*i]*qmf_coeffs[i];
317                     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                 xlow = (sumeven + sumodd) >> 14;
323                 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         el = saturate(xlow - s->band[0].s);
337 
338         /* Block 1L, QUANTL */
339         wd = (el >= 0)  ?  el  :  -(el + 1);
340 
341         for (i = 1;  i < 30;  i++)
342         {
343             wd1 = (q6[i]*s->band[0].det) >> 12;
344             if (wd < wd1)
345                 break;
346         }
347         ilow = (el < 0)  ?  iln[i]  :  ilp[i];
348 
349         /* Block 2L, INVQAL */
350         ril = ilow >> 2;
351         wd2 = qm4[ril];
352         dlow = (s->band[0].det*wd2) >> 15;
353 
354         /* Block 3L, LOGSCL */
355         il4 = rl42[ril];
356         wd = (s->band[0].nb*127) >> 7;
357         s->band[0].nb = wd + wl[il4];
358         if (s->band[0].nb < 0)
359             s->band[0].nb = 0;
360         else if (s->band[0].nb > 18432)
361             s->band[0].nb = 18432;
362 
363         /* Block 3L, SCALEL */
364         wd1 = (s->band[0].nb >> 6) & 31;
365         wd2 = 8 - (s->band[0].nb >> 11);
366         wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
367         s->band[0].det = wd3 << 2;
368 
369         block4(s, 0, dlow);
370 
371         if (s->eight_k)
372         {
373             /* Just leave the high bits as zero */
374             code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
375         }
376         else
377         {
378             /* Block 1H, SUBTRA */
379             eh = saturate(xhigh - s->band[1].s);
380 
381             /* Block 1H, QUANTH */
382             wd = (eh >= 0)  ?  eh  :  -(eh + 1);
383             wd1 = (564*s->band[1].det) >> 12;
384             mih = (wd >= wd1)  ?  2  :  1;
385             ihigh = (eh < 0)  ?  ihn[mih]  :  ihp[mih];
386 
387             /* Block 2H, INVQAH */
388             wd2 = qm2[ihigh];
389             dhigh = (s->band[1].det*wd2) >> 15;
390 
391             /* Block 3H, LOGSCH */
392             ih2 = rh2[ihigh];
393             wd = (s->band[1].nb*127) >> 7;
394             s->band[1].nb = wd + wh[ih2];
395             if (s->band[1].nb < 0)
396                 s->band[1].nb = 0;
397             else if (s->band[1].nb > 22528)
398                 s->band[1].nb = 22528;
399 
400             /* Block 3H, SCALEH */
401             wd1 = (s->band[1].nb >> 6) & 31;
402             wd2 = 10 - (s->band[1].nb >> 11);
403             wd3 = (wd2 < 0)  ?  (ilb[wd1] << -wd2)  :  (ilb[wd1] >> wd2);
404             s->band[1].det = wd3 << 2;
405 
406             block4(s, 1, dhigh);
407             code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
408         }
409 
410         if (s->packed)
411         {
412             /* Pack the code bits */
413             s->out_buffer |= (code << s->out_bits);
414             s->out_bits += s->bits_per_sample;
415             if (s->out_bits >= 8)
416             {
417                 g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
418                 s->out_bits -= 8;
419                 s->out_buffer >>= 8;
420             }
421         }
422         else
423         {
424             g722_data[g722_bytes++] = (uint8_t) code;
425         }
426     }
427     return g722_bytes;
428 }
429 /*- End of function --------------------------------------------------------*/
430 /*- End of file ------------------------------------------------------------*/
431