freeswitch/libs/ilbc/src/helpfun.c

335 lines
9.4 KiB
C

/*
* iLBC - a library for the iLBC codec
*
* helpfun.c - The iLBC low bit rate speech codec.
*
* Adapted by Steve Underwood <steveu@coppice.org> from the reference
* iLBC code supplied in RFC3951.
*
* Original code Copyright (C) The Internet Society (2004).
* All changes to produce this version Copyright (C) 2008 by Steve Underwood
* All Rights Reserved.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: helpfun.c,v 1.2 2008/03/06 12:27:38 steveu Exp $
*/
/*! \file */
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <inttypes.h>
#include <math.h>
#include "ilbc.h"
#include "constants.h"
#include "helpfun.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;
int 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;
float alpha;
int m;
int m_h;
int i;
a[0] = 1.0f;
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 = 1.0f - 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;
int j;
int pos;
int minindex;
float dist;
float tmp;
float 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;
int X_pos;
int 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;
int n;
int m;
int Nit = 2;
int change = 0;
int pos;
float tmp;
static const float eps = 0.039f; /* 50 Hz */
static const float eps2 = 0.0195f;
static const float maxlsf = 3.14f; /* 4000 Hz */
static const float minlsf = 0.01f; /* 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;
}