comparison spandsp-0.0.3/spandsp-0.0.3/src/ima_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 * ima_adpcm.c - Conversion routines between linear 16 bit PCM data and
5 * IMA/DVI/Intel ADPCM format.
6 *
7 * Written by Steve Underwood <steveu@coppice.org>
8 *
9 * Copyright (C) 2001, 2004 Steve Underwood
10 *
11 * All rights reserved.
12 *
13 * This program is free software; you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License version 2, as
15 * published by the Free Software Foundation.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 *
26 * $Id: ima_adpcm.c,v 1.18 2006/11/30 15:41:47 steveu Exp $
27 */
28
29 /*! \file */
30
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
34
35 #include <stdlib.h>
36 #include <inttypes.h>
37 #include <string.h>
38 #if defined(HAVE_TGMATH_H)
39 #include <tgmath.h>
40 #endif
41 #if defined(HAVE_MATH_H)
42 #include <math.h>
43 #endif
44
45 #include "spandsp/telephony.h"
46 #include "spandsp/dc_restore.h"
47 #include "spandsp/ima_adpcm.h"
48
49 /*
50 * Intel/DVI ADPCM coder/decoder.
51 *
52 * The algorithm for this coder was taken from the IMA Compatability Project
53 * proceedings, Vol 2, Number 2; May 1992.
54 *
55 * The RTP payload specs. reference a variant of DVI, called VDVI. This attempts to
56 * further compresses, in a variable bit rate manner, by expressing the 4 bit codes
57 * from the DVI codec as:
58 *
59 * 0 00
60 * 1 010
61 * 2 1100
62 * 3 11100
63 * 4 111100
64 * 5 1111100
65 * 6 11111100
66 * 7 11111110
67 * 8 10
68 * 9 011
69 * 10 1101
70 * 11 11101
71 * 12 111101
72 * 13 1111101
73 * 14 11111101
74 * 15 11111111
75 *
76 * Any left over bits in the last octet of an encoded burst are set to one.
77 */
78
79 /* Intel ADPCM step variation table */
80 static const int step_size[89] =
81 {
82 7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
83 19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
84 50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
85 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
86 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
87 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
88 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
89 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
90 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
91 };
92
93 static const int step_adjustment[8] =
94 {
95 -1, -1, -1, -1, 2, 4, 6, 8
96 };
97
98 static const struct
99 {
100 uint8_t code;
101 uint8_t bits;
102 } vdvi_encode[] =
103 {
104 {0x00, 2},
105 {0x02, 3},
106 {0x0C, 4},
107 {0x1C, 5},
108 {0x3C, 6},
109 {0x7C, 7},
110 {0xFC, 8},
111 {0xFE, 8},
112 {0x02, 2},
113 {0x03, 3},
114 {0x0D, 4},
115 {0x1D, 5},
116 {0x3D, 6},
117 {0x7D, 7},
118 {0xFD, 8},
119 {0xFF, 8}
120 };
121
122 static const struct
123 {
124 uint16_t code;
125 uint16_t mask;
126 uint8_t bits;
127 } vdvi_decode[] =
128 {
129 {0x0000, 0xC000, 2},
130 {0x4000, 0xE000, 3},
131 {0xC000, 0xF000, 4},
132 {0xE000, 0xF800, 5},
133 {0xF000, 0xFC00, 6},
134 {0xF800, 0xFE00, 7},
135 {0xFC00, 0xFF00, 8},
136 {0xFE00, 0xFF00, 8},
137 {0x8000, 0xC000, 2},
138 {0x6000, 0xE000, 3},
139 {0xD000, 0xF000, 4},
140 {0xE800, 0xF800, 5},
141 {0xF400, 0xFC00, 6},
142 {0xFA00, 0xFE00, 7},
143 {0xFD00, 0xFF00, 8},
144 {0xFF00, 0xFF00, 8}
145 };
146
147 static int16_t decode(ima_adpcm_state_t *s, uint8_t adpcm)
148 {
149 int e;
150 int ss;
151 int16_t linear;
152
153 /* e = (adpcm+0.5)*step/4 */
154
155 ss = step_size[s->step_index];
156 e = ss >> 3;
157 if (adpcm & 0x01)
158 e += (ss >> 2);
159 /*endif*/
160 if (adpcm & 0x02)
161 e += (ss >> 1);
162 /*endif*/
163 if (adpcm & 0x04)
164 e += ss;
165 /*endif*/
166 if (adpcm & 0x08)
167 e = -e;
168 /*endif*/
169 linear = saturate(s->last + e);
170 s->last = linear;
171 s->step_index += step_adjustment[adpcm & 0x07];
172 if (s->step_index < 0)
173 s->step_index = 0;
174 else if (s->step_index > 88)
175 s->step_index = 88;
176 /*endif*/
177 return linear;
178 }
179 /*- End of function --------------------------------------------------------*/
180
181 static uint8_t encode(ima_adpcm_state_t *s, int16_t linear)
182 {
183 int e;
184 int ss;
185 int adpcm;
186 int diff;
187 int initial_e;
188
189 ss = step_size[s->step_index];
190 initial_e =
191 e = linear - s->last;
192 diff = ss >> 3;
193 adpcm = (uint8_t) 0x00;
194 if (e < 0)
195 {
196 adpcm = (uint8_t) 0x08;
197 e = -e;
198 }
199 /*endif*/
200 if (e >= ss)
201 {
202 adpcm |= (uint8_t) 0x04;
203 e -= ss;
204 }
205 /*endif*/
206 ss >>= 1;
207 if (e >= ss)
208 {
209 adpcm |= (uint8_t) 0x02;
210 e -= ss;
211 }
212 /*endif*/
213 ss >>= 1;
214 if (e >= ss)
215 {
216 adpcm |= (uint8_t) 0x01;
217 e -= ss;
218 }
219 /*endif*/
220
221 if (initial_e < 0)
222 diff = -(diff - initial_e - e);
223 else
224 diff = diff + initial_e - e;
225 /*endif*/
226 s->last = saturate(diff + s->last);
227 s->step_index += step_adjustment[adpcm & 0x07];
228 if (s->step_index < 0)
229 s->step_index = 0;
230 else if (s->step_index > 88)
231 s->step_index = 88;
232 /*endif*/
233 return (uint8_t) adpcm;
234 }
235 /*- End of function --------------------------------------------------------*/
236
237 ima_adpcm_state_t *ima_adpcm_init(ima_adpcm_state_t *s, int variant)
238 {
239 if (s == NULL)
240 {
241 if ((s = (ima_adpcm_state_t *) malloc(sizeof(*s))) == NULL)
242 return NULL;
243 }
244 /*endif*/
245 memset(s, 0, sizeof(*s));
246 s->variant = variant;
247 return s;
248 }
249 /*- End of function --------------------------------------------------------*/
250
251 int ima_adpcm_release(ima_adpcm_state_t *s)
252 {
253 free(s);
254 return 0;
255 }
256 /*- End of function --------------------------------------------------------*/
257
258 int ima_adpcm_decode(ima_adpcm_state_t *s,
259 int16_t amp[],
260 const uint8_t ima_data[],
261 int ima_bytes)
262 {
263 int i;
264 int j;
265 int samples;
266 uint16_t code;
267
268 samples = 0;
269 if (s->variant == IMA_ADPCM_VDVI)
270 {
271 code = 0;
272 s->bits = 0;
273 for (i = 0; ; )
274 {
275 if (s->bits <= 8)
276 {
277 if (i >= ima_bytes)
278 break;
279 /*endif*/
280 code |= ((uint16_t) ima_data[i++] << (8 - s->bits));
281 s->bits += 8;
282 }
283 /*endif*/
284 for (j = 0; j < 8; j++)
285 {
286 if ((vdvi_decode[j].mask & code) == vdvi_decode[j].code)
287 break;
288 if ((vdvi_decode[j + 8].mask & code) == vdvi_decode[j + 8].code)
289 {
290 j += 8;
291 break;
292 }
293 /*endif*/
294 }
295 /*endfor*/
296 amp[samples++] = decode(s, (uint8_t) j);
297 code <<= vdvi_decode[j].bits;
298 s->bits -= vdvi_decode[j].bits;
299 }
300 /*endfor*/
301 /* Use up the remanents of the last octet */
302 while (s->bits > 0)
303 {
304 for (j = 0; j < 8; j++)
305 {
306 if ((vdvi_decode[j].mask & code) == vdvi_decode[j].code)
307 break;
308 /*endif*/
309 if ((vdvi_decode[j + 8].mask & code) == vdvi_decode[j + 8].code)
310 {
311 j += 8;
312 break;
313 }
314 /*endif*/
315 }
316 /*endfor*/
317 if (vdvi_decode[j].bits > s->bits)
318 break;
319 /*endif*/
320 amp[samples++] = decode(s, (uint8_t) j);
321 code <<= vdvi_decode[j].bits;
322 s->bits -= vdvi_decode[j].bits;
323 }
324 /*endfor*/
325 }
326 else
327 {
328 for (i = 0; i < ima_bytes; i++)
329 {
330 amp[samples++] = decode(s, ima_data[i] & 0xF);
331 amp[samples++] = decode(s, (ima_data[i] >> 4) & 0xF);
332 }
333 /*endwhile*/
334 }
335 /*endif*/
336 return samples;
337 }
338 /*- End of function --------------------------------------------------------*/
339
340 int ima_adpcm_encode(ima_adpcm_state_t *s,
341 uint8_t ima_data[],
342 const int16_t amp[],
343 int len)
344 {
345 int i;
346 int bytes;
347 uint8_t code;
348
349 bytes = 0;
350 if (s->variant == IMA_ADPCM_VDVI)
351 {
352 s->bits = 0;
353 for (i = 0; i < len; i++)
354 {
355 code = encode(s, amp[i]);
356 s->ima_byte = (s->ima_byte << vdvi_encode[code].bits) | vdvi_encode[code].code;
357 s->bits += vdvi_encode[code].bits;
358 if (s->bits >= 8)
359 {
360 s->bits -= 8;
361 ima_data[bytes++] = (uint8_t) (s->ima_byte >> s->bits);
362 }
363 /*endif*/
364 }
365 /*endfor*/
366 if (s->bits)
367 {
368 ima_data[bytes++] = (uint8_t) (((s->ima_byte << 8) | 0xFF) >> s->bits);
369 }
370 /*endif*/
371 }
372 else
373 {
374 for (i = 0; i < len; i++)
375 {
376 s->ima_byte = (uint8_t) ((s->ima_byte >> 4) | (encode(s, amp[i]) << 4));
377 if ((s->bits++ & 1))
378 ima_data[bytes++] = (uint8_t) s->ima_byte;
379 /*endif*/
380 }
381 /*endfor*/
382 }
383 /*endif*/
384 return bytes;
385 }
386 /*- End of function --------------------------------------------------------*/
387 /*- End of file ------------------------------------------------------------*/

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