comparison spandsp-0.0.3/spandsp-0.0.3/src/g722_encode.c @ 5:f762bf195c4b

import spandsp-0.0.3
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 16:00:21 +0200
parents
children
comparison
equal deleted inserted replaced
4:26cd8f1ef0b1 5:f762bf195c4b
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 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2, as
14 * published by the Free Software Foundation.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * Based on a single channel 64kbps only G.722 codec which is:
26 *
27 ***** Copyright (c) CMU 1993 *****
28 * Computer Science, Speech Group
29 * Chengxiang Lu and Alex Hauptmann
30 *
31 * $Id: g722_encode.c,v 1.16 2006/11/19 14:07:24 steveu Exp $
32 */
33
34 /*! \file */
35
36 #ifdef HAVE_CONFIG_H
37 #include <config.h>
38 #endif
39
40 #include <inttypes.h>
41 #include <memory.h>
42 #include <stdlib.h>
43 #if defined(HAVE_TGMATH_H)
44 #include <tgmath.h>
45 #endif
46 #if defined(HAVE_MATH_H)
47 #include <math.h>
48 #endif
49
50 #include "spandsp/telephony.h"
51 #include "spandsp/dc_restore.h"
52 #include "spandsp/g722.h"
53
54 static void block4(g722_encode_state_t *s, int band, int d)
55 {
56 int wd1;
57 int wd2;
58 int wd3;
59 int i;
60
61 /* Block 4, RECONS */
62 s->band[band].d[0] = d;
63 s->band[band].r[0] = saturate(s->band[band].s + d);
64
65 /* Block 4, PARREC */
66 s->band[band].p[0] = saturate(s->band[band].sz + d);
67
68 /* Block 4, UPPOL2 */
69 for (i = 0; i < 3; i++)
70 s->band[band].sg[i] = s->band[band].p[i] >> 15;
71 wd1 = saturate(s->band[band].a[1] << 2);
72
73 wd2 = (s->band[band].sg[0] == s->band[band].sg[1]) ? -wd1 : wd1;
74 if (wd2 > 32767)
75 wd2 = 32767;
76 wd3 = (wd2 >> 7) + ((s->band[band].sg[0] == s->band[band].sg[2]) ? 128 : -128);
77 wd3 += (s->band[band].a[2]*32512) >> 15;
78 if (wd3 > 12288)
79 wd3 = 12288;
80 else if (wd3 < -12288)
81 wd3 = -12288;
82 s->band[band].ap[2] = wd3;
83
84 /* Block 4, UPPOL1 */
85 s->band[band].sg[0] = s->band[band].p[0] >> 15;
86 s->band[band].sg[1] = s->band[band].p[1] >> 15;
87 wd1 = (s->band[band].sg[0] == s->band[band].sg[1]) ? 192 : -192;
88 wd2 = (s->band[band].a[1]*32640) >> 15;
89
90 s->band[band].ap[1] = saturate(wd1 + wd2);
91 wd3 = saturate(15360 - s->band[band].ap[2]);
92 if (s->band[band].ap[1] > wd3)
93 s->band[band].ap[1] = wd3;
94 else if (s->band[band].ap[1] < -wd3)
95 s->band[band].ap[1] = -wd3;
96
97 /* Block 4, UPZERO */
98 wd1 = (d == 0) ? 0 : 128;
99 s->band[band].sg[0] = d >> 15;
100 for (i = 1; i < 7; i++)
101 {
102 s->band[band].sg[i] = s->band[band].d[i] >> 15;
103 wd2 = (s->band[band].sg[i] == s->band[band].sg[0]) ? wd1 : -wd1;
104 wd3 = (s->band[band].b[i]*32640) >> 15;
105 s->band[band].bp[i] = saturate(wd2 + wd3);
106 }
107
108 /* Block 4, DELAYA */
109 for (i = 6; i > 0; i--)
110 {
111 s->band[band].d[i] = s->band[band].d[i - 1];
112 s->band[band].b[i] = s->band[band].bp[i];
113 }
114
115 for (i = 2; i > 0; i--)
116 {
117 s->band[band].r[i] = s->band[band].r[i - 1];
118 s->band[band].p[i] = s->band[band].p[i - 1];
119 s->band[band].a[i] = s->band[band].ap[i];
120 }
121
122 /* Block 4, FILTEP */
123 wd1 = saturate(s->band[band].r[1] + s->band[band].r[1]);
124 wd1 = (s->band[band].a[1]*wd1) >> 15;
125 wd2 = saturate(s->band[band].r[2] + s->band[band].r[2]);
126 wd2 = (s->band[band].a[2]*wd2) >> 15;
127 s->band[band].sp = saturate(wd1 + wd2);
128
129 /* Block 4, FILTEZ */
130 s->band[band].sz = 0;
131 for (i = 6; i > 0; i--)
132 {
133 wd1 = saturate(s->band[band].d[i] + s->band[band].d[i]);
134 s->band[band].sz += (s->band[band].b[i]*wd1) >> 15;
135 }
136 s->band[band].sz = saturate(s->band[band].sz);
137
138 /* Block 4, PREDIC */
139 s->band[band].s = saturate(s->band[band].sp + s->band[band].sz);
140 }
141 /*- End of function --------------------------------------------------------*/
142
143 g722_encode_state_t *g722_encode_init(g722_encode_state_t *s, int rate, int options)
144 {
145 if (s == NULL)
146 {
147 if ((s = (g722_encode_state_t *) malloc(sizeof(*s))) == NULL)
148 return NULL;
149 }
150 memset(s, 0, sizeof(*s));
151 if (rate == 48000)
152 s->bits_per_sample = 6;
153 else if (rate == 56000)
154 s->bits_per_sample = 7;
155 else
156 s->bits_per_sample = 8;
157 if ((options & G722_SAMPLE_RATE_8000))
158 s->eight_k = TRUE;
159 if ((options & G722_PACKED) && s->bits_per_sample != 8)
160 s->packed = TRUE;
161 else
162 s->packed = FALSE;
163 s->band[0].det = 32;
164 s->band[1].det = 8;
165 return s;
166 }
167 /*- End of function --------------------------------------------------------*/
168
169 int g722_encode_release(g722_encode_state_t *s)
170 {
171 free(s);
172 return 0;
173 }
174 /*- End of function --------------------------------------------------------*/
175
176 int g722_encode(g722_encode_state_t *s, uint8_t g722_data[], const int16_t amp[], int len)
177 {
178 static const int q6[32] =
179 {
180 0, 35, 72, 110, 150, 190, 233, 276,
181 323, 370, 422, 473, 530, 587, 650, 714,
182 786, 858, 940, 1023, 1121, 1219, 1339, 1458,
183 1612, 1765, 1980, 2195, 2557, 2919, 0, 0
184 };
185 static const int iln[32] =
186 {
187 0, 63, 62, 31, 30, 29, 28, 27,
188 26, 25, 24, 23, 22, 21, 20, 19,
189 18, 17, 16, 15, 14, 13, 12, 11,
190 10, 9, 8, 7, 6, 5, 4, 0
191 };
192 static const int ilp[32] =
193 {
194 0, 61, 60, 59, 58, 57, 56, 55,
195 54, 53, 52, 51, 50, 49, 48, 47,
196 46, 45, 44, 43, 42, 41, 40, 39,
197 38, 37, 36, 35, 34, 33, 32, 0
198 };
199 static const int wl[8] =
200 {
201 -60, -30, 58, 172, 334, 538, 1198, 3042
202 };
203 static const int rl42[16] =
204 {
205 0, 7, 6, 5, 4, 3, 2, 1, 7, 6, 5, 4, 3, 2, 1, 0
206 };
207 static const int ilb[32] =
208 {
209 2048, 2093, 2139, 2186, 2233, 2282, 2332,
210 2383, 2435, 2489, 2543, 2599, 2656, 2714,
211 2774, 2834, 2896, 2960, 3025, 3091, 3158,
212 3228, 3298, 3371, 3444, 3520, 3597, 3676,
213 3756, 3838, 3922, 4008
214 };
215 static const int qm4[16] =
216 {
217 0, -20456, -12896, -8968,
218 -6288, -4240, -2584, -1200,
219 20456, 12896, 8968, 6288,
220 4240, 2584, 1200, 0
221 };
222 static const int qm2[4] =
223 {
224 -7408, -1616, 7408, 1616
225 };
226 static const int qmf_coeffs[12] =
227 {
228 3, -11, 12, 32, -210, 951, 3876, -805, 362, -156, 53, -11,
229 };
230 static const int ihn[3] = {0, 1, 0};
231 static const int ihp[3] = {0, 3, 2};
232 static const int wh[3] = {0, -214, 798};
233 static const int rh2[4] = {2, 1, 2, 1};
234
235 int dlow;
236 int dhigh;
237 int el;
238 int wd;
239 int wd1;
240 int ril;
241 int wd2;
242 int il4;
243 int ih2;
244 int wd3;
245 int eh;
246 int mih;
247 int i;
248 int j;
249 /* Low and high band PCM from the QMF */
250 int xlow;
251 int xhigh;
252 int g722_bytes;
253 /* Even and odd tap accumulators */
254 int sumeven;
255 int sumodd;
256 int ihigh;
257 int ilow;
258 int code;
259
260 g722_bytes = 0;
261 xhigh = 0;
262 for (j = 0; j < len; )
263 {
264 if (s->itu_test_mode)
265 {
266 xlow =
267 xhigh = amp[j++] >> 1;
268 }
269 else
270 {
271 if (s->eight_k)
272 {
273 xlow = amp[j++];
274 }
275 else
276 {
277 /* Apply the transmit QMF */
278 /* Shuffle the buffer down */
279 for (i = 0; i < 22; i++)
280 s->x[i] = s->x[i + 2];
281 s->x[22] = amp[j++];
282 s->x[23] = amp[j++];
283
284 /* Discard every other QMF output */
285 sumeven = 0;
286 sumodd = 0;
287 for (i = 0; i < 12; i++)
288 {
289 sumodd += s->x[2*i]*qmf_coeffs[i];
290 sumeven += s->x[2*i + 1]*qmf_coeffs[11 - i];
291 }
292 xlow = (sumeven + sumodd) >> 13;
293 xhigh = (sumeven - sumodd) >> 13;
294 }
295 }
296 /* Block 1L, SUBTRA */
297 el = saturate(xlow - s->band[0].s);
298
299 /* Block 1L, QUANTL */
300 wd = (el >= 0) ? el : -(el + 1);
301
302 for (i = 1; i < 30; i++)
303 {
304 wd1 = (q6[i]*s->band[0].det) >> 12;
305 if (wd < wd1)
306 break;
307 }
308 ilow = (el < 0) ? iln[i] : ilp[i];
309
310 /* Block 2L, INVQAL */
311 ril = ilow >> 2;
312 wd2 = qm4[ril];
313 dlow = (s->band[0].det*wd2) >> 15;
314
315 /* Block 3L, LOGSCL */
316 il4 = rl42[ril];
317 wd = (s->band[0].nb*127) >> 7;
318 s->band[0].nb = wd + wl[il4];
319 if (s->band[0].nb < 0)
320 s->band[0].nb = 0;
321 else if (s->band[0].nb > 18432)
322 s->band[0].nb = 18432;
323
324 /* Block 3L, SCALEL */
325 wd1 = (s->band[0].nb >> 6) & 31;
326 wd2 = 8 - (s->band[0].nb >> 11);
327 wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
328 s->band[0].det = wd3 << 2;
329
330 block4(s, 0, dlow);
331
332 if (s->eight_k)
333 {
334 /* Just leave the high bits as zero */
335 code = (0xC0 | ilow) >> (8 - s->bits_per_sample);
336 }
337 else
338 {
339 /* Block 1H, SUBTRA */
340 eh = saturate(xhigh - s->band[1].s);
341
342 /* Block 1H, QUANTH */
343 wd = (eh >= 0) ? eh : -(eh + 1);
344 wd1 = (564*s->band[1].det) >> 12;
345 mih = (wd >= wd1) ? 2 : 1;
346 ihigh = (eh < 0) ? ihn[mih] : ihp[mih];
347
348 /* Block 2H, INVQAH */
349 wd2 = qm2[ihigh];
350 dhigh = (s->band[1].det*wd2) >> 15;
351
352 /* Block 3H, LOGSCH */
353 ih2 = rh2[ihigh];
354 wd = (s->band[1].nb*127) >> 7;
355 s->band[1].nb = wd + wh[ih2];
356 if (s->band[1].nb < 0)
357 s->band[1].nb = 0;
358 else if (s->band[1].nb > 22528)
359 s->band[1].nb = 22528;
360
361 /* Block 3H, SCALEH */
362 wd1 = (s->band[1].nb >> 6) & 31;
363 wd2 = 10 - (s->band[1].nb >> 11);
364 wd3 = (wd2 < 0) ? (ilb[wd1] << -wd2) : (ilb[wd1] >> wd2);
365 s->band[1].det = wd3 << 2;
366
367 block4(s, 1, dhigh);
368 code = ((ihigh << 6) | ilow) >> (8 - s->bits_per_sample);
369 }
370
371 if (s->packed)
372 {
373 /* Pack the code bits */
374 s->out_buffer |= (code << s->out_bits);
375 s->out_bits += s->bits_per_sample;
376 if (s->out_bits >= 8)
377 {
378 g722_data[g722_bytes++] = (uint8_t) (s->out_buffer & 0xFF);
379 s->out_bits -= 8;
380 s->out_buffer >>= 8;
381 }
382 }
383 else
384 {
385 g722_data[g722_bytes++] = (uint8_t) code;
386 }
387 }
388 return g722_bytes;
389 }
390 /*- End of function --------------------------------------------------------*/
391 /*- End of file ------------------------------------------------------------*/

Repositories maintained by Peter Meerwald, pmeerw@pmeerw.net.