comparison spandsp-0.0.3/spandsp-0.0.3/src/gsm0610_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 * 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 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 * 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.12 2006/11/30 15:41:47 steveu Exp $
29 */
30
31 /*! \file */
32
33 #ifdef 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 <stdlib.h>
46 #include <memory.h>
47
48 #include "spandsp/telephony.h"
49 #include "spandsp/dc_restore.h"
50 #include "spandsp/bitstream.h"
51 #include "spandsp/gsm0610.h"
52
53 #include "gsm0610_local.h"
54
55 /* 4.2 FIXED POINT IMPLEMENTATION OF THE RPE-LTP CODER */
56
57 /* The RPE-LTD coder works on a frame by frame basis. The length of
58 the frame is equal to 160 samples. Some computations are done
59 once per frame to produce at the output of the coder the
60 LARc[1..8] parameters which are the coded LAR coefficients and
61 also to realize the inverse filtering operation for the entire
62 frame (160 samples of signal d[0..159]). These parts produce at
63 the output of the coder:
64
65 Procedure 4.2.11 to 4.2.18 are to be executed four times per
66 frame. That means once for each sub-segment RPE-LTP analysis of
67 40 samples. These parts produce at the output of the coder.
68 */
69 static void encode_a_frame(gsm0610_state_t *s, const int16_t amp[], gsm0610_frame_t *f)
70 {
71 int k;
72 int16_t *dp;
73 int16_t *dpp;
74 int16_t so[GSM0610_FRAME_LEN];
75 int i;
76
77 dp = s->dp0 + 120;
78 dpp = dp;
79 gsm0610_preprocess(s, amp, so);
80 gsm0610_lpc_analysis(s, so, f->LARc);
81 gsm0610_short_term_analysis_filter(s, f->LARc, so);
82
83 for (k = 0; k < 4; k++)
84 {
85 gsm0610_long_term_predictor(s,
86 so + k*40,
87 dp,
88 s->e + 5,
89 dpp,
90 &f->Nc[k],
91 &f->bc[k]);
92 gsm0610_rpe_encoding(s, s->e + 5, &f->xmaxc[k], &f->Mc[k], f->xMc[k]);
93
94 for (i = 0; i < 40; i++)
95 dp[i] = gsm_add(s->e[5 + i], dpp[i]);
96 /*endfor*/
97 dp += 40;
98 dpp += 40;
99 }
100 /*endfor*/
101 memcpy ((char *) s->dp0,
102 (char *) (s->dp0 + GSM0610_FRAME_LEN),
103 120*sizeof(*s->dp0));
104 }
105 /*- End of function --------------------------------------------------------*/
106
107 gsm0610_state_t *gsm0610_init(gsm0610_state_t *s, int packing)
108 {
109 if (s == NULL)
110 {
111 s = (gsm0610_state_t *) malloc(sizeof (gsm0610_state_t));
112 if (s == NULL)
113 return NULL;
114 /*endif*/
115 }
116 /*endif*/
117 memset((char *) s, '\0', sizeof (gsm0610_state_t));
118 s->nrp = 40;
119 s->packing = packing;
120 return s;
121 }
122 /*- End of function --------------------------------------------------------*/
123
124 int gsm0610_release(gsm0610_state_t *s)
125 {
126 if (s)
127 free(s);
128 /*endif*/
129 return 0;
130 }
131 /*- End of function --------------------------------------------------------*/
132
133 int gsm0610_pack_none(uint8_t c[], gsm0610_frame_t *s)
134 {
135 int i;
136 int j;
137 int k;
138
139 i = 0;
140 for (j = 0; j < 8; j++)
141 c[i++] = (uint8_t) s->LARc[j];
142 for (j = 0; j < 4; j++)
143 {
144 c[i++] = (uint8_t) s->Nc[j];
145 c[i++] = (uint8_t) s->bc[j];
146 c[i++] = (uint8_t) s->Mc[j];
147 c[i++] = (uint8_t) s->xmaxc[j];
148 for (k = 0; k < 13; k++)
149 c[i++] = (uint8_t) s->xMc[j][k];
150 }
151 return 76;
152 }
153 /*- End of function --------------------------------------------------------*/
154
155 int gsm0610_pack_wav49(uint8_t code[], gsm0610_frame_t *s, int half)
156 {
157 int i;
158 int j;
159 uint8_t *c;
160 bitstream_state_t bs;
161
162 c = code;
163 if (half)
164 bitstream_init(&bs);
165 bitstream_put(&bs, &c, s->LARc[0], 6);
166 bitstream_put(&bs, &c, s->LARc[1], 6);
167 bitstream_put(&bs, &c, s->LARc[2], 5);
168 bitstream_put(&bs, &c, s->LARc[3], 5);
169 bitstream_put(&bs, &c, s->LARc[4], 4);
170 bitstream_put(&bs, &c, s->LARc[5], 4);
171 bitstream_put(&bs, &c, s->LARc[6], 3);
172 bitstream_put(&bs, &c, s->LARc[7], 3);
173 for (i = 0; i < 4; i++)
174 {
175 bitstream_put(&bs, &c, s->Nc[i], 7);
176 bitstream_put(&bs, &c, s->bc[i], 2);
177 bitstream_put(&bs, &c, s->Mc[i], 2);
178 bitstream_put(&bs, &c, s->xmaxc[i], 6);
179 for (j = 0; j < 13; j++)
180 bitstream_put(&bs, &c, s->xMc[i][j], 3);
181 }
182 return (half) ? 32 : 33;
183 }
184 /*- End of function --------------------------------------------------------*/
185
186 int gsm0610_pack_voip(uint8_t code[], gsm0610_frame_t *s)
187 {
188 int i;
189 int j;
190 uint8_t *c;
191 bitstream_state_t bs;
192
193 c = code;
194 bitstream_init(&bs);
195 bitstream_put2(&bs, &c, GSM0610_MAGIC, 4);
196 bitstream_put2(&bs, &c, s->LARc[0], 6);
197 bitstream_put2(&bs, &c, s->LARc[1], 6);
198 bitstream_put2(&bs, &c, s->LARc[2], 5);
199 bitstream_put2(&bs, &c, s->LARc[3], 5);
200 bitstream_put2(&bs, &c, s->LARc[4], 4);
201 bitstream_put2(&bs, &c, s->LARc[5], 4);
202 bitstream_put2(&bs, &c, s->LARc[6], 3);
203 bitstream_put2(&bs, &c, s->LARc[7], 3);
204 for (i = 0; i < 4; i++)
205 {
206 bitstream_put2(&bs, &c, s->Nc[i], 7);
207 bitstream_put2(&bs, &c, s->bc[i], 2);
208 bitstream_put2(&bs, &c, s->Mc[i], 2);
209 bitstream_put2(&bs, &c, s->xmaxc[i], 6);
210 for (j = 0; j < 13; j++)
211 bitstream_put2(&bs, &c, s->xMc[i][j], 3);
212 }
213 return 33;
214 }
215 /*- End of function --------------------------------------------------------*/
216
217 int gsm0610_encode(gsm0610_state_t *s, uint8_t code[], const int16_t amp[], int quant)
218 {
219 gsm0610_frame_t frame;
220 uint8_t *c;
221 int i;
222
223 c = code;
224 if (s->packing == GSM0610_PACKING_WAV49)
225 quant <<= 1;
226 for (i = 0; i < quant; i++)
227 {
228 encode_a_frame(s, &amp[i*GSM0610_FRAME_LEN], &frame);
229 /* variable size
230
231 LARc[0] 6
232 LARc[1] 6
233 LARc[2] 5
234 LARc[3] 5
235 LARc[4] 4
236 LARc[5] 4
237 LARc[6] 3
238 LARc[7] 3
239
240 Nc[0] 7
241 bc[0] 2
242 Mc[0] 2
243 xmaxc[0] 6
244 xMc[0] 3
245 xMc[1] 3
246 xMc[2] 3
247 xMc[3] 3
248 xMc[4] 3
249 xMc[5] 3
250 xMc[6] 3
251 xMc[7] 3
252 xMc[8] 3
253 xMc[9] 3
254 xMc[10] 3
255 xMc[11] 3
256 xMc[12] 3
257
258 Nc[1] 7
259 bc[1] 2
260 Mc[1] 2
261 xmaxc[1] 6
262 xMc[13] 3
263 xMc[14] 3
264 xMc[15] 3
265 xMc[16] 3
266 xMc[17] 3
267 xMc[18] 3
268 xMc[19] 3
269 xMc[20] 3
270 xMc[21] 3
271 xMc[22] 3
272 xMc[23] 3
273 xMc[24] 3
274 xMc[25] 3
275
276 Nc[2] 7
277 bc[2] 2
278 Mc[2] 2
279 xmaxc[2] 6
280 xMc[26] 3
281 xMc[27] 3
282 xMc[28] 3
283 xMc[29] 3
284 xMc[30] 3
285 xMc[31] 3
286 xMc[32] 3
287 xMc[33] 3
288 xMc[34] 3
289 xMc[35] 3
290 xMc[36] 3
291 xMc[37] 3
292 xMc[38] 3
293
294 Nc[3] 7
295 bc[3] 2
296 Mc[3] 2
297 xmaxc[3] 6
298 xMc[39] 3
299 xMc[40] 3
300 xMc[41] 3
301 xMc[42] 3
302 xMc[43] 3
303 xMc[44] 3
304 xMc[45] 3
305 xMc[46] 3
306 xMc[47] 3
307 xMc[48] 3
308 xMc[49] 3
309 xMc[50] 3
310 xMc[51] 3
311 */
312
313 switch (s->packing)
314 {
315 case GSM0610_PACKING_NONE:
316 c += gsm0610_pack_none(c, &frame);
317 break;
318 case GSM0610_PACKING_WAV49:
319 s->frame_index = !s->frame_index;
320 c += gsm0610_pack_wav49(c, &frame, s->frame_index);
321 break;
322 case GSM0610_PACKING_VOIP:
323 c += gsm0610_pack_voip(c, &frame);
324 break;
325 }
326 /*endswitch*/
327 }
328 /*endwhile*/
329 return (int) (c - code);
330 }
331 /*- End of function --------------------------------------------------------*/
332 /*- End of file ------------------------------------------------------------*/

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