Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: webrtc/webrtc/modules/audio_coding/codecs/g722/g722_encode.c @ 0:4bda6873e34c

pub_scrub_3792 tip
Last change on this file since 0:4bda6873e34c was 0:4bda6873e34c, checked in by Michael Prittie <mprittie@…>, 6 years ago

Scrubbed password for publication.

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