mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			324 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			324 lines
		
	
	
		
			9.0 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;
 | |
|        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]) {
 | |
|                            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;
 | |
|    }
 |