Mercurial > hg > audiostuff
comparison spandsp-0.0.6pre17/src/lpc10_encode.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 * lpc10_encode.c - LPC10 low bit 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 Lesser General Public License version 2.1, | |
| 14 * as 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 Lesser General Public License for more details. | |
| 20 * | |
| 21 * You should have received a copy of the GNU Lesser General Public | |
| 22 * License 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 U.S. Department of Defense reference | |
| 26 * implementation of the LPC-10 2400 bps Voice Coder. They do not | |
| 27 * exert copyright claims on their code, and it may be freely used. | |
| 28 * | |
| 29 * $Id: lpc10_encode.c,v 1.28 2009/02/10 13:06:46 steveu Exp $ | |
| 30 */ | |
| 31 | |
| 32 #if defined(HAVE_CONFIG_H) | |
| 33 #include "config.h" | |
| 34 #endif | |
| 35 | |
| 36 #include <stdlib.h> | |
| 37 #include <stdio.h> | |
| 38 #include <inttypes.h> | |
| 39 #include <memory.h> | |
| 40 #if defined(HAVE_TGMATH_H) | |
| 41 #include <tgmath.h> | |
| 42 #endif | |
| 43 #if defined(HAVE_MATH_H) | |
| 44 #include <math.h> | |
| 45 #endif | |
| 46 #include "floating_fudge.h" | |
| 47 | |
| 48 #include "spandsp/telephony.h" | |
| 49 #include "spandsp/dc_restore.h" | |
| 50 #include "spandsp/lpc10.h" | |
| 51 #include "spandsp/private/lpc10.h" | |
| 52 | |
| 53 #include "lpc10_encdecs.h" | |
| 54 | |
| 55 static void lpc10_pack(lpc10_encode_state_t *s, uint8_t ibits[], lpc10_frame_t *t) | |
| 56 { | |
| 57 static const int iblist[53] = | |
| 58 { | |
| 59 13, 12, 11, 1, 2, 13, 12, 11, 1, 2, | |
| 60 13, 10, 11, 2, 1, 10, 13, 12, 11, 10, | |
| 61 2, 13, 12, 11, 10, 2, 1, 12, 7, 6, | |
| 62 1, 10, 9, 8, 7, 4, 6, 9, 8, 7, | |
| 63 5, 1, 9, 8, 4, 6, 1, 5, 9, 8, | |
| 64 7, 5, 6 | |
| 65 }; | |
| 66 int32_t itab[13]; | |
| 67 int x; | |
| 68 int i; | |
| 69 | |
| 70 /* ibits is 54 bits of LPC data ordered as follows: */ | |
| 71 /* R1-0, R2-0, R3-0, P-0, A-0, */ | |
| 72 /* R1-1, R2-1, R3-1, P-1, A-1, */ | |
| 73 /* R1-2, R4-0, R3-2, A-2, P-2, R4-1, */ | |
| 74 /* R1-3, R2-2, R3-3, R4-2, A-3, */ | |
| 75 /* R1-4, R2-3, R3-4, R4-3, A-4, */ | |
| 76 /* P-3, R2-4, R7-0, R8-0, P-4, R4-4, */ | |
| 77 /* R5-0, R6-0, R7-1,R10-0, R8-1, */ | |
| 78 /* R5-1, R6-1, R7-2, R9-0, P-5, */ | |
| 79 /* R5-2, R6-2,R10-1, R8-2, P-6, R9-1, */ | |
| 80 /* R5-3, R6-3, R7-3, R9-2, R8-3, SYNC */ | |
| 81 | |
| 82 itab[0] = t->ipitch; | |
| 83 itab[1] = t->irms; | |
| 84 itab[2] = 0; | |
| 85 for (i = 0; i < LPC10_ORDER; i++) | |
| 86 itab[i + 3] = t->irc[LPC10_ORDER - 1 - i] & 0x7FFF; | |
| 87 /* Put 54 bits into the output buffer */ | |
| 88 x = 0; | |
| 89 for (i = 0; i < 53; i++) | |
| 90 { | |
| 91 x = (x << 1) | (itab[iblist[i] - 1] & 1); | |
| 92 if ((i & 7) == 7) | |
| 93 ibits[i >> 3] = (uint8_t) (x & 0xFF); | |
| 94 itab[iblist[i] - 1] >>= 1; | |
| 95 } | |
| 96 x = (x << 1) | (s->isync & 1); | |
| 97 s->isync ^= 1; | |
| 98 x <<= 2; | |
| 99 ibits[6] = (uint8_t) (x & 0xFF); | |
| 100 } | |
| 101 /*- End of function --------------------------------------------------------*/ | |
| 102 | |
| 103 /* Quantize LPC parameters for transmission */ | |
| 104 static int encode(lpc10_encode_state_t *s, | |
| 105 lpc10_frame_t *t, | |
| 106 int32_t *voice, | |
| 107 int32_t pitch, | |
| 108 float rms, | |
| 109 float *rc) | |
| 110 { | |
| 111 static const int32_t enctab[16] = | |
| 112 { | |
| 113 0, 7, 11, 12, 13, 10, 6, 1, 14, 9, 5, 2, 3, 4, 8, 15 | |
| 114 }; | |
| 115 static const int32_t entau[60] = | |
| 116 { | |
| 117 19, 11, 27, 25, 29, 21, 23, 22, 30, 14, 15, 7, 39, 38, 46, | |
| 118 42, 43, 41, 45, 37, 53, 49, 51, 50, 54, 52, 60, 56, 58, 26, | |
| 119 90, 88, 92, 84, 86, 82, 83, 81, 85, 69, 77, 73, 75, 74, 78, | |
| 120 70, 71, 67, 99, 97, 113, 112, 114, 98, 106, 104, 108, 100, | |
| 121 101, 76 | |
| 122 }; | |
| 123 static const int32_t enadd[8] = | |
| 124 { | |
| 125 1920, -768, 2432, 1280, 3584, 1536, 2816, -1152 | |
| 126 }; | |
| 127 static const float enscl[8] = | |
| 128 { | |
| 129 0.0204f, 0.0167f, 0.0145f, 0.0147f, 0.0143f, 0.0135f, 0.0125f, 0.0112f | |
| 130 }; | |
| 131 static const int32_t enbits[8] = | |
| 132 { | |
| 133 6, 5, 4, 4, 4, 4, 3, 3 | |
| 134 }; | |
| 135 static const int32_t entab6[64] = | |
| 136 { | |
| 137 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, | |
| 138 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, | |
| 139 7, 7, 7, 7, 7, 8, 8, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 13, 14, 15 | |
| 140 }; | |
| 141 static const int32_t rmst[64] = | |
| 142 { | |
| 143 1024, 936, 856, 784, 718, 656, 600, 550, 502, | |
| 144 460, 420, 384, 352, 328, 294, 270, 246, 226, | |
| 145 206, 188, 172, 158, 144, 132, 120, 110, 102, | |
| 146 92, 84, 78, 70, 64, 60, 54, 50, | |
| 147 46, 42, 38, 34, 32, 30, 26, 24, | |
| 148 22, 20, 18, 17, 16, 15, 14, 13, | |
| 149 12, 11, 10, 9, 8, 7, 6, 5, 4, | |
| 150 3, 2, 1, 0 | |
| 151 }; | |
| 152 | |
| 153 int32_t idel; | |
| 154 int32_t nbit; | |
| 155 int32_t i; | |
| 156 int32_t j; | |
| 157 int32_t i2; | |
| 158 int32_t i3; | |
| 159 int32_t mrk; | |
| 160 | |
| 161 /* Scale RMS and RC's to int32_ts */ | |
| 162 t->irms = (int32_t) rms; | |
| 163 for (i = 0; i < LPC10_ORDER; i++) | |
| 164 t->irc[i] = (int32_t) (rc[i]*32768.0f); | |
| 165 if (voice[0] != 0 && voice[1] != 0) | |
| 166 { | |
| 167 t->ipitch = entau[pitch - 1]; | |
| 168 } | |
| 169 else | |
| 170 { | |
| 171 if (s->error_correction) | |
| 172 { | |
| 173 t->ipitch = 0; | |
| 174 if (voice[0] != voice[1]) | |
| 175 t->ipitch = 127; | |
| 176 } | |
| 177 else | |
| 178 { | |
| 179 t->ipitch = (voice[0] << 1) + voice[1]; | |
| 180 } | |
| 181 } | |
| 182 /* Encode RMS by binary table search */ | |
| 183 j = 32; | |
| 184 idel = 16; | |
| 185 t->irms = min(t->irms, 1023); | |
| 186 while (idel > 0) | |
| 187 { | |
| 188 if (t->irms > rmst[j - 1]) | |
| 189 j -= idel; | |
| 190 if (t->irms < rmst[j - 1]) | |
| 191 j += idel; | |
| 192 idel /= 2; | |
| 193 } | |
| 194 if (t->irms > rmst[j - 1]) | |
| 195 --j; | |
| 196 t->irms = 31 - j/2; | |
| 197 /* Encode RC(1) and (2) as log-area-ratios */ | |
| 198 for (i = 0; i < 2; i++) | |
| 199 { | |
| 200 i2 = t->irc[i]; | |
| 201 mrk = 0; | |
| 202 if (i2 < 0) | |
| 203 { | |
| 204 i2 = -i2; | |
| 205 mrk = 1; | |
| 206 } | |
| 207 i2 = min(i2/512, 63); | |
| 208 i2 = entab6[i2]; | |
| 209 if (mrk != 0) | |
| 210 i2 = -i2; | |
| 211 t->irc[i] = i2; | |
| 212 } | |
| 213 /* Encode RC(3) - (10) linearly, remove bias then scale */ | |
| 214 for (i = 2; i < LPC10_ORDER; i++) | |
| 215 { | |
| 216 i2 = (int32_t) ((t->irc[i]/2 + enadd[LPC10_ORDER - 1 - i])*enscl[LPC10_ORDER - 1 - i]); | |
| 217 i2 = max(i2, -127); | |
| 218 i2 = min(i2, 127); | |
| 219 nbit = enbits[LPC10_ORDER - 1 - i]; | |
| 220 i3 = (i2 < 0); | |
| 221 i2 /= pow_ii(2, nbit); | |
| 222 if (i3) | |
| 223 i2--; | |
| 224 t->irc[i] = i2; | |
| 225 } | |
| 226 /* Protect the most significant bits of the most | |
| 227 important parameters during non-voiced frames. | |
| 228 RC(1) - RC(4) are protected using 20 parity bits | |
| 229 replacing RC(5) - RC(10). */ | |
| 230 if (s->error_correction) | |
| 231 { | |
| 232 if (t->ipitch == 0 || t->ipitch == 127) | |
| 233 { | |
| 234 t->irc[4] = enctab[(t->irc[0] & 0x1E) >> 1]; | |
| 235 t->irc[5] = enctab[(t->irc[1] & 0x1E) >> 1]; | |
| 236 t->irc[6] = enctab[(t->irc[2] & 0x1E) >> 1]; | |
| 237 t->irc[7] = enctab[(t->irms & 0x1E) >> 1]; | |
| 238 t->irc[8] = enctab[(t->irc[3] & 0x1E) >> 1] >> 1; | |
| 239 t->irc[9] = enctab[(t->irc[3] & 0x1E) >> 1] & 1; | |
| 240 } | |
| 241 } | |
| 242 return 0; | |
| 243 } | |
| 244 /*- End of function --------------------------------------------------------*/ | |
| 245 | |
| 246 static void high_pass_100hz(lpc10_encode_state_t *s, float speech[], int start, int len) | |
| 247 { | |
| 248 float si; | |
| 249 float err; | |
| 250 int i; | |
| 251 | |
| 252 /* 100 Hz high pass filter */ | |
| 253 for (i = start; i < len; i++) | |
| 254 { | |
| 255 si = speech[i]; | |
| 256 err = si + s->z11*1.859076f - s->z21*0.8648249f; | |
| 257 si = err - s->z11*2.0f + s->z21; | |
| 258 s->z21 = s->z11; | |
| 259 s->z11 = err; | |
| 260 err = si + s->z12*1.935715f - s->z22*0.9417004f; | |
| 261 si = err - s->z12*2.0f + s->z22; | |
| 262 s->z22 = s->z12; | |
| 263 s->z12 = err; | |
| 264 speech[i] = si*0.902428f; | |
| 265 } | |
| 266 } | |
| 267 /*- End of function --------------------------------------------------------*/ | |
| 268 | |
| 269 SPAN_DECLARE(lpc10_encode_state_t *) lpc10_encode_init(lpc10_encode_state_t *s, int error_correction) | |
| 270 { | |
| 271 int i; | |
| 272 int j; | |
| 273 | |
| 274 if (s == NULL) | |
| 275 { | |
| 276 if ((s = (lpc10_encode_state_t *) malloc(sizeof(*s))) == NULL) | |
| 277 return NULL; | |
| 278 } | |
| 279 | |
| 280 s->error_correction = error_correction; | |
| 281 | |
| 282 /* State used only by function high_pass_100hz */ | |
| 283 s->z11 = 0.0f; | |
| 284 s->z21 = 0.0f; | |
| 285 s->z12 = 0.0f; | |
| 286 s->z22 = 0.0f; | |
| 287 | |
| 288 /* State used by function lpc10_analyse */ | |
| 289 for (i = 0; i < 540; i++) | |
| 290 { | |
| 291 s->inbuf[i] = 0.0f; | |
| 292 s->pebuf[i] = 0.0f; | |
| 293 } | |
| 294 for (i = 0; i < 696; i++) | |
| 295 s->lpbuf[i] = 0.0f; | |
| 296 for (i = 0; i < 312; i++) | |
| 297 s->ivbuf[i] = 0.0f; | |
| 298 s->bias = 0.0f; | |
| 299 s->osptr = 1; | |
| 300 for (i = 0; i < 3; i++) | |
| 301 s->obound[i] = 0; | |
| 302 s->vwin[2][0] = 307; | |
| 303 s->vwin[2][1] = 462; | |
| 304 s->awin[2][0] = 307; | |
| 305 s->awin[2][1] = 462; | |
| 306 for (i = 0; i < 4; i++) | |
| 307 { | |
| 308 s->voibuf[i][0] = 0; | |
| 309 s->voibuf[i][1] = 0; | |
| 310 } | |
| 311 for (i = 0; i < 3; i++) | |
| 312 s->rmsbuf[i] = 0.0f; | |
| 313 for (i = 0; i < 3; i++) | |
| 314 { | |
| 315 for (j = 0; j < 10; j++) | |
| 316 s->rcbuf[i][j] = 0.0f; | |
| 317 } | |
| 318 s->zpre = 0.0f; | |
| 319 | |
| 320 /* State used by function onset */ | |
| 321 s->n = 0.0f; | |
| 322 s->d__ = 1.0f; | |
| 323 for (i = 0; i < 16; i++) | |
| 324 s->l2buf[i] = 0.0f; | |
| 325 s->l2sum1 = 0.0f; | |
| 326 s->l2ptr1 = 1; | |
| 327 s->l2ptr2 = 9; | |
| 328 s->hyst = FALSE; | |
| 329 | |
| 330 /* State used by function lpc10_voicing */ | |
| 331 s->dither = 20.0f; | |
| 332 s->maxmin = 0.0f; | |
| 333 for (i = 0; i < 3; i++) | |
| 334 { | |
| 335 s->voice[i][0] = 0.0f; | |
| 336 s->voice[i][1] = 0.0f; | |
| 337 } | |
| 338 s->lbve = 3000; | |
| 339 s->fbve = 3000; | |
| 340 s->fbue = 187; | |
| 341 s->ofbue = 187; | |
| 342 s->sfbue = 187; | |
| 343 s->lbue = 93; | |
| 344 s->olbue = 93; | |
| 345 s->slbue = 93; | |
| 346 s->snr = (float) (s->fbve / s->fbue << 6); | |
| 347 | |
| 348 /* State used by function dynamic_pitch_tracking */ | |
| 349 for (i = 0; i < 60; i++) | |
| 350 s->s[i] = 0.0f; | |
| 351 for (i = 0; i < 2; i++) | |
| 352 { | |
| 353 for (j = 0; j < 60; j++) | |
| 354 s->p[i][j] = 0; | |
| 355 } | |
| 356 s->ipoint = 0; | |
| 357 s->alphax = 0.0f; | |
| 358 | |
| 359 /* State used by function lpc10_pack */ | |
| 360 s->isync = 0; | |
| 361 | |
| 362 return s; | |
| 363 } | |
| 364 /*- End of function --------------------------------------------------------*/ | |
| 365 | |
| 366 SPAN_DECLARE(int) lpc10_encode_release(lpc10_encode_state_t *s) | |
| 367 { | |
| 368 return 0; | |
| 369 } | |
| 370 /*- End of function --------------------------------------------------------*/ | |
| 371 | |
| 372 SPAN_DECLARE(int) lpc10_encode_free(lpc10_encode_state_t *s) | |
| 373 { | |
| 374 free(s); | |
| 375 return 0; | |
| 376 } | |
| 377 /*- End of function --------------------------------------------------------*/ | |
| 378 | |
| 379 SPAN_DECLARE(int) lpc10_encode(lpc10_encode_state_t *s, uint8_t code[], const int16_t amp[], int len) | |
| 380 { | |
| 381 int32_t voice[2]; | |
| 382 int32_t pitch; | |
| 383 float speech[LPC10_SAMPLES_PER_FRAME]; | |
| 384 float rc[LPC10_ORDER]; | |
| 385 float rms; | |
| 386 lpc10_frame_t frame; | |
| 387 int i; | |
| 388 int j; | |
| 389 | |
| 390 len /= LPC10_SAMPLES_PER_FRAME; | |
| 391 for (i = 0; i < len; i++) | |
| 392 { | |
| 393 for (j = 0; j < LPC10_SAMPLES_PER_FRAME; j++) | |
| 394 speech[j] = (float) amp[i*LPC10_SAMPLES_PER_FRAME + j]/32768.0f; | |
| 395 high_pass_100hz(s, speech, 0, LPC10_SAMPLES_PER_FRAME); | |
| 396 lpc10_analyse(s, speech, voice, &pitch, &rms, rc); | |
| 397 encode(s, &frame, voice, pitch, rms, rc); | |
| 398 lpc10_pack(s, &code[7*i], &frame); | |
| 399 } | |
| 400 return len*7; | |
| 401 } | |
| 402 /*- End of function --------------------------------------------------------*/ | |
| 403 /*- End of file ------------------------------------------------------------*/ |
