⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lpc_lib.c

📁 melp1.2.tar_Floating.gz为美军2400bps语音压缩编码
💻 C
字号:
/*2.4 kbps MELP Proposed Federal Standard speech coderversion 1.2Copyright (c) 1996, Texas Instruments, Inc.  Texas Instruments has intellectual property rights on the MELPalgorithm.  The Texas Instruments contact for licensing issues forcommercial and non-government use is William Gordon, Director,Government Contracts, Texas Instruments Incorporated, SemiconductorGroup (phone 972 480 7442).*//*  lpc_lib.c: LPC function library*/#include <stdio.h>#include <math.h>#include "spbstd.h"#include "lpc.h"/*     Name: lpc_aejw- Compute square of A(z) evaluated at exp(jw)    Description:        Compute the magnitude squared of the z-transform of <nf>        A(z) = 1+a(1)z^-1 + ... +a(p)z^-p</nf>        evaluated at z=exp(jw)     Inputs:        a- LPC filter (a[0] is undefined, a[1..p])        w- radian frequency        p- predictor order     Returns:        |A(exp(jw))|^2     See_Also: cos(3), sin(3)     Includes:        spbstd.h        lpc.h     Systems and Info. Science Lab     Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.*/float lpc_aejw(float *a,float w,int p){    int i;    float c_re,c_im;    float cs,sn,tmp;    if (p==0)        return(1.);    /* use horners method    A(exp(jw)) = 1+ e(-jw)[a(1)+e(-jw)[a(2)+e(-jw)[a(3)+..            ...[a(p-1)+e(-jw)a(p)]]]]    */    cs = (float)cos((double)w);    sn = -(float)sin((double)w);    c_re = cs*a[p];    c_im = sn*a[p];    for(i=p-1; i > 0; i--)    {        /* add a[i] */        c_re += a[i];        /* multiply by exp(-jw) */        c_im = cs*(tmp=c_im) + sn*c_re;        c_re = cs*c_re - sn*tmp;    }    /* add one */    c_re += 1.0;    return(SQR(c_re) + SQR(c_im));} /* LPC_AEJW *//*    Name: lpc_bwex- Move the zeros of A(z) toward the origin.    Aliases: lpc_bw_expand    Description:        Expand the zeros of the LPC filter by gamma, which        moves each zero radially into the origin.<nf>        for j = 1 to p            aw[j] = a[j]*gamma^j</nf>        (Can also be used to perform an exponential windowing procedure).    Inputs:        a- lpc vector (order p, a[1..p])        gamma- the bandwidth expansion factor        p- order of lpc filter    Outputs:        aw- the bandwidth expanded LPC filter    Returns: NULL    See_Also: lpc_lagw(3l)    Includes:        spbstd.h        lpc.h    Systems and Info. Science Lab    Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.*/int lpc_bwex(float *a, float *aw, float gamma, int p){    int i;    float gk;    for(i=1,gk=gamma; i <= p; i++, gk *= gamma)        aw[i] = a[i]*gk;    return(0);}/*    Name: lpc_clmp- Sort and ensure minimum separation in LSPs.    Aliases: lpc_clamp    Description:        Ensure that all LSPs are ordered and separated        by at least delta.  The algorithm isn't guarenteed        to work, so it prints an error message when it fails        to sort the LSPs properly.    Inputs:        w- lsp vector (order p, w[1..p])        delta- the clamping factor        p- order of lpc filter    Outputs:        w- the sorted and clamped lsps    Returns: NULL    See_Also:    Includes:        spbstd.h        lpc.h    Bugs:         Currently only supports 10 loops, which is too        complex and perhaps unneccesary.    Systems and Info. Science Lab    Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.**/#define MAX_LOOPS 10int lpc_clmp(float *w, float delta, int p){    int i,j,unsorted;    float tmp,d,step1,step2;    /* sort the LSPs- for 10 loops, complexity is approximately 150 p */      for (j=0,unsorted=TRUE; unsorted && (j < MAX_LOOPS); j++)    {        for(i=1,unsorted=FALSE; i < p; i++)            if (w[i] > w[i+1])            {                tmp = w[i+1];		w[i+1] = w[i];		w[i] = tmp;                unsorted = TRUE;	    }    }    /* ensure minimum separation */    if (!unsorted)     {        for(j=0; j < MAX_LOOPS; j++)        {            for(i=1; i < p; i++)            {                if ((d = w[i+1]-w[i]) < delta)                {                    step1 = step2 = (delta-d)/2.0;                    if (i==1 && (w[i] < delta))                    {                        step1 = w[i]/2.0;	            }                    else if (i > 1)                    {                        if ((tmp = w[i] - w[i-1]) < delta)                            step1 = 0;                        else if (tmp < 2*delta)                            step1 = (tmp-delta)/2.0;		    }                    if (i==(p-1) && (w[i+1] > (1.0-delta)))                    {                        step2 = (1-w[i+1])/2.0;		    }                    else if (i < (p-1))                    {                        if ((tmp = w[i+2] - w[i+1]) < delta)                            step2 = 0;                        else if (tmp < 2*delta)                            step2 = (tmp-delta)/2.0;		    }                    w[i] -= step1;		    w[i+1] += step2;	        }	    }        }    }    /* Debug: check if the minimum separation rule was met */    for(j=1; j < p; j++)      if ((w[j+1]-w[j]) < 0.99*delta)          (void)fprintf(stderr,"%s: LSPs not separated by enough (line %d)\n",              __FILE__,__LINE__);    if (unsorted)        (void)fprintf(stderr,"%s: LSPs still unsorted (line %d)\n",		      __FILE__,__LINE__);    return(0);}/*    Name: lpc_schr- Schur recursion (autocorrelations to refl coef)    Aliases: lpc_schur    Description:        Compute reflection coefficients from autocorrelations        based on schur recursion.  Will also compute predictor        parameters by calling lpc_refl2pred(3l) if necessary.    Inputs:        r- autocorrelation vector (r[0..p]).        p- order of lpc filter.    Outputs:        a-     predictor parameters    (can be NULL)        k_tmp- reflection coefficients (can be NULL)    Returns:        alphap- the minimum residual energy    Includes:        spbstd.h        lpc.h    See_Also:        lpc_refl2pred(3l) in lpc.h or lpc(3l)*/float lpc_schr(float *r, float *a, float *k_tmp, int p){    int i,j;    float temp,alphap,*y1,*y2,*k;    MEM_ALLOC(MALLOC,y1,p+2,float);    MEM_ALLOC(MALLOC,y2,p+2,float);    if (k_tmp == NULL)    {        MEM_ALLOC(MALLOC,k,p+1,float);    }    else        k = k_tmp;    k[1] = -r[1]/r[0];    alphap = r[0]*(1-SQR(k[1]));    y2[1] = r[1];    y2[2] = r[0]+k[1]*r[1];    for(i=2; i <= p; i++)    {        y1[1] = temp = r[i];        for(j=1; j < i; j++)        {            y1[j+1] = y2[j] + k[j]*temp;            temp += k[j]*y2[j];            y2[j] = y1[j];        }        k[i] = -temp/y2[i];        y2[i+1] = y2[i]+k[i]*temp;        y2[i] = y1[i];        alphap *= 1-SQR(k[i]);    }    if (a != NULL)    {        (void)lpc_refl2pred(k,a,p);    }    if (k_tmp == NULL)    {        MEM_FREE(FREE,k);    }    MEM_FREE(FREE,y2);    MEM_FREE(FREE,y1);    return(alphap);}/* minimum LSP separation-- a global variable */float lsp_delta = 0.0;/* private functions */static float lsp_g(float x,float *c,int p2);static int   lsp_roots(float *w,float **c,int p2);#define DELTA  0.00781250#define BISECTIONS 4    /* LPC_PRED2LSP      get LSP coeffs from the predictor coeffs      Input:         a- the predictor coefficients         p- the predictor order      Output:         w- the lsp coefficients   Reference:  Kabal and Ramachandran*/int lpc_pred2lsp(float *a,float *w,int p){    int i,p2;    float **c;    p2 = p/2;    MEM_2ALLOC(MALLOC,c,2,p2+1,float);    c[0][p2] = c[1][p2] = 1.0;    for(i=1; i <= p2; i++)    {        c[0][p2-i] = (a[i] + a[p+1-i] - c[0][p2+1-i]);        c[1][p2-i] = c[1][p2+1-i] + a[i] - a[p+1-i];    }    c[0][0] /= 2.0;    c[1][0] /= 2.0;    i = lsp_roots(w,c,p2);    if (i)    {        for(i=1; i <= p; i++)            (void)fprintf(stderr,"%11.7f ",a[i]);        (void)fprintf(stderr,"\n");    }    /* ensure minimum separation and sort */    (void)lpc_clamp(w,lsp_delta,p);    MEM_2FREE(FREE,c);    return(i);} /* LPC_PRED2LSP *//* LPC_PRED2REFL      get refl coeffs from the predictor coeffs      Input:         a- the predictor coefficients         p- the predictor order      Output:         k- the reflection coefficients   Reference:  Markel and Gray, Linear Prediction of Speech*/int lpc_pred2refl(float *a,float *k,int p){    float *b,*b1,e;    int   i,j;    MEM_ALLOC(MALLOC,b,p+1,float);    MEM_ALLOC(MALLOC,b1,p+1,float);    /* equate temporary variables (b = a) */    for(i=1; i <= p; i++)        b[i] = a[i];    /* compute reflection coefficients */    for(i=p; i > 0; i--)    {        k[i] = b[i];        e = 1 - SQR(k[i]);        for(j=1; j < i; j++)            b1[j] = b[j];        for(j=1; j < i; j++)            b[j] = (b1[j] - k[i]*b1[i-j])/e;    }    MEM_FREE(FREE,b1);    MEM_FREE(FREE,b);    return(0);}/* LPC_LSP2PRED      get predictor coefficients from the LSPs   Synopsis: lpc_lsp2pred(w,a,p)      Input:         w- the LSPs         p- the predictor order      Output:         a- the predictor coefficients   Reference:  Kabal and Ramachandran*/int lpc_lsp2pred(float *w,float *a,int p){    int i,j,k,p2;    float **f,c[2];    /* ensure minimum separation and sort */    (void)lpc_clamp(w,lsp_delta,p);    p2 = p/2;    MEM_2ALLOC(MALLOC,f,2,p2+1,float);    f[0][0] = f[1][0] = 1.0;    f[0][1] = (float)-2.0*cos((double)w[1]*M_PI);    f[1][1] = (float)-2.0*cos((double)w[2]*M_PI);    k = 3;    for(i=2; i <= p2; i++)    {        c[0] = (float)-2.0*cos((double)w[k++]*M_PI);        c[1] = (float)-2.0*cos((double)w[k++]*M_PI);        f[0][i] = f[0][i-2];        f[1][i] = f[1][i-2];        for(j=i; j >= 2; j--)        {            f[0][j] += c[0]*f[0][j-1]+f[0][j-2];            f[1][j] += c[1]*f[1][j-1]+f[1][j-2];        }        f[0][1] += c[0]*f[0][0];        f[1][1] += c[1]*f[1][0];    }    for(i=p2; i > 0; i--)    {        f[0][i] += f[0][i-1];        f[1][i] -= f[1][i-1];        a[i] = 0.50*(f[0][i]+f[1][i]);        a[p+1-i] = 0.50*(f[0][i]-f[1][i]);    }    MEM_2FREE(FREE,f);    return(0);}/* LPC_REFL2PRED      get predictor coefficients from the reflection coeffs      Input:         k- the reflection coeffs         p- the predictor order      Output:         a- the predictor coefficients   Reference:  Markel and Gray, Linear Prediction of Speech*/int lpc_refl2pred(float *k,float *a,int p){    int   i,j;    float *a1;    MEM_ALLOC(MALLOC,a1,p+1,float);    for(i=1; i <= p; i++)    {        /* refl to a recursion */        a[i] = k[i];        for(j=1; j < i; j++)            a1[j] = a[j];        for(j=1; j < i; j++)            a[j] = a1[j] + k[i]*a1[i-j];    }    MEM_FREE(FREE,a1);    return(0);} /* LPC_REFL2PRED *//* G - compute the value of the Chebychev series                sum c_k T_k(x) = x b_1(x) - b_2(x) + c_0                b_k(x) = 2x b_{k+1}(x) - b_{k+2}(x) + c_k */static float lsp_g(float x,float *c,int p2){    int i;    float b[3];    b[1] = b[2] = 0.0;    for(i=p2; i > 0; i--)    {        b[0] = 2.0*x*b[1] - b[2] + c[i];        b[2] = b[1];        b[1] = b[0];    }    b[0] = x*b[1]-b[2]+c[0];    return(b[0]);} /* G *//* LSP_ROOTS        - find the roots of the two polynomials G_1(x) and G_2(x)          the first root corresponds to G_1(x)          compute the inverse cos (and these are the LSFs) */static int lsp_roots(float *w,float **c,int p2){    int i,k;    float x,x0,x1,y,*ptr,g0,g1;    w[0] = 0.0;    ptr = c[0];    x = 1.0;    g0 = lsp_g(x,ptr,p2);    for(k=1,x = 1.0-DELTA; x > -DELTA-1.0; x -= DELTA)    {        /* Search for a zero crossing */        if (g0*(g1 = lsp_g(x,ptr,p2)) <= 0.0)        {            /* Search Incrementally using bisection */            x0 = x+DELTA;            x1 = x;            for(i=0; i < BISECTIONS; i++)            {                x = (x0+x1)/2.0;                y = lsp_g(x,ptr,p2);                if(y*g0 < 0.0)                {                    x1 = x;                    g1 = y;                }                else                {                    x0 = x;                    g0 = y;                }            }            /* Linear interpolate */            x = (g1*x0-g0*x1)/(g1-g0);            /* Evaluate the LSF */            w[k] = (float)acos((double)x)/M_PI;            ptr = c[k % 2];            k++;            if (k > 2*p2)                return(0);            g1 = lsp_g(x,ptr,p2);        }        g0 = g1;    }    (void)fprintf(stderr,"\n Error(lsp_roots): LSPs Not All Found\n");    return(1);} /* LSP_ROOTS *//*    Name: lpc_syn- LPC synthesis filter.    Aliases: lpc_synthesis    Description:        LPC all-pole synthesis filter<nf>        for j = 0 to n-1            y[j] = x[j] - sum(k=1 to p) y[j-k] a[k]</nf>    Inputs:        x- input vector (n samples, x[0..n-1])        a- lpc vector (order p, a[1..p])        p- order of lpc filter        n- number of elements in vector which is to be filtered        y[-p..-1]- filter memory (past outputs)    Outputs:        y- output vector (n samples, y[0..n-1])    Returns: NULL    Includes:        spbstd.h        lpc.h    Systems and Info. Science Lab    Copyright (c) 1995 by Texas Instruments, Inc.  All rights reserved.*/int lpc_syn(float *x,float *y,float *a,int p,int n){    int i,j;    for(j=0; j < n; j++)    {        for(i=p,y[j]=x[j]; i > 0; i--)            y[j] -= y[j-i]*a[i];    }    return(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -