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