Mercurial > hg > audiostuff
comparison intercom/ilbc/helpfun.c @ 2:13be24d74cd2
import intercom-0.4.1
| author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
|---|---|
| date | Fri, 25 Jun 2010 09:57:52 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:9cadc470e3da | 2:13be24d74cd2 |
|---|---|
| 1 | |
| 2 /****************************************************************** | |
| 3 | |
| 4 iLBC Speech Coder ANSI-C Source Code | |
| 5 | |
| 6 helpfun.c | |
| 7 | |
| 8 Copyright (C) The Internet Society (2004). | |
| 9 All Rights Reserved. | |
| 10 | |
| 11 ******************************************************************/ | |
| 12 | |
| 13 #include <math.h> | |
| 14 | |
| 15 #include "iLBC_define.h" | |
| 16 #include "constants.h" | |
| 17 | |
| 18 /*----------------------------------------------------------------* | |
| 19 * calculation of auto correlation | |
| 20 *---------------------------------------------------------------*/ | |
| 21 | |
| 22 void autocorr(float *r, /* (o) autocorrelation vector */ | |
| 23 const float *x, /* (i) data vector */ | |
| 24 int N, /* (i) length of data vector */ | |
| 25 int order /* largest lag for calculated | |
| 26 autocorrelations */ | |
| 27 ) | |
| 28 { | |
| 29 int lag, n; | |
| 30 float sum; | |
| 31 | |
| 32 for (lag = 0; lag <= order; lag++) { | |
| 33 sum = 0; | |
| 34 for (n = 0; n < N - lag; n++) { | |
| 35 sum += x[n] * x[n + lag]; | |
| 36 } | |
| 37 r[lag] = sum; | |
| 38 } | |
| 39 | |
| 40 | |
| 41 | |
| 42 | |
| 43 | |
| 44 } | |
| 45 | |
| 46 /*----------------------------------------------------------------* | |
| 47 * window multiplication | |
| 48 *---------------------------------------------------------------*/ | |
| 49 | |
| 50 void window(float *z, /* (o) the windowed data */ | |
| 51 const float *x, /* (i) the original data vector */ | |
| 52 const float *y, /* (i) the window */ | |
| 53 int N /* (i) length of all vectors */ | |
| 54 ) | |
| 55 { | |
| 56 int i; | |
| 57 | |
| 58 for (i = 0; i < N; i++) { | |
| 59 z[i] = x[i] * y[i]; | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 /*----------------------------------------------------------------* | |
| 64 * levinson-durbin solution for lpc coefficients | |
| 65 *---------------------------------------------------------------*/ | |
| 66 | |
| 67 void levdurb(float *a, /* (o) lpc coefficient vector starting | |
| 68 with 1.0 */ | |
| 69 float *k, /* (o) reflection coefficients */ | |
| 70 float *r, /* (i) autocorrelation vector */ | |
| 71 int order /* (i) order of lpc filter */ | |
| 72 ) | |
| 73 { | |
| 74 float sum, alpha; | |
| 75 int m, m_h, i; | |
| 76 | |
| 77 a[0] = 1.0; | |
| 78 | |
| 79 if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ | |
| 80 for (i = 0; i < order; i++) { | |
| 81 k[i] = 0; | |
| 82 a[i + 1] = 0; | |
| 83 } | |
| 84 } else { | |
| 85 a[1] = k[0] = -r[1] / r[0]; | |
| 86 alpha = r[0] + r[1] * k[0]; | |
| 87 for (m = 1; m < order; m++) { | |
| 88 sum = r[m + 1]; | |
| 89 for (i = 0; i < m; i++) { | |
| 90 sum += a[i + 1] * r[m - i]; | |
| 91 } | |
| 92 | |
| 93 | |
| 94 | |
| 95 | |
| 96 | |
| 97 k[m] = -sum / alpha; | |
| 98 alpha += k[m] * sum; | |
| 99 m_h = (m + 1) >> 1; | |
| 100 for (i = 0; i < m_h; i++) { | |
| 101 sum = a[i + 1] + k[m] * a[m - i]; | |
| 102 a[m - i] += k[m] * a[i + 1]; | |
| 103 a[i + 1] = sum; | |
| 104 } | |
| 105 a[m + 1] = k[m]; | |
| 106 } | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 /*----------------------------------------------------------------* | |
| 111 * interpolation between vectors | |
| 112 *---------------------------------------------------------------*/ | |
| 113 | |
| 114 void interpolate(float *out, /* (o) the interpolated vector */ | |
| 115 float *in1, /* (i) the first vector for the | |
| 116 interpolation */ | |
| 117 float *in2, /* (i) the second vector for the | |
| 118 interpolation */ | |
| 119 float coef, /* (i) interpolation weights */ | |
| 120 int length /* (i) length of all vectors */ | |
| 121 ) | |
| 122 { | |
| 123 int i; | |
| 124 float invcoef; | |
| 125 | |
| 126 invcoef = (float) 1.0 - coef; | |
| 127 for (i = 0; i < length; i++) { | |
| 128 out[i] = coef * in1[i] + invcoef * in2[i]; | |
| 129 } | |
| 130 } | |
| 131 | |
| 132 /*----------------------------------------------------------------* | |
| 133 * lpc bandwidth expansion | |
| 134 *---------------------------------------------------------------*/ | |
| 135 | |
| 136 void bwexpand(float *out, /* (o) the bandwidth expanded lpc | |
| 137 coefficients */ | |
| 138 float *in, /* (i) the lpc coefficients before bandwidth | |
| 139 expansion */ | |
| 140 float coef, /* (i) the bandwidth expansion factor */ | |
| 141 int length /* (i) the length of lpc coefficient vectors */ | |
| 142 ) | |
| 143 { | |
| 144 int i; | |
| 145 | |
| 146 | |
| 147 | |
| 148 | |
| 149 | |
| 150 float chirp; | |
| 151 | |
| 152 chirp = coef; | |
| 153 | |
| 154 out[0] = in[0]; | |
| 155 for (i = 1; i < length; i++) { | |
| 156 out[i] = chirp * in[i]; | |
| 157 chirp *= coef; | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 /*----------------------------------------------------------------* | |
| 162 * vector quantization | |
| 163 *---------------------------------------------------------------*/ | |
| 164 | |
| 165 void vq(float *Xq, /* (o) the quantized vector */ | |
| 166 int *index, /* (o) the quantization index */ | |
| 167 const float *CB, /* (i) the vector quantization codebook */ | |
| 168 float *X, /* (i) the vector to quantize */ | |
| 169 int n_cb, /* (i) the number of vectors in the codebook */ | |
| 170 int dim /* (i) the dimension of all vectors */ | |
| 171 ) | |
| 172 { | |
| 173 int i, j; | |
| 174 int pos, minindex; | |
| 175 float dist, tmp, mindist; | |
| 176 | |
| 177 pos = 0; | |
| 178 mindist = FLOAT_MAX; | |
| 179 minindex = 0; | |
| 180 for (j = 0; j < n_cb; j++) { | |
| 181 dist = X[0] - CB[pos]; | |
| 182 dist *= dist; | |
| 183 for (i = 1; i < dim; i++) { | |
| 184 tmp = X[i] - CB[pos + i]; | |
| 185 dist += tmp * tmp; | |
| 186 } | |
| 187 | |
| 188 if (dist < mindist) { | |
| 189 mindist = dist; | |
| 190 minindex = j; | |
| 191 } | |
| 192 pos += dim; | |
| 193 } | |
| 194 for (i = 0; i < dim; i++) { | |
| 195 Xq[i] = CB[minindex * dim + i]; | |
| 196 } | |
| 197 *index = minindex; | |
| 198 | |
| 199 | |
| 200 | |
| 201 | |
| 202 | |
| 203 } | |
| 204 | |
| 205 /*----------------------------------------------------------------* | |
| 206 * split vector quantization | |
| 207 *---------------------------------------------------------------*/ | |
| 208 | |
| 209 void SplitVQ(float *qX, /* (o) the quantized vector */ | |
| 210 int *index, /* (o) a vector of indexes for all vector | |
| 211 codebooks in the split */ | |
| 212 float *X, /* (i) the vector to quantize */ | |
| 213 const float *CB, /* (i) the quantizer codebook */ | |
| 214 int nsplit, /* the number of vector splits */ | |
| 215 const int *dim, /* the dimension of X and qX */ | |
| 216 const int *cbsize /* the number of vectors in the codebook */ | |
| 217 ) | |
| 218 { | |
| 219 int cb_pos, X_pos, i; | |
| 220 | |
| 221 cb_pos = 0; | |
| 222 X_pos = 0; | |
| 223 for (i = 0; i < nsplit; i++) { | |
| 224 vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, | |
| 225 cbsize[i], dim[i]); | |
| 226 X_pos += dim[i]; | |
| 227 cb_pos += dim[i] * cbsize[i]; | |
| 228 } | |
| 229 } | |
| 230 | |
| 231 /*----------------------------------------------------------------* | |
| 232 * scalar quantization | |
| 233 *---------------------------------------------------------------*/ | |
| 234 | |
| 235 void sort_sq(float *xq, /* (o) the quantized value */ | |
| 236 int *index, /* (o) the quantization index */ | |
| 237 float x, /* (i) the value to quantize */ | |
| 238 const float *cb, /* (i) the quantization codebook */ | |
| 239 int cb_size /* (i) the size of the quantization codebook */ | |
| 240 ) | |
| 241 { | |
| 242 int i; | |
| 243 | |
| 244 if (x <= cb[0]) { | |
| 245 *index = 0; | |
| 246 *xq = cb[0]; | |
| 247 } else { | |
| 248 i = 0; | |
| 249 while ((x > cb[i]) && i < cb_size - 1) { | |
| 250 i++; | |
| 251 | |
| 252 | |
| 253 | |
| 254 | |
| 255 | |
| 256 } | |
| 257 | |
| 258 if (x > ((cb[i] + cb[i - 1]) / 2)) { | |
| 259 *index = i; | |
| 260 *xq = cb[i]; | |
| 261 } else { | |
| 262 *index = i - 1; | |
| 263 *xq = cb[i - 1]; | |
| 264 } | |
| 265 } | |
| 266 } | |
| 267 | |
| 268 /*----------------------------------------------------------------* | |
| 269 * check for stability of lsf coefficients | |
| 270 *---------------------------------------------------------------*/ | |
| 271 | |
| 272 int LSF_check( /* (o) 1 for stable lsf vectors and 0 for | |
| 273 nonstable ones */ | |
| 274 float *lsf, /* (i) a table of lsf vectors */ | |
| 275 int dim, /* (i) the dimension of each lsf vector */ | |
| 276 int NoAn /* (i) the number of lsf vectors in the | |
| 277 table */ | |
| 278 ) | |
| 279 { | |
| 280 int k, n, m, Nit = 2, change = 0, pos; | |
| 281 float tmp; | |
| 282 static float eps = (float) 0.039; /* 50 Hz */ | |
| 283 static float eps2 = (float) 0.0195; | |
| 284 static float maxlsf = (float) 3.14; /* 4000 Hz */ | |
| 285 static float minlsf = (float) 0.01; /* 0 Hz */ | |
| 286 | |
| 287 /* LSF separation check */ | |
| 288 | |
| 289 for (n = 0; n < Nit; n++) { /* Run through a couple of times */ | |
| 290 for (m = 0; m < NoAn; m++) { /* Number of analyses per frame */ | |
| 291 for (k = 0; k < (dim - 1); k++) { | |
| 292 pos = m * dim + k; | |
| 293 | |
| 294 if ((lsf[pos + 1] - lsf[pos]) < eps) { | |
| 295 | |
| 296 if (lsf[pos + 1] < lsf[pos]) { | |
| 297 tmp = lsf[pos + 1]; | |
| 298 lsf[pos + 1] = lsf[pos] + eps2; | |
| 299 lsf[pos] = lsf[pos + 1] - eps2; | |
| 300 } else { | |
| 301 lsf[pos] -= eps2; | |
| 302 lsf[pos + 1] += eps2; | |
| 303 } | |
| 304 change = 1; | |
| 305 | |
| 306 | |
| 307 | |
| 308 | |
| 309 | |
| 310 } | |
| 311 | |
| 312 if (lsf[pos] < minlsf) { | |
| 313 lsf[pos] = minlsf; | |
| 314 change = 1; | |
| 315 } | |
| 316 | |
| 317 if (lsf[pos] > maxlsf) { | |
| 318 lsf[pos] = maxlsf; | |
| 319 change = 1; | |
| 320 } | |
| 321 } | |
| 322 } | |
| 323 } | |
| 324 | |
| 325 return change; | |
| 326 } |
