examples/sfexamples/oggvorbiscodec/src/libvorbis/lib/lsp.c

00001 /********************************************************************
00002  *                                                                  *
00003  * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
00004  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
00005  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
00006  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
00007  *                                                                  *
00008  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2002             *
00009  * by the XIPHOPHORUS Company http://www.xiph.org/                  *
00010  *                                                                  *
00011  ********************************************************************
00012 
00013   function: LSP (also called LSF) conversion routines
00014   last mod: $Id: lsp.c 7187 2004-07-20 07:24:27Z xiphmont $
00015 
00016   The LSP generation code is taken (with minimal modification and a
00017   few bugfixes) from "On the Computation of the LSP Frequencies" by
00018   Joseph Rothweiler (see http://www.rothweiler.us for contact info).
00019   The paper is available at:
00020 
00021   http://www.myown1.com/joe/lsf
00022 
00023  ********************************************************************/
00024 
00025 /* Note that the lpc-lsp conversion finds the roots of polynomial with
00026    an iterative root polisher (CACM algorithm 283).  It *is* possible
00027    to confuse this algorithm into not converging; that should only
00028    happen with absurdly closely spaced roots (very sharp peaks in the
00029    LPC f response) which in turn should be impossible in our use of
00030    the code.  If this *does* happen anyway, it's a bug in the floor
00031    finder; find the cause of the confusion (probably a single bin
00032    spike or accidental near-float-limit resolution problems) and
00033    correct it. */
00034 
00035 #include <math.h>
00036 #include <string.h>
00037 #include <stdlib.h>
00038 #include "lsp.h"
00039 #include "os.h"
00040 #include "misc.h"
00041 #include "lookup.h"
00042 #include "scales.h"
00043 
00044 /* three possible LSP to f curve functions; the exact computation
00045    (float), a lookup based float implementation, and an integer
00046    implementation.  The float lookup is likely the optimal choice on
00047    any machine with an FPU.  The integer implementation is *not* fixed
00048    point (due to the need for a large dynamic range and thus a
00049    seperately tracked exponent) and thus much more complex than the
00050    relatively simple float implementations. It's mostly for future
00051    work on a fully fixed point implementation for processors like the
00052    ARM family. */
00053 
00054 /* undefine both for the 'old' but more precise implementation */
00055 #define   FLOAT_LOOKUP
00056 #undef    INT_LOOKUP
00057 
00058 #ifdef FLOAT_LOOKUP
00059 #include "lookup.c" /* catch this in the build system; we #include for
00060                        compilers (like gcc) that can't inline across
00061                        modules */
00062 
00063 /* side effect: changes *lsp to cosines of lsp */
00064 void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
00065                             float amp,float ampoffset){
00066   int i;
00067   float wdel=M_PI/ln;
00068   //vorbis_fpu_control fpu;
00069   //fpu = fpu;//warning
00070   //vorbis_fpu_setround(&fpu);
00071   for(i=0;i<m;i++)lsp[i]=vorbis_coslook(lsp[i]);
00072 
00073   i=0;
00074   while(i<n){
00075     int k=map[i];
00076     int qexp;
00077     float p=.7071067812f;
00078     float q=.7071067812f;
00079     float w=vorbis_coslook(wdel*k);
00080     float *ftmp=lsp;
00081     int c=m>>1;
00082 
00083     do{
00084       q*=ftmp[0]-w;
00085       p*=ftmp[1]-w;
00086       ftmp+=2;
00087     }while(--c);
00088 
00089     if(m&1){
00090       /* odd order filter; slightly assymetric */
00091       /* the last coefficient */
00092       q*=ftmp[0]-w;
00093       q*=q;
00094       p*=p*(1.f-w*w);
00095     }else{
00096       /* even order filter; still symmetric */
00097       q*=q*(1.f+w);
00098       p*=p*(1.f-w);
00099     }
00100 
00101     q=frexp(p+q,&qexp);
00102     q=vorbis_fromdBlook(amp*             
00103                         vorbis_invsqlook(q)*
00104                         vorbis_invsq2explook(qexp+m)- 
00105                         ampoffset);
00106 
00107     do{
00108       curve[i++]*=q;
00109     }while(map[i]==k);
00110   }
00111   //vorbis_fpu_restore(fpu);
00112 }
00113 
00114 #else
00115 
00116 #ifdef INT_LOOKUP
00117 #include "lookup.c" /* catch this in the build system; we #include for
00118                        compilers (like gcc) that can't inline across
00119                        modules */
00120 
00121 static int MLOOP_1[64]={
00122    0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
00123   14,14,14,14, 14,14,14,14, 14,14,14,14, 14,14,14,14,
00124   15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
00125   15,15,15,15, 15,15,15,15, 15,15,15,15, 15,15,15,15,
00126 };
00127 
00128 static int MLOOP_2[64]={
00129   0,4,5,5, 6,6,6,6, 7,7,7,7, 7,7,7,7,
00130   8,8,8,8, 8,8,8,8, 8,8,8,8, 8,8,8,8,
00131   9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
00132   9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
00133 };
00134 
00135 static int MLOOP_3[8]={0,1,2,2,3,3,3,3};
00136 
00137 
00138 /* side effect: changes *lsp to cosines of lsp */
00139 void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
00140                             float amp,float ampoffset){
00141 
00142   /* 0 <= m < 256 */
00143 
00144   /* set up for using all int later */
00145   int i;
00146   int ampoffseti=rint(ampoffset*4096.f);
00147   int ampi=rint(amp*16.f);
00148   long *ilsp=alloca(m*sizeof(*ilsp));
00149   for(i=0;i<m;i++)ilsp[i]=vorbis_coslook_i(lsp[i]/M_PI*65536.f+.5f);
00150 
00151   i=0;
00152   while(i<n){
00153     int j,k=map[i];
00154     unsigned long pi=46341; /* 2**-.5 in 0.16 */
00155     unsigned long qi=46341;
00156     int qexp=0,shift;
00157     long wi=vorbis_coslook_i(k*65536/ln);
00158 
00159     qi*=labs(ilsp[0]-wi);
00160     pi*=labs(ilsp[1]-wi);
00161 
00162     for(j=3;j<m;j+=2){
00163       if(!(shift=MLOOP_1[(pi|qi)>>25]))
00164         if(!(shift=MLOOP_2[(pi|qi)>>19]))
00165           shift=MLOOP_3[(pi|qi)>>16];
00166       qi=(qi>>shift)*labs(ilsp[j-1]-wi);
00167       pi=(pi>>shift)*labs(ilsp[j]-wi);
00168       qexp+=shift;
00169     }
00170     if(!(shift=MLOOP_1[(pi|qi)>>25]))
00171       if(!(shift=MLOOP_2[(pi|qi)>>19]))
00172         shift=MLOOP_3[(pi|qi)>>16];
00173 
00174     /* pi,qi normalized collectively, both tracked using qexp */
00175 
00176     if(m&1){
00177       /* odd order filter; slightly assymetric */
00178       /* the last coefficient */
00179       qi=(qi>>shift)*labs(ilsp[j-1]-wi);
00180       pi=(pi>>shift)<<14;
00181       qexp+=shift;
00182 
00183       if(!(shift=MLOOP_1[(pi|qi)>>25]))
00184         if(!(shift=MLOOP_2[(pi|qi)>>19]))
00185           shift=MLOOP_3[(pi|qi)>>16];
00186       
00187       pi>>=shift;
00188       qi>>=shift;
00189       qexp+=shift-14*((m+1)>>1);
00190 
00191       pi=((pi*pi)>>16);
00192       qi=((qi*qi)>>16);
00193       qexp=qexp*2+m;
00194 
00195       pi*=(1<<14)-((wi*wi)>>14);
00196       qi+=pi>>14;
00197 
00198     }else{
00199       /* even order filter; still symmetric */
00200 
00201       /* p*=p(1-w), q*=q(1+w), let normalization drift because it isn't
00202          worth tracking step by step */
00203       
00204       pi>>=shift;
00205       qi>>=shift;
00206       qexp+=shift-7*m;
00207 
00208       pi=((pi*pi)>>16);
00209       qi=((qi*qi)>>16);
00210       qexp=qexp*2+m;
00211       
00212       pi*=(1<<14)-wi;
00213       qi*=(1<<14)+wi;
00214       qi=(qi+pi)>>14;
00215       
00216     }
00217     
00218 
00219     /* we've let the normalization drift because it wasn't important;
00220        however, for the lookup, things must be normalized again.  We
00221        need at most one right shift or a number of left shifts */
00222 
00223     if(qi&0xffff0000){ /* checks for 1.xxxxxxxxxxxxxxxx */
00224       qi>>=1; qexp++; 
00225     }else
00226       while(qi && !(qi&0x8000)){ /* checks for 0.0xxxxxxxxxxxxxxx or less*/
00227         qi<<=1; qexp--; 
00228       }
00229 
00230     amp=vorbis_fromdBlook_i(ampi*                     /*  n.4         */
00231                             vorbis_invsqlook_i(qi,qexp)- 
00232                                                       /*  m.8, m+n<=8 */
00233                             ampoffseti);              /*  8.12[0]     */
00234 
00235     curve[i]*=amp;
00236     while(map[++i]==k)curve[i]*=amp;
00237   }
00238 }
00239 
00240 #else 
00241 
00242 /* old, nonoptimized but simple version for any poor sap who needs to
00243    figure out what the hell this code does, or wants the other
00244    fraction of a dB precision */
00245 
00246 /* side effect: changes *lsp to cosines of lsp */
00247 void vorbis_lsp_to_curve(float *curve,int *map,int n,int ln,float *lsp,int m,
00248                             float amp,float ampoffset){
00249   int i;
00250   float wdel=M_PI/ln;
00251   for(i=0;i<m;i++)lsp[i]=2.f*cos(lsp[i]);
00252 
00253   i=0;
00254   while(i<n){
00255     int j,k=map[i];
00256     float p=.5f;
00257     float q=.5f;
00258     float w=2.f*cos(wdel*k);
00259     for(j=1;j<m;j+=2){
00260       q *= w-lsp[j-1];
00261       p *= w-lsp[j];
00262     }
00263     if(j==m){
00264       /* odd order filter; slightly assymetric */
00265       /* the last coefficient */
00266       q*=w-lsp[j-1];
00267       p*=p*(4.f-w*w);
00268       q*=q;
00269     }else{
00270       /* even order filter; still symmetric */
00271       p*=p*(2.f-w);
00272       q*=q*(2.f+w);
00273     }
00274 
00275     q=fromdB(amp/sqrt(p+q)-ampoffset);
00276 
00277     curve[i]*=q;
00278     while(map[++i]==k)curve[i]*=q;
00279   }
00280 }
00281 
00282 #endif
00283 #endif
00284 
00285 static void cheby(float *g, int ord) {
00286   int i, j;
00287 
00288   g[0] *= .5f;
00289   for(i=2; i<= ord; i++) {
00290     for(j=ord; j >= i; j--) {
00291       g[j-2] -= g[j];
00292       g[j] += g[j]; 
00293     }
00294   }
00295 }
00296 
00297 static int comp(const void *a,const void *b){
00298   return (*(float *)a<*(float *)b)-(*(float *)a>*(float *)b);
00299 }
00300 
00301 /* Newton-Raphson-Maehly actually functioned as a decent root finder,
00302    but there are root sets for which it gets into limit cycles
00303    (exacerbated by zero suppression) and fails.  We can't afford to
00304    fail, even if the failure is 1 in 100,000,000, so we now use
00305    Laguerre and later polish with Newton-Raphson (which can then
00306    afford to fail) */
00307 
00308 #define EPSILON 10e-7
00309 static int Laguerre_With_Deflation(float *a,int ord,float *r){
00310   int i,m;
00311   //double lastdelta=0.f;//warning
00312   double *defl= (double*)_ogg_malloc(sizeof(*defl)*(ord+1)); //alloca(sizeof(*defl)*(ord+1)); //patch
00313   double *defl_cpy = defl;
00314   for(i=0;i<=ord;i++)defl[i]=a[i];
00315 
00316   for(m=ord;m>0;m--){
00317     double newval = 0.f,delta;
00318 
00319     /* iterate a root */
00320     while(1){
00321       double p=defl[m],pp=0.f,ppp=0.f,denom;
00322       
00323       /* eval the polynomial and its first two derivatives */
00324       for(i=m;i>0;i--){
00325         ppp = newval*ppp + pp;
00326         pp  = newval*pp  + p;
00327         p   = newval*p   + defl[i-1];
00328       }
00329       
00330       /* Laguerre's method */
00331       denom=(m-1) * ((m-1)*pp*pp - m*p*ppp);
00332       if(denom<0){  
00333                 free(defl_cpy); //patch          
00334         return(-1);  /* complex root!  The LPC generator handed us a bad filter */                      
00335       }
00336         
00337 
00338       if(pp>0){
00339         denom = pp + sqrt(denom);
00340         if(denom<EPSILON)denom=EPSILON;
00341       }else{
00342         denom = pp - sqrt(denom);
00343         if(denom>-(EPSILON))denom=-(EPSILON);
00344       }
00345 
00346       delta  = m*p/denom;
00347       newval   -= delta;
00348 
00349       if(delta<0.f)delta*=-1;
00350 
00351       if(fabs(delta/newval)<10e-12)break; 
00352       //lastdelta=delta;
00353     }
00354 
00355     r[m-1]=newval;
00356 
00357     /* forward deflation */
00358     
00359     for(i=m;i>0;i--)
00360       defl[i-1]+=newval*defl[i];
00361     defl++;
00362 
00363   }
00364   
00365   free(defl_cpy); //patch
00366   return(0);
00367 }
00368 
00369 
00370 /* for spit-and-polish only */
00371 static int Newton_Raphson(float *a,int ord,float *r)
00372 {
00373   int i, k, count=0;
00374   double error=1.f;
00375   double *root= (double*)_ogg_malloc(ord*sizeof(*root));//alloca(ord*sizeof(*root));//patch
00376   double *root_cpy = root; //patch
00377   
00378   for(i=0; i<ord;i++) root[i] = r[i];
00379   
00380   while(error>1e-20){
00381     error=0;
00382     
00383     for(i=0; i<ord; i++) { /* Update each point. */
00384       double pp=0.,delta;
00385       double rooti=root[i];
00386       double p=a[ord];
00387       for(k=ord-1; k>= 0; k--) {
00388 
00389         pp= pp* rooti + p;
00390         p = p * rooti + a[k];
00391       }
00392 
00393       delta = p/pp;
00394       root[i] -= delta;
00395       error+= delta*delta;
00396     }
00397     
00398     if(count>40){
00399         free(root_cpy); //patch
00400         return(-1);     
00401     }
00402     
00403      
00404     count++;
00405   }
00406 
00407   /* Replaced the original bubble sort with a real sort.  With your
00408      help, we can eliminate the bubble sort in our lifetime. --Monty */
00409 
00410   for(i=0; i<ord;i++) r[i] = root[i];
00411   free(root_cpy); //patch
00412   return(0);
00413 }
00414 
00415 
00416 /* Convert lpc coefficients to lsp coefficients */
00417 int vorbis_lpc_to_lsp(float *lpc,float *lsp,int m){
00418   int order2=(m+1)>>1;
00419   int g1_order,g2_order;
00420   /*
00421   float *g1=alloca(sizeof(*g1)*(order2+1));
00422   float *g2=alloca(sizeof(*g2)*(order2+1));
00423   float *g1r=alloca(sizeof(*g1r)*(order2+1));
00424   float *g2r=alloca(sizeof(*g2r)*(order2+1));
00425   */
00426   //-------patch
00427   float *g1=(float*)_ogg_malloc(sizeof(*g1)*(order2+1));
00428   float *g2=(float*)_ogg_malloc(sizeof(*g2)*(order2+1));
00429   float *g1r=(float*)_ogg_malloc(sizeof(*g1r)*(order2+1));
00430   float *g2r=(float*)_ogg_malloc(sizeof(*g2r)*(order2+1));
00431   float *g1_cpy = g1;
00432   float *g2_cpy = g2;
00433   float *g1r_cpy = g1r;
00434   float *g2r_cpy = g2r;
00435   //-------patch
00436   int i;
00437 
00438   /* even and odd are slightly different base cases */
00439   g1_order=(m+1)>>1;
00440   g2_order=(m)  >>1;
00441 
00442   /* Compute the lengths of the x polynomials. */
00443   /* Compute the first half of K & R F1 & F2 polynomials. */
00444   /* Compute half of the symmetric and antisymmetric polynomials. */
00445   /* Remove the roots at +1 and -1. */
00446   
00447   g1[g1_order] = 1.f;
00448   for(i=1;i<=g1_order;i++) g1[g1_order-i] = lpc[i-1]+lpc[m-i];
00449   g2[g2_order] = 1.f;
00450   for(i=1;i<=g2_order;i++) g2[g2_order-i] = lpc[i-1]-lpc[m-i];
00451   
00452   if(g1_order>g2_order){
00453     for(i=2; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+2];
00454   }else{
00455     for(i=1; i<=g1_order;i++) g1[g1_order-i] -= g1[g1_order-i+1];
00456     for(i=1; i<=g2_order;i++) g2[g2_order-i] += g2[g2_order-i+1];
00457   }
00458 
00459   /* Convert into polynomials in cos(alpha) */
00460   cheby(g1,g1_order);
00461   cheby(g2,g2_order);
00462 
00463   /* Find the roots of the 2 even polynomials.*/
00464   if(Laguerre_With_Deflation(g1,g1_order,g1r) ||
00465      Laguerre_With_Deflation(g2,g2_order,g2r)){
00466         //--patch
00467         free(g1_cpy);
00468         free(g2_cpy);
00469         free(g1r_cpy); 
00470         free(g2r_cpy);
00471         //--patch     
00472         return(-1);     
00473   }
00474     
00475 
00476   Newton_Raphson(g1,g1_order,g1r); /* if it fails, it leaves g1r alone */
00477   Newton_Raphson(g2,g2_order,g2r); /* if it fails, it leaves g2r alone */
00478 
00479   qsort(g1r,g1_order,sizeof(*g1r),comp);
00480   qsort(g2r,g2_order,sizeof(*g2r),comp);
00481 
00482   for(i=0;i<g1_order;i++)
00483     lsp[i*2] = acos(g1r[i]);
00484 
00485   for(i=0;i<g2_order;i++)
00486     lsp[i*2+1] = acos(g2r[i]);
00487     
00488   //--patch
00489   free(g1_cpy);
00490   free(g2_cpy);
00491   free(g1r_cpy); 
00492   free(g2r_cpy);          
00493   //--patch  
00494   
00495   return(0);
00496 }

Generated by  doxygen 1.6.2