327 lines
9.1 KiB
C
327 lines
9.1 KiB
C
|
|
||
|
/******************************************************************
|
||
|
|
||
|
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;
|
||
|
}
|
||
|
|