mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +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; | ||
|  |    } |