X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=lib%2Flpc.c;h=877da47f8efeb9ee138479f4a152d793e0fdc878;hb=4ba8efed8797016a85e57bc3cc7975bb31d65db5;hp=7382636a0bcd3d6bb95ea18554e6443aec36b87e;hpb=f6246535ae25ac62560acecb35036dd4239a95d5;p=platform%2Fupstream%2Flibvorbis.git diff --git a/lib/lpc.c b/lib/lpc.c index 7382636..877da47 100644 --- a/lib/lpc.c +++ b/lib/lpc.c @@ -1,18 +1,16 @@ /******************************************************************** * * - * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. * - * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY * - * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. * - * PLEASE READ THESE TERMS DISTRIBUTING. * + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE * + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * * * - * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 * - * by Monty and The XIPHOPHORUS Company * - * http://www.xiph.org/ * + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009 * + * by the Xiph.Org Foundation https://xiph.org/ * * * ******************************************************************** function: LPC low level routines - last mod: $Id: lpc.c,v 1.16 2000/02/06 13:39:42 xiphmont Exp $ ********************************************************************/ @@ -45,13 +43,13 @@ Carsten Bormann *********************************************************************/ #include -#include #include #include #include "os.h" #include "smallft.h" #include "lpc.h" #include "scales.h" +#include "misc.h" /* Autocorrelation LPC coeff generation algorithm invented by N. Levinson in 1947, modified by J. Durbin in 1959. */ @@ -59,30 +57,34 @@ Carsten Bormann /* Input : n elements of time doamin data Output: m lpc coefficients, excitation energy */ -double vorbis_lpc_from_data(double *data,double *lpc,int n,int m){ - double *aut=alloca(sizeof(double)*(m+1)); +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; /* autocorrelation, p+1 lag coefficients */ - j=m+1; while(j--){ - double d=0; - for(i=j;iln; - int m=l->m; - double *work=alloca(sizeof(double)*(n+n)); - double fscale=.5/n; - int i,j; - - /* input is a real curve. make it complex-real */ - /* This mixes phase, but the LPC generation doesn't care. */ - for(i=0;ifft,work); - - /* The autocorrelation will not be circular. Shift, else we lose - most of the power in the edges. */ - - for(i=0,j=n/2;in=n; - l->ln=mapped; - l->m=m; + done: - l->linearmap=malloc(n*sizeof(int)); - l->barknorm=malloc(mapped*sizeof(double)); - - /* we choose a scaling constant so that: - floor(bark(rate-1)*C)=mapped-1 - floor(bark(rate)*C)=mapped */ - - scale=mapped/toBARK(rate); - - /* the mapping from a linear scale to a smaller bark scale is - straightforward. We do *not* make sure that the linear mapping - does not skip bark-scale bins; the decoder simply skips them and - the encoder may do what it wishes in filling them. They're - necessary in some mapping combinations to keep the scale spacing - accurate */ + /* slightly damp the filter */ { - int last=-1; - for(i=0;i=mapped)val=mapped; /* guard against the approximation */ - l->linearmap[i]=val; - last=val; - } - } - - /* 'Normalization' is just making sure that power isn't lost in the - log scale by virtue of compressing the scale in higher - frequencies. We figure the weight of bands in proportion to - their linear/bark width ratio below, again, authoritatively. We - use computed width (not the number of actual bins above) for - smoothness in the scale; they should agree closely */ - - for(i=0;ibarknorm[i]=fromBARK((i+1)/scale)-fromBARK(i/scale); - - /* we cheat decoding the LPC spectrum via FFTs */ - - drft_init(&l->fft,mapped*2); - -} - -void lpc_clear(lpc_lookup *l){ - if(l){ - if(l->barknorm)free(l->barknorm); - if(l->linearmap)free(l->linearmap); - drft_clear(&l->fft); - } -} - - -/* less efficient than the decode side (written for clarity). We're - not bottlenecked here anyway */ - -double vorbis_curve_to_lpc(double *curve,double *lpc,lpc_lookup *l){ - /* map the input curve to a bark-scale curve for encoding */ - - int mapped=l->ln; - double *work=alloca(sizeof(double)*mapped); - int i,j,last=0; - - memset(work,0,sizeof(double)*mapped); - - /* Only the decode side is behavior-specced; for now in the encoder, - we select the maximum value of each band as representative (this - helps make sure peaks don't go out of range. In error terms, - selecting min would make more sense, but the codebook is trained - numerically, so we don't actually lose. We'd still want to - use the original curve for error and noise estimation */ - - for(i=0;in;i++){ - int bark=l->linearmap[i]; - if(work[bark]last+1){ - /* If the bark scale is climbing rapidly, some bins may end up - going unused. This isn't a waste actually; it keeps the - scale resolution even so that the LPC generator has an easy - time. However, if we leave the bins empty we lose energy. - So, fill 'em in. The decoder does not do anything witht he - unused bins, so we can fill them anyway we like to end up - with a better spectral curve */ - - /* we'll always have a bin zero, so we don't need to guard init */ - long span=bark-last; - for(j=1;jbarknorm[i]; - -#ifdef ANALYSIS - { - int j; - FILE *out; - char buffer[80]; - static int frameno=0; - - sprintf(buffer,"prelpc%d.m",frameno); - out=fopen(buffer,"w+"); - for(j=0;jn;j++) - fprintf(out,"%g\n",curve[j]); - fclose(out); - sprintf(buffer,"preloglpc%d.m",frameno++); - out=fopen(buffer,"w+"); - for(j=0;jln;j++) - fprintf(out,"%g\n",work[j]); - fclose(out); - } -#endif - - return vorbis_lpc_from_spectrum(work,lpc,l); -} + for(j=0;jln*2); - if(amp==0)return; - - for(i=0;im;i++){ - curve[i*2+1]=lpc[i]/4/amp; - curve[i*2+2]=-lpc[i]/4/amp; - } - - drft_backward(&l->fft,curve); /* reappropriated ;-) */ - - { - int l2=l->ln*2; - double unit=1./amp; - curve[0]=(1./(curve[0]*2+unit)); - for(i=1;iln;i++){ - double real=(curve[i]+curve[l2-i]); - double imag=(curve[i]-curve[l2-i]); - curve[i]=(1./hypot(real+unit,imag)); - } - } -} - - -/* generate the whole freq response curve of an LPC IIR filter */ - -void vorbis_lpc_to_curve(double *curve,double *lpc,double amp,lpc_lookup *l){ - double *lcurve=alloca(sizeof(double)*(l->ln*2)); - int i; - - if(amp==0){ - memset(curve,0,sizeof(double)*l->n); - return; - } - _vlpc_de_helper(lcurve,lpc,amp,l); - -#ifdef ANALYSIS - { - static int frameno=0; - int j; - FILE *out; - char buffer[80]; - - sprintf(buffer,"loglpc%d.m",frameno++); - out=fopen(buffer,"w+"); - for(j=0;jln;j++) - fprintf(out,"%g\n",lcurve[j]); - fclose(out); - -#endif - - for(i=0;iln;i++)lcurve[i]/=l->barknorm[i]; - for(i=0;in;i++)curve[i]=lcurve[l->linearmap[i]]; - -#ifdef ANALYSIS - - sprintf(buffer,"lpc%d.m",frameno-1); - out=fopen(buffer,"w+"); - for(j=0;jn;j++) - fprintf(out,"%g\n",curve[j]); - fclose(out); - } -#endif -} - -/* subtract or add an lpc filter to data. Vorbis doesn't actually use this. */ - -void vorbis_lpc_residue(double *coeff,double *prime,int m, - double *data,long n){ - - /* in: coeff[0...m-1] LPC coefficients - prime[0...m-1] initial values - data[0...n-1] data samples - out: data[0...n-1] residuals from LPC prediction */ - - long i,j; - double *work=alloca(sizeof(double)*(m+n)); - double y; - - if(!prime) - for(i=0;i