Mercurial > hg > audiostuff
comparison spandsp-0.0.3/spandsp-0.0.3/src/oki_adpcm.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 * oki_adpcm.c - Conversion routines between linear 16 bit PCM data and | |
5 * OKI (Dialogic) ADPCM format. Supports with the 32kbps | |
6 * and 24kbps variants used by Dialogic. | |
7 * | |
8 * Written by Steve Underwood <steveu@coppice.org> | |
9 * | |
10 * Copyright (C) 2001, 2004 Steve Underwood | |
11 * | |
12 * The actual OKI ADPCM encode and decode method is derived from freely | |
13 * available code, whose exact origins seem uncertain. | |
14 * | |
15 * All rights reserved. | |
16 * | |
17 * This program is free software; you can redistribute it and/or modify | |
18 * it under the terms of the GNU General Public License version 2, as | |
19 * published by the Free Software Foundation. | |
20 * | |
21 * This program is distributed in the hope that it will be useful, | |
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
24 * GNU General Public License for more details. | |
25 * | |
26 * You should have received a copy of the GNU General Public License | |
27 * along with this program; if not, write to the Free Software | |
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
29 * | |
30 * $Id: oki_adpcm.c,v 1.22 2006/11/28 16:59:56 steveu Exp $ | |
31 */ | |
32 | |
33 /*! \file */ | |
34 | |
35 #ifdef HAVE_CONFIG_H | |
36 #include <config.h> | |
37 #endif | |
38 | |
39 #include <stdlib.h> | |
40 #include <inttypes.h> | |
41 #include <string.h> | |
42 | |
43 #include "spandsp/telephony.h" | |
44 #include "spandsp/oki_adpcm.h" | |
45 | |
46 /* Routines to convert 12 bit linear samples to the Oki ADPCM coding format, | |
47 widely used in CTI, because Dialogic use it. */ | |
48 | |
49 static const int16_t step_size[49] = | |
50 { | |
51 16, 17, 19, 21, 23, 25, 28, 31, | |
52 34, 37, 41, 45, 50, 55, 60, 66, | |
53 73, 80, 88, 97, 107, 118, 130, 143, | |
54 157, 173, 190, 209, 230, 253, 279, 307, | |
55 337, 371, 408, 449, 494, 544, 598, 658, | |
56 724, 796, 876, 963, 1060, 1166, 1282, 1408, | |
57 1552 | |
58 }; | |
59 | |
60 static const int16_t step_adjustment[8] = | |
61 { | |
62 -1, -1, -1, -1, 2, 4, 6, 8 | |
63 }; | |
64 | |
65 /* Band limiting filter, to allow sample rate conversion to and | |
66 from 6k samples/second. */ | |
67 static const float cutoff_coeffs[] = | |
68 { | |
69 -3.648392e-4f, | |
70 5.062391e-4f, | |
71 1.206247e-3f, | |
72 1.804452e-3f, | |
73 1.691750e-3f, | |
74 4.083405e-4f, | |
75 -1.931085e-3f, | |
76 -4.452107e-3f, | |
77 -5.794821e-3f, | |
78 -4.778489e-3f, | |
79 -1.161266e-3f, | |
80 3.928504e-3f, | |
81 8.259786e-3f, | |
82 9.500425e-3f, | |
83 6.512800e-3f, | |
84 2.227856e-4f, | |
85 -6.531275e-3f, | |
86 -1.026843e-2f, | |
87 -8.718062e-3f, | |
88 -2.280487e-3f, | |
89 5.817733e-3f, | |
90 1.096777e-2f, | |
91 9.634404e-3f, | |
92 1.569301e-3f, | |
93 -9.522632e-3f, | |
94 -1.748273e-2f, | |
95 -1.684408e-2f, | |
96 -6.100054e-3f, | |
97 1.071206e-2f, | |
98 2.525209e-2f, | |
99 2.871779e-2f, | |
100 1.664411e-2f, | |
101 -7.706268e-3f, | |
102 -3.331083e-2f, | |
103 -4.521249e-2f, | |
104 -3.085962e-2f, | |
105 1.373653e-2f, | |
106 8.089593e-2f, | |
107 1.529060e-1f, | |
108 2.080487e-1f, | |
109 2.286834e-1f, | |
110 2.080487e-1f, | |
111 1.529060e-1f, | |
112 8.089593e-2f, | |
113 1.373653e-2f, | |
114 -3.085962e-2f, | |
115 -4.521249e-2f, | |
116 -3.331083e-2f, | |
117 -7.706268e-3f, | |
118 1.664411e-2f, | |
119 2.871779e-2f, | |
120 2.525209e-2f, | |
121 1.071206e-2f, | |
122 -6.100054e-3f, | |
123 -1.684408e-2f, | |
124 -1.748273e-2f, | |
125 -9.522632e-3f, | |
126 1.569301e-3f, | |
127 9.634404e-3f, | |
128 1.096777e-2f, | |
129 5.817733e-3f, | |
130 -2.280487e-3f, | |
131 -8.718062e-3f, | |
132 -1.026843e-2f, | |
133 -6.531275e-3f, | |
134 2.227856e-4f, | |
135 6.512800e-3f, | |
136 9.500425e-3f, | |
137 8.259786e-3f, | |
138 3.928504e-3f, | |
139 -1.161266e-3f, | |
140 -4.778489e-3f, | |
141 -5.794821e-3f, | |
142 -4.452107e-3f, | |
143 -1.931085e-3f, | |
144 4.083405e-4f, | |
145 1.691750e-3f, | |
146 1.804452e-3f, | |
147 1.206247e-3f, | |
148 5.062391e-4f, | |
149 -3.648392e-4f | |
150 }; | |
151 | |
152 static int16_t decode(oki_adpcm_state_t *s, uint8_t adpcm) | |
153 { | |
154 int16_t e; | |
155 int16_t ss; | |
156 int16_t linear; | |
157 | |
158 /* Doing the next part as follows: | |
159 * | |
160 * x = adpcm & 0x07; | |
161 * e = (step_size[s->step_index]*(x + x + 1)) >> 3; | |
162 * | |
163 * Seems an obvious improvement on a modern machine, but remember | |
164 * the truncation errors do not come out the same. It would | |
165 * not, therefore, be an exact match for what this code is doing. | |
166 * | |
167 * Just what a Dialogic card does, I do not know! | |
168 */ | |
169 | |
170 ss = step_size[s->step_index]; | |
171 e = ss >> 3; | |
172 if (adpcm & 0x01) | |
173 e += (ss >> 2); | |
174 /*endif*/ | |
175 if (adpcm & 0x02) | |
176 e += (ss >> 1); | |
177 /*endif*/ | |
178 if (adpcm & 0x04) | |
179 e += ss; | |
180 /*endif*/ | |
181 if (adpcm & 0x08) | |
182 e = -e; | |
183 /*endif*/ | |
184 linear = s->last + e; | |
185 | |
186 /* Saturate the values to +/- 2^11 (supposed to be 12 bits) */ | |
187 if (linear > 2047) | |
188 linear = 2047; | |
189 else if (linear < -2048) | |
190 linear = -2048; | |
191 /*endif*/ | |
192 | |
193 s->last = linear; | |
194 s->step_index += step_adjustment[adpcm & 0x07]; | |
195 if (s->step_index < 0) | |
196 s->step_index = 0; | |
197 else if (s->step_index > 48) | |
198 s->step_index = 48; | |
199 /*endif*/ | |
200 /* Note: the result here is a 12 bit value */ | |
201 return linear; | |
202 } | |
203 /*- End of function --------------------------------------------------------*/ | |
204 | |
205 static uint8_t encode(oki_adpcm_state_t *s, int16_t linear) | |
206 { | |
207 int16_t e; | |
208 int16_t ss; | |
209 uint8_t adpcm; | |
210 | |
211 ss = step_size[s->step_index]; | |
212 e = (linear >> 4) - s->last; | |
213 adpcm = (uint8_t) 0x00; | |
214 if (e < 0) | |
215 { | |
216 adpcm = (uint8_t) 0x08; | |
217 e = -e; | |
218 } | |
219 /*endif*/ | |
220 if (e >= ss) | |
221 { | |
222 adpcm |= (uint8_t) 0x04; | |
223 e -= ss; | |
224 } | |
225 /*endif*/ | |
226 if (e >= (ss >> 1)) | |
227 { | |
228 adpcm |= (uint8_t) 0x02; | |
229 e -= ss; | |
230 } | |
231 /*endif*/ | |
232 if (e >= (ss >> 2)) | |
233 adpcm |= (uint8_t) 0x01; | |
234 /*endif*/ | |
235 | |
236 /* Use the decoder to set the estimate of the last sample. */ | |
237 /* It also will adjust the step_index for us. */ | |
238 s->last = decode(s, adpcm); | |
239 return adpcm; | |
240 } | |
241 /*- End of function --------------------------------------------------------*/ | |
242 | |
243 oki_adpcm_state_t *oki_adpcm_init(oki_adpcm_state_t *s, int bit_rate) | |
244 { | |
245 if (bit_rate != 32000 && bit_rate != 24000) | |
246 return NULL; | |
247 if (s == NULL) | |
248 { | |
249 if ((s = (oki_adpcm_state_t *) malloc(sizeof(*s))) == NULL) | |
250 return NULL; | |
251 } | |
252 memset(s, 0, sizeof(*s)); | |
253 s->bit_rate = bit_rate; | |
254 | |
255 return s; | |
256 } | |
257 /*- End of function --------------------------------------------------------*/ | |
258 | |
259 int oki_adpcm_release(oki_adpcm_state_t *s) | |
260 { | |
261 free(s); | |
262 return 0; | |
263 } | |
264 /*- End of function --------------------------------------------------------*/ | |
265 | |
266 int oki_adpcm_decode(oki_adpcm_state_t *s, | |
267 int16_t amp[], | |
268 const uint8_t oki_data[], | |
269 int oki_bytes) | |
270 { | |
271 int i; | |
272 int x; | |
273 int l; | |
274 int n; | |
275 int samples; | |
276 float z; | |
277 | |
278 samples = 0; | |
279 if (s->bit_rate == 32000) | |
280 { | |
281 for (i = 0; i < oki_bytes; i++) | |
282 { | |
283 amp[samples++] = decode(s, (oki_data[i] >> 4) & 0xF) << 4; | |
284 amp[samples++] = decode(s, oki_data[i] & 0xF) << 4; | |
285 } | |
286 /*endwhile*/ | |
287 } | |
288 else | |
289 { | |
290 n = 0; | |
291 for (i = 0; i < oki_bytes; ) | |
292 { | |
293 /* 6k to 8k sample/second conversion */ | |
294 if (s->phase) | |
295 { | |
296 s->history[s->ptr++] = | |
297 decode(s, (n++ & 1) ? (oki_data[i++] & 0xF) : ((oki_data[i] >> 4) & 0xF)) << 4; | |
298 s->ptr &= (32 - 1); | |
299 } | |
300 /*endif*/ | |
301 z = 0.0f; | |
302 for (l = 80 - 3 + s->phase, x = s->ptr - 1; l >= 0; l -= 4, x--) | |
303 z += cutoff_coeffs[l]*s->history[x & (32 - 1)]; | |
304 amp[samples++] = (int16_t) (z*4.0f); | |
305 if (++s->phase > 3) | |
306 s->phase = 0; | |
307 /*endif*/ | |
308 } | |
309 /*endfor*/ | |
310 } | |
311 /*endif*/ | |
312 return samples; | |
313 } | |
314 /*- End of function --------------------------------------------------------*/ | |
315 | |
316 int oki_adpcm_encode(oki_adpcm_state_t *s, | |
317 uint8_t oki_data[], | |
318 const int16_t amp[], | |
319 int len) | |
320 { | |
321 int x; | |
322 int l; | |
323 int n; | |
324 int bytes; | |
325 float z; | |
326 | |
327 bytes = 0; | |
328 if (s->bit_rate == 32000) | |
329 { | |
330 for (n = 0; n < len; n++) | |
331 { | |
332 s->oki_byte = (s->oki_byte << 4) | encode(s, amp[n]); | |
333 if ((s->mark++ & 1)) | |
334 oki_data[bytes++] = s->oki_byte; | |
335 /*endif*/ | |
336 } | |
337 /*endfor*/ | |
338 } | |
339 else | |
340 { | |
341 n = 0; | |
342 for (;;) | |
343 { | |
344 /* 8k to 6k sample/second conversion */ | |
345 if (s->phase > 2) | |
346 { | |
347 s->history[s->ptr++] = amp[n]; | |
348 s->ptr &= (32 - 1); | |
349 s->phase = 0; | |
350 if (++n >= len) | |
351 break; | |
352 /*endif*/ | |
353 } | |
354 /*endif*/ | |
355 s->history[s->ptr++] = amp[n]; | |
356 s->ptr &= (32 - 1); | |
357 z = 0.0f; | |
358 for (l = 80 - s->phase, x = s->ptr - 1; l >= 0; l -= 3, x--) | |
359 z += cutoff_coeffs[l]*s->history[x & (32 - 1)]; | |
360 /*endfor*/ | |
361 s->oki_byte = (s->oki_byte << 4) | encode(s, (int16_t) (z*3.0f)); | |
362 if ((s->mark++ & 1)) | |
363 oki_data[bytes++] = s->oki_byte; | |
364 /*endif*/ | |
365 s->phase++; | |
366 if (++n >= len) | |
367 break; | |
368 /*endif*/ | |
369 } | |
370 /*endfor*/ | |
371 } | |
372 /*endif*/ | |
373 return bytes; | |
374 } | |
375 /*- End of function --------------------------------------------------------*/ | |
376 /*- End of file ------------------------------------------------------------*/ |