comparison spandsp-0.0.3/spandsp-0.0.3/src/gsm0610_decode.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_decode.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_decode.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.3 FIXED POINT IMPLEMENTATION OF THE RPE-LTP DECODER */
56
57 static void postprocessing(gsm0610_state_t *s, int16_t amp[])
58 {
59 int k;
60 int16_t msr;
61 int16_t tmp;
62
63 msr = s->msr;
64 for (k = 0; k < GSM0610_FRAME_LEN; k++)
65 {
66 tmp = gsm_mult_r(msr, 28180);
67 /* De-emphasis */
68 msr = gsm_add(amp[k], tmp);
69 /* Truncation & upscaling */
70 amp[k] = (int16_t) (gsm_add(msr, msr) & 0xFFF8);
71 }
72 /*endfor*/
73 s->msr = msr;
74 }
75 /*- End of function --------------------------------------------------------*/
76
77 static void decode_a_frame(gsm0610_state_t *s,
78 int16_t amp[GSM0610_FRAME_LEN],
79 gsm0610_frame_t *f)
80 {
81 int j;
82 int k;
83 int16_t erp[40];
84 int16_t wt[GSM0610_FRAME_LEN];
85 int16_t *drp;
86
87 drp = s->dp0 + 120;
88 for (j = 0; j < 4; j++)
89 {
90 gsm0610_rpe_decoding(s, f->xmaxc[j], f->Mc[j], f->xMc[j], erp);
91 gsm0610_long_term_synthesis_filtering(s, f->Nc[j], f->bc[j], erp, drp);
92 for (k = 0; k < 40; k++)
93 wt[j*40 + k] = drp[k];
94 /*endfor*/
95 }
96 /*endfor*/
97
98 gsm0610_short_term_synthesis_filter(s, f->LARc, wt, amp);
99 postprocessing(s, amp);
100 }
101 /*- End of function --------------------------------------------------------*/
102
103 int gsm0610_unpack_none(gsm0610_frame_t *s, const uint8_t c[])
104 {
105 int i;
106 int j;
107 int k;
108
109 i = 0;
110 for (j = 0; j < 8; j++)
111 s->LARc[j] = c[i++];
112 for (j = 0; j < 4; j++)
113 {
114 s->Nc[j] = c[i++];
115 s->bc[j] = c[i++];
116 s->Mc[j] = c[i++];
117 s->xmaxc[j] = c[i++];
118 for (k = 0; k < 13; k++)
119 s->xMc[j][k] = c[i++];
120 }
121 return 76;
122 }
123 /*- End of function --------------------------------------------------------*/
124
125 int gsm0610_unpack_wav49(gsm0610_frame_t *s, const uint8_t code[], int half)
126 {
127 int i;
128 int j;
129 static bitstream_state_t bs;
130 const uint8_t *c;
131
132 c = code;
133 if (half)
134 bitstream_init(&bs);
135 s->LARc[0] = (int16_t) bitstream_get(&bs, &c, 6);
136 s->LARc[1] = (int16_t) bitstream_get(&bs, &c, 6);
137 s->LARc[2] = (int16_t) bitstream_get(&bs, &c, 5);
138 s->LARc[3] = (int16_t) bitstream_get(&bs, &c, 5);
139 s->LARc[4] = (int16_t) bitstream_get(&bs, &c, 4);
140 s->LARc[5] = (int16_t) bitstream_get(&bs, &c, 4);
141 s->LARc[6] = (int16_t) bitstream_get(&bs, &c, 3);
142 s->LARc[7] = (int16_t) bitstream_get(&bs, &c, 3);
143 for (i = 0; i < 4; i++)
144 {
145 s->Nc[i] = (int16_t) bitstream_get(&bs, &c, 7);
146 s->bc[i] = (int16_t) bitstream_get(&bs, &c, 2);
147 s->Mc[i] = (int16_t) bitstream_get(&bs, &c, 2);
148 s->xmaxc[i] = (int16_t) bitstream_get(&bs, &c, 6);
149 for (j = 0; j < 13; j++)
150 s->xMc[i][j] = (int16_t) bitstream_get(&bs, &c, 3);
151 }
152 return (half) ? 33 : 32;
153 }
154 /*- End of function --------------------------------------------------------*/
155
156 int gsm0610_unpack_voip(gsm0610_frame_t *s, const uint8_t code[])
157 {
158 int i;
159 int j;
160 const uint8_t *c;
161 unsigned int magic;
162 bitstream_state_t bs;
163
164 c = code;
165 bitstream_init(&bs);
166 magic = bitstream_get2(&bs, &c, 4);
167 if (magic != GSM0610_MAGIC)
168 return -1;
169 s->LARc[0] = (int16_t) bitstream_get2(&bs, &c, 6);
170 s->LARc[1] = (int16_t) bitstream_get2(&bs, &c, 6);
171 s->LARc[2] = (int16_t) bitstream_get2(&bs, &c, 5);
172 s->LARc[3] = (int16_t) bitstream_get2(&bs, &c, 5);
173 s->LARc[4] = (int16_t) bitstream_get2(&bs, &c, 4);
174 s->LARc[5] = (int16_t) bitstream_get2(&bs, &c, 4);
175 s->LARc[6] = (int16_t) bitstream_get2(&bs, &c, 3);
176 s->LARc[7] = (int16_t) bitstream_get2(&bs, &c, 3);
177 for (i = 0; i < 4; i++)
178 {
179 s->Nc[i] = (int16_t) bitstream_get2(&bs, &c, 7);
180 s->bc[i] = (int16_t) bitstream_get2(&bs, &c, 2);
181 s->Mc[i] = (int16_t) bitstream_get2(&bs, &c, 2);
182 s->xmaxc[i] = (int16_t) bitstream_get2(&bs, &c, 6);
183 for (j = 0; j < 13; j++)
184 s->xMc[i][j] = (int16_t) bitstream_get2(&bs, &c, 3);
185 }
186 return 33;
187 }
188 /*- End of function --------------------------------------------------------*/
189
190 int gsm0610_decode(gsm0610_state_t *s, int16_t amp[], const uint8_t code[], int quant)
191 {
192 gsm0610_frame_t frame;
193 const uint8_t *c;
194 int bytes;
195 int i;
196
197 if (s->packing == GSM0610_PACKING_WAV49)
198 quant <<= 1;
199 c = code;
200 for (i = 0; i < quant; i++)
201 {
202 switch (s->packing)
203 {
204 default:
205 case GSM0610_PACKING_NONE:
206 bytes = gsm0610_unpack_none(&frame, c);
207 break;
208 case GSM0610_PACKING_WAV49:
209 s->frame_index = !s->frame_index;
210 bytes = gsm0610_unpack_wav49(&frame, c, s->frame_index);
211 break;
212 case GSM0610_PACKING_VOIP:
213 bytes = gsm0610_unpack_voip(&frame, c);
214 break;
215 }
216 /*endswitch*/
217 if (bytes < 0)
218 return 0;
219 decode_a_frame(s, amp, &frame);
220 c += bytes;
221 amp += GSM0610_FRAME_LEN;
222 }
223 /*endwhile*/
224 return quant*GSM0610_FRAME_LEN;
225 }
226 /*- End of function --------------------------------------------------------*/
227 /*- End of file ------------------------------------------------------------*/

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