comparison spandsp-0.0.6pre17/src/gsm0610_encode.c @ 4:26cd8f1ef0b1

import spandsp-0.0.6pre17
author Peter Meerwald <pmeerw@cosy.sbg.ac.at>
date Fri, 25 Jun 2010 15:50:58 +0200
parents
children
comparison
equal deleted inserted replaced
3:c6c5a16ce2f2 4:26cd8f1ef0b1
1 /*
2 * SpanDSP - a series of DSP components for telephony
3 *
4 * gsm0610_encode.c - GSM 06.10 full rate speech codec.
5 *
6 * Written by Steve Underwood <steveu@coppice.org>
7 *
8 * Copyright (C) 2006 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 Lesser General Public License version 2.1,
14 * as 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 Lesser General Public License for more details.
20 *
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 *
25 * This code is based on the widely used GSM 06.10 code available from
26 * http://kbs.cs.tu-berlin.de/~jutta/toast.html
27 *
28 * $Id: gsm0610_encode.c,v 1.30 2009/02/10 13:06:46 steveu Exp $
29 */
30
31 /*! \file */
32
33 #if defined(HAVE_CONFIG_H)
34 #include "config.h"
35 #endif
36
37 #include <assert.h>
38 #include <inttypes.h>
39 #if defined(HAVE_TGMATH_H)
40 #include <tgmath.h>
41 #endif
42 #if defined(HAVE_MATH_H)
43 #include <math.h>
44 #endif
45 #include "floating_fudge.h"
46 #include <stdlib.h>
47 #include <memory.h>
48
49 #include "spandsp/telephony.h"
50 #include "spandsp/fast_convert.h"
51 #include "spandsp/bitstream.h"
52 #include "spandsp/saturated.h"
53 #include "spandsp/gsm0610.h"
54
55 #include "gsm0610_local.h"
56
57 /* 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER */
58
59 /* The RPE-LTD coder works on a frame by frame basis. The length of
60 the frame is equal to 160 samples. Some computations are done
61 once per frame to produce at the output of the coder the
62 LARc[1..8] parameters which are the coded LAR coefficients and
63 also to realize the inverse filtering operation for the entire
64 frame (160 samples of signal d[0..159]). These parts produce at
65 the output of the coder:
66
67 Procedure 4.2.11 to 4.2.18 are to be executed four times per
68 frame. That means once for each sub-segment RPE-LTP analysis of
69 40 samples. These parts produce at the output of the coder.
70 */
71 static void encode_a_frame(gsm0610_state_t *s, gsm0610_frame_t *f, const int16_t amp[])
72 {
73 int k;
74 int16_t *dp;
75 int16_t *dpp;
76 int16_t so[GSM0610_FRAME_LEN];
77 int i;
78
79 dp = s->dp0 + 120;
80 dpp = dp;
81 gsm0610_preprocess(s, amp, so);
82 gsm0610_lpc_analysis(s, so, f->LARc);
83 gsm0610_short_term_analysis_filter(s, f->LARc, so);
84
85 for (k = 0; k < 4; k++)
86 {
87 gsm0610_long_term_predictor(s,
88 so + k*40,
89 dp,
90 s->e + 5,
91 dpp,
92 &f->Nc[k],
93 &f->bc[k]);
94 gsm0610_rpe_encoding(s, s->e + 5, &f->xmaxc[k], &f->Mc[k], f->xMc[k]);
95
96 for (i = 0; i < 40; i++)
97 dp[i] = saturated_add16(s->e[5 + i], dpp[i]);
98 /*endfor*/
99 dp += 40;
100 dpp += 40;
101 }
102 /*endfor*/
103 memcpy((char *) s->dp0,
104 (char *) (s->dp0 + GSM0610_FRAME_LEN),
105 120*sizeof(*s->dp0));
106 }
107 /*- End of function --------------------------------------------------------*/
108
109 SPAN_DECLARE(int) gsm0610_set_packing(gsm0610_state_t *s, int packing)
110 {
111 s->packing = packing;
112 return 0;
113 }
114 /*- End of function --------------------------------------------------------*/
115
116 SPAN_DECLARE(gsm0610_state_t *) gsm0610_init(gsm0610_state_t *s, int packing)
117 {
118 if (s == NULL)
119 {
120 if ((s = (gsm0610_state_t *) malloc(sizeof (*s))) == NULL)
121 return NULL;
122 /*endif*/
123 }
124 /*endif*/
125 memset((char *) s, '\0', sizeof (gsm0610_state_t));
126 s->nrp = 40;
127 s->packing = packing;
128 return s;
129 }
130 /*- End of function --------------------------------------------------------*/
131
132 SPAN_DECLARE(int) gsm0610_release(gsm0610_state_t *s)
133 {
134 return 0;
135 }
136 /*- End of function --------------------------------------------------------*/
137
138 SPAN_DECLARE(int) gsm0610_free(gsm0610_state_t *s)
139 {
140 if (s)
141 free(s);
142 /*endif*/
143 return 0;
144 }
145 /*- End of function --------------------------------------------------------*/
146
147 SPAN_DECLARE(int) gsm0610_pack_none(uint8_t c[], const gsm0610_frame_t *s)
148 {
149 int i;
150 int j;
151 int k;
152
153 i = 0;
154 for (j = 0; j < 8; j++)
155 c[i++] = (uint8_t) s->LARc[j];
156 for (j = 0; j < 4; j++)
157 {
158 c[i++] = (uint8_t) s->Nc[j];
159 c[i++] = (uint8_t) s->bc[j];
160 c[i++] = (uint8_t) s->Mc[j];
161 c[i++] = (uint8_t) s->xmaxc[j];
162 for (k = 0; k < 13; k++)
163 c[i++] = (uint8_t) s->xMc[j][k];
164 }
165 /*endfor*/
166 return 76;
167 }
168 /*- End of function --------------------------------------------------------*/
169
170 SPAN_DECLARE(int) gsm0610_pack_wav49(uint8_t c[], const gsm0610_frame_t *s)
171 {
172 uint16_t sr;
173 int i;
174
175 sr = 0;
176 sr = (sr >> 6) | (s->LARc[0] << 10);
177 sr = (sr >> 6) | (s->LARc[1] << 10);
178 *c++ = (uint8_t) (sr >> 4);
179 sr = (sr >> 5) | (s->LARc[2] << 11);
180 *c++ = (uint8_t) (sr >> 7);
181 sr = (sr >> 5) | (s->LARc[3] << 11);
182 sr = (sr >> 4) | (s->LARc[4] << 12);
183 *c++ = (uint8_t) (sr >> 6);
184 sr = (sr >> 4) | (s->LARc[5] << 12);
185 sr = (sr >> 3) | (s->LARc[6] << 13);
186 *c++ = (uint8_t) (sr >> 7);
187 sr = (sr >> 3) | (s->LARc[7] << 13);
188
189 for (i = 0; i < 4; i++)
190 {
191 sr = (sr >> 7) | (s->Nc[i] << 9);
192 *c++ = (uint8_t) (sr >> 5);
193 sr = (sr >> 2) | (s->bc[i] << 14);
194 sr = (sr >> 2) | (s->Mc[i] << 14);
195 sr = (sr >> 6) | (s->xmaxc[i] << 10);
196 *c++ = (uint8_t) (sr >> 3);
197 sr = (sr >> 3) | (s->xMc[i][0] << 13);
198 *c++ = (uint8_t) (sr >> 8);
199 sr = (sr >> 3) | (s->xMc[i][1] << 13);
200 sr = (sr >> 3) | (s->xMc[i][2] << 13);
201 sr = (sr >> 3) | (s->xMc[i][3] << 13);
202 *c++ = (uint8_t) (sr >> 7);
203 sr = (sr >> 3) | (s->xMc[i][4] << 13);
204 sr = (sr >> 3) | (s->xMc[i][5] << 13);
205 sr = (sr >> 3) | (s->xMc[i][6] << 13);
206 *c++ = (uint8_t) (sr >> 6);
207 sr = (sr >> 3) | (s->xMc[i][7] << 13);
208 sr = (sr >> 3) | (s->xMc[i][8] << 13);
209 *c++ = (uint8_t) (sr >> 8);
210 sr = (sr >> 3) | (s->xMc[i][9] << 13);
211 sr = (sr >> 3) | (s->xMc[i][10] << 13);
212 sr = (sr >> 3) | (s->xMc[i][11] << 13);
213 *c++ = (uint8_t) (sr >> 7);
214 sr = (sr >> 3) | (s->xMc[i][12] << 13);
215 }
216 /*endfor*/
217
218 s++;
219 sr = (sr >> 6) | (s->LARc[0] << 10);
220 *c++ = (uint8_t) (sr >> 6);
221 sr = (sr >> 6) | (s->LARc[1] << 10);
222 *c++ = (uint8_t) (sr >> 8);
223 sr = (sr >> 5) | (s->LARc[2] << 11);
224 sr = (sr >> 5) | (s->LARc[3] << 11);
225 *c++ = (uint8_t) (sr >> 6);
226 sr = (sr >> 4) | (s->LARc[4] << 12);
227 sr = (sr >> 4) | (s->LARc[5] << 12);
228 *c++ = (uint8_t) (sr >> 6);
229 sr = (sr >> 3) | (s->LARc[6] << 13);
230 sr = (sr >> 3) | (s->LARc[7] << 13);
231 *c++ = (uint8_t) (sr >> 8);
232
233 for (i = 0; i < 4; i++)
234 {
235 sr = (sr >> 7) | (s->Nc[i] << 9);
236 sr = (sr >> 2) | (s->bc[i] << 14);
237 *c++ = (uint8_t) (sr >> 7);
238 sr = (sr >> 2) | (s->Mc[i] << 14);
239 sr = (sr >> 6) | (s->xmaxc[i] << 10);
240 *c++ = (uint8_t) (sr >> 7);
241 sr = (sr >> 3) | (s->xMc[i][0] << 13);
242 sr = (sr >> 3) | (s->xMc[i][1] << 13);
243 sr = (sr >> 3) | (s->xMc[i][2] << 13);
244 *c++ = (uint8_t) (sr >> 6);
245 sr = (sr >> 3) | (s->xMc[i][3] << 13);
246 sr = (sr >> 3) | (s->xMc[i][4] << 13);
247 *c++ = (uint8_t) (sr >> 8);
248 sr = (sr >> 3) | (s->xMc[i][5] << 13);
249 sr = (sr >> 3) | (s->xMc[i][6] << 13);
250 sr = (sr >> 3) | (s->xMc[i][7] << 13);
251 *c++ = (uint8_t) (sr >> 7);
252 sr = (sr >> 3) | (s->xMc[i][8] << 13);
253 sr = (sr >> 3) | (s->xMc[i][9] << 13);
254 sr = (sr >> 3) | (s->xMc[i][10] << 13);
255 *c++ = (uint8_t) (sr >> 6);
256 sr = (sr >> 3) | (s->xMc[i][11] << 13);
257 sr = (sr >> 3) | (s->xMc[i][12] << 13);
258 *c++ = (uint8_t) (sr >> 8);
259 }
260 /*endfor*/
261 return 65;
262 }
263 /*- End of function --------------------------------------------------------*/
264
265 SPAN_DECLARE(int) gsm0610_pack_voip(uint8_t c[33], const gsm0610_frame_t *s)
266 {
267 int i;
268
269 *c++ = (uint8_t) (((GSM0610_MAGIC & 0xF) << 4)
270 | ((s->LARc[0] >> 2) & 0xF));
271 *c++ = (uint8_t) (((s->LARc[0] & 0x3) << 6)
272 | (s->LARc[1] & 0x3F));
273 *c++ = (uint8_t) (((s->LARc[2] & 0x1F) << 3)
274 | ((s->LARc[3] >> 2) & 0x7));
275 *c++ = (uint8_t) (((s->LARc[3] & 0x3) << 6)
276 | ((s->LARc[4] & 0xF) << 2)
277 | ((s->LARc[5] >> 2) & 0x3));
278 *c++ = (uint8_t) (((s->LARc[5] & 0x3) << 6)
279 | ((s->LARc[6] & 0x7) << 3)
280 | (s->LARc[7] & 0x7));
281
282 for (i = 0; i < 4; i++)
283 {
284 *c++ = (uint8_t) (((s->Nc[i] & 0x7F) << 1)
285 | ((s->bc[i] >> 1) & 0x1));
286 *c++ = (uint8_t) (((s->bc[i] & 0x1) << 7)
287 | ((s->Mc[i] & 0x3) << 5)
288 | ((s->xmaxc[i] >> 1) & 0x1F));
289 *c++ = (uint8_t) (((s->xmaxc[i] & 0x1) << 7)
290 | ((s->xMc[i][0] & 0x7) << 4)
291 | ((s->xMc[i][1] & 0x7) << 1)
292 | ((s->xMc[i][2] >> 2) & 0x1));
293 *c++ = (uint8_t) (((s->xMc[i][2] & 0x3) << 6)
294 | ((s->xMc[i][3] & 0x7) << 3)
295 | (s->xMc[i][4] & 0x7));
296 *c++ = (uint8_t) (((s->xMc[i][5] & 0x7) << 5)
297 | ((s->xMc[i][6] & 0x7) << 2)
298 | ((s->xMc[i][7] >> 1) & 0x3));
299 *c++ = (uint8_t) (((s->xMc[i][7] & 0x1) << 7)
300 | ((s->xMc[i][8] & 0x7) << 4)
301 | ((s->xMc[i][9] & 0x7) << 1)
302 | ((s->xMc[i][10] >> 2) & 0x1));
303 *c++ = (uint8_t) (((s->xMc[i][10] & 0x3) << 6)
304 | ((s->xMc[i][11] & 0x7) << 3)
305 | (s->xMc[i][12] & 0x7));
306 }
307 /*endfor*/
308 return 33;
309 }
310 /*- End of function --------------------------------------------------------*/
311
312 SPAN_DECLARE(int) gsm0610_encode(gsm0610_state_t *s, uint8_t code[], const int16_t amp[], int len)
313 {
314 gsm0610_frame_t frame[2];
315 int bytes;
316 int i;
317
318 bytes = 0;
319 for (i = 0; i < len; i += GSM0610_FRAME_LEN)
320 {
321 encode_a_frame(s, frame, &amp[i]);
322 switch (s->packing)
323 {
324 case GSM0610_PACKING_WAV49:
325 i += GSM0610_FRAME_LEN;
326 encode_a_frame(s, frame + 1, &amp[i]);
327 bytes += gsm0610_pack_wav49(&code[bytes], frame);
328 break;
329 case GSM0610_PACKING_VOIP:
330 bytes += gsm0610_pack_voip(&code[bytes], frame);
331 break;
332 default:
333 bytes += gsm0610_pack_none(&code[bytes], frame);
334 break;
335 }
336 /*endswitch*/
337 }
338 /*endfor*/
339 return bytes;
340 }
341 /*- End of function --------------------------------------------------------*/
342 /*- End of file ------------------------------------------------------------*/

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