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 ------------------------------------------------------------*/ |