123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- #include <stdlib.h>
- #include <string.h>
- #include <math.h>
- #include "os.h"
- #include "smallft.h"
- #include "lpc.h"
- #include "scales.h"
- #include "misc.h"
- float vorbis_lpc_from_data(float *data,float *lpci,int n,int m){
- double *aut=alloca(sizeof(*aut)*(m+1));
- double *lpc=alloca(sizeof(*lpc)*(m));
- double error;
- double epsilon;
- int i,j;
-
- j=m+1;
- while(j--){
- double d=0;
- for(i=j;i<n;i++)d+=(double)data[i]*data[i-j];
- aut[j]=d;
- }
-
-
- error=aut[0] * (1. + 1e-10);
- epsilon=1e-9*aut[0]+1e-10;
- for(i=0;i<m;i++){
- double r= -aut[i+1];
- if(error<epsilon){
- memset(lpc+i,0,(m-i)*sizeof(*lpc));
- goto done;
- }
-
- for(j=0;j<i;j++)r-=lpc[j]*aut[i-j];
- r/=error;
-
- lpc[i]=r;
- for(j=0;j<i/2;j++){
- double tmp=lpc[j];
- lpc[j]+=r*lpc[i-1-j];
- lpc[i-1-j]+=r*tmp;
- }
- if(i&1)lpc[j]+=lpc[j]*r;
- error*=1.-r*r;
- }
- done:
-
- {
- double g = .99;
- double damp = g;
- for(j=0;j<m;j++){
- lpc[j]*=damp;
- damp*=g;
- }
- }
- for(j=0;j<m;j++)lpci[j]=(float)lpc[j];
-
- return error;
- }
- void vorbis_lpc_predict(float *coeff,float *prime,int m,
- float *data,long n){
-
- long i,j,o,p;
- float y;
- float *work=alloca(sizeof(*work)*(m+n));
- if(!prime)
- for(i=0;i<m;i++)
- work[i]=0.f;
- else
- for(i=0;i<m;i++)
- work[i]=prime[i];
- for(i=0;i<n;i++){
- y=0;
- o=i;
- p=m;
- for(j=0;j<m;j++)
- y-=work[o++]*coeff[--p];
- data[i]=work[o]=y;
- }
- }
|