Mercurial > hg > audiostuff
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/intercom/ilbc/helpfun.c Fri Jun 25 09:57:52 2010 +0200 @@ -0,0 +1,326 @@ + + /****************************************************************** + + iLBC Speech Coder ANSI-C Source Code + + helpfun.c + + Copyright (C) The Internet Society (2004). + All Rights Reserved. + + ******************************************************************/ + +#include <math.h> + +#include "iLBC_define.h" +#include "constants.h" + + /*----------------------------------------------------------------* + * calculation of auto correlation + *---------------------------------------------------------------*/ + +void autocorr(float *r, /* (o) autocorrelation vector */ + const float *x, /* (i) data vector */ + int N, /* (i) length of data vector */ + int order /* largest lag for calculated + autocorrelations */ + ) +{ + int lag, n; + float sum; + + for (lag = 0; lag <= order; lag++) { + sum = 0; + for (n = 0; n < N - lag; n++) { + sum += x[n] * x[n + lag]; + } + r[lag] = sum; + } + + + + + +} + + /*----------------------------------------------------------------* + * window multiplication + *---------------------------------------------------------------*/ + +void window(float *z, /* (o) the windowed data */ + const float *x, /* (i) the original data vector */ + const float *y, /* (i) the window */ + int N /* (i) length of all vectors */ + ) +{ + int i; + + for (i = 0; i < N; i++) { + z[i] = x[i] * y[i]; + } +} + + /*----------------------------------------------------------------* + * levinson-durbin solution for lpc coefficients + *---------------------------------------------------------------*/ + +void levdurb(float *a, /* (o) lpc coefficient vector starting + with 1.0 */ + float *k, /* (o) reflection coefficients */ + float *r, /* (i) autocorrelation vector */ + int order /* (i) order of lpc filter */ + ) +{ + float sum, alpha; + int m, m_h, i; + + a[0] = 1.0; + + if (r[0] < EPS) { /* if r[0] <= 0, set LPC coeff. to zero */ + for (i = 0; i < order; i++) { + k[i] = 0; + a[i + 1] = 0; + } + } else { + a[1] = k[0] = -r[1] / r[0]; + alpha = r[0] + r[1] * k[0]; + for (m = 1; m < order; m++) { + sum = r[m + 1]; + for (i = 0; i < m; i++) { + sum += a[i + 1] * r[m - i]; + } + + + + + + k[m] = -sum / alpha; + alpha += k[m] * sum; + m_h = (m + 1) >> 1; + for (i = 0; i < m_h; i++) { + sum = a[i + 1] + k[m] * a[m - i]; + a[m - i] += k[m] * a[i + 1]; + a[i + 1] = sum; + } + a[m + 1] = k[m]; + } + } +} + + /*----------------------------------------------------------------* + * interpolation between vectors + *---------------------------------------------------------------*/ + +void interpolate(float *out, /* (o) the interpolated vector */ + float *in1, /* (i) the first vector for the + interpolation */ + float *in2, /* (i) the second vector for the + interpolation */ + float coef, /* (i) interpolation weights */ + int length /* (i) length of all vectors */ + ) +{ + int i; + float invcoef; + + invcoef = (float) 1.0 - coef; + for (i = 0; i < length; i++) { + out[i] = coef * in1[i] + invcoef * in2[i]; + } +} + + /*----------------------------------------------------------------* + * lpc bandwidth expansion + *---------------------------------------------------------------*/ + +void bwexpand(float *out, /* (o) the bandwidth expanded lpc + coefficients */ + float *in, /* (i) the lpc coefficients before bandwidth + expansion */ + float coef, /* (i) the bandwidth expansion factor */ + int length /* (i) the length of lpc coefficient vectors */ + ) +{ + int i; + + + + + + float chirp; + + chirp = coef; + + out[0] = in[0]; + for (i = 1; i < length; i++) { + out[i] = chirp * in[i]; + chirp *= coef; + } +} + + /*----------------------------------------------------------------* + * vector quantization + *---------------------------------------------------------------*/ + +void vq(float *Xq, /* (o) the quantized vector */ + int *index, /* (o) the quantization index */ + const float *CB, /* (i) the vector quantization codebook */ + float *X, /* (i) the vector to quantize */ + int n_cb, /* (i) the number of vectors in the codebook */ + int dim /* (i) the dimension of all vectors */ + ) +{ + int i, j; + int pos, minindex; + float dist, tmp, mindist; + + pos = 0; + mindist = FLOAT_MAX; + minindex = 0; + for (j = 0; j < n_cb; j++) { + dist = X[0] - CB[pos]; + dist *= dist; + for (i = 1; i < dim; i++) { + tmp = X[i] - CB[pos + i]; + dist += tmp * tmp; + } + + if (dist < mindist) { + mindist = dist; + minindex = j; + } + pos += dim; + } + for (i = 0; i < dim; i++) { + Xq[i] = CB[minindex * dim + i]; + } + *index = minindex; + + + + + +} + + /*----------------------------------------------------------------* + * split vector quantization + *---------------------------------------------------------------*/ + +void SplitVQ(float *qX, /* (o) the quantized vector */ + int *index, /* (o) a vector of indexes for all vector + codebooks in the split */ + float *X, /* (i) the vector to quantize */ + const float *CB, /* (i) the quantizer codebook */ + int nsplit, /* the number of vector splits */ + const int *dim, /* the dimension of X and qX */ + const int *cbsize /* the number of vectors in the codebook */ + ) +{ + int cb_pos, X_pos, i; + + cb_pos = 0; + X_pos = 0; + for (i = 0; i < nsplit; i++) { + vq(qX + X_pos, index + i, CB + cb_pos, X + X_pos, + cbsize[i], dim[i]); + X_pos += dim[i]; + cb_pos += dim[i] * cbsize[i]; + } +} + + /*----------------------------------------------------------------* + * scalar quantization + *---------------------------------------------------------------*/ + +void sort_sq(float *xq, /* (o) the quantized value */ + int *index, /* (o) the quantization index */ + float x, /* (i) the value to quantize */ + const float *cb, /* (i) the quantization codebook */ + int cb_size /* (i) the size of the quantization codebook */ + ) +{ + int i; + + if (x <= cb[0]) { + *index = 0; + *xq = cb[0]; + } else { + i = 0; + while ((x > cb[i]) && i < cb_size - 1) { + i++; + + + + + + } + + if (x > ((cb[i] + cb[i - 1]) / 2)) { + *index = i; + *xq = cb[i]; + } else { + *index = i - 1; + *xq = cb[i - 1]; + } + } +} + + /*----------------------------------------------------------------* + * check for stability of lsf coefficients + *---------------------------------------------------------------*/ + +int LSF_check( /* (o) 1 for stable lsf vectors and 0 for + nonstable ones */ + float *lsf, /* (i) a table of lsf vectors */ + int dim, /* (i) the dimension of each lsf vector */ + int NoAn /* (i) the number of lsf vectors in the + table */ + ) +{ + int k, n, m, Nit = 2, change = 0, pos; + float tmp; + static float eps = (float) 0.039; /* 50 Hz */ + static float eps2 = (float) 0.0195; + static float maxlsf = (float) 3.14; /* 4000 Hz */ + static float minlsf = (float) 0.01; /* 0 Hz */ + + /* LSF separation check */ + + for (n = 0; n < Nit; n++) { /* Run through a couple of times */ + for (m = 0; m < NoAn; m++) { /* Number of analyses per frame */ + for (k = 0; k < (dim - 1); k++) { + pos = m * dim + k; + + if ((lsf[pos + 1] - lsf[pos]) < eps) { + + if (lsf[pos + 1] < lsf[pos]) { + tmp = lsf[pos + 1]; + lsf[pos + 1] = lsf[pos] + eps2; + lsf[pos] = lsf[pos + 1] - eps2; + } else { + lsf[pos] -= eps2; + lsf[pos + 1] += eps2; + } + change = 1; + + + + + + } + + if (lsf[pos] < minlsf) { + lsf[pos] = minlsf; + change = 1; + } + + if (lsf[pos] > maxlsf) { + lsf[pos] = maxlsf; + change = 1; + } + } + } + } + + return change; +}