misc/libtremor/tremor/floor0.c
changeset 7697 767d3c4153a1
parent 6045 9a7cc0f29430
child 7849 a12155461b34
equal deleted inserted replaced
7696:78a00bc68913 7697:767d3c4153a1
     4  *                                                                  *
     4  *                                                                  *
     5  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
     5  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
     6  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
     6  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
     7  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
     7  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
     8  *                                                                  *
     8  *                                                                  *
     9  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
     9  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2003    *
    10  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
    10  * BY THE Xiph.Org FOUNDATION http://www.xiph.org/                  *
    11  *                                                                  *
    11  *                                                                  *
    12  ********************************************************************
    12  ********************************************************************
    13 
    13 
    14  function: floor backend 0 implementation
    14  function: floor backend 0 implementation
    19 #include <string.h>
    19 #include <string.h>
    20 #include <math.h>
    20 #include <math.h>
    21 #include "ogg.h"
    21 #include "ogg.h"
    22 #include "ivorbiscodec.h"
    22 #include "ivorbiscodec.h"
    23 #include "codec_internal.h"
    23 #include "codec_internal.h"
    24 #include "registry.h"
       
    25 #include "codebook.h"
    24 #include "codebook.h"
    26 #include "misc.h"
    25 #include "misc.h"
    27 #include "block.h"
    26 #include "os.h"
    28 
    27 
    29 #define LSP_FRACBITS 14
    28 #define LSP_FRACBITS 14
    30 
    29 extern const ogg_int32_t FLOOR_fromdB_LOOKUP[];
    31 typedef struct {
       
    32   long n;
       
    33   int ln;
       
    34   int  m;
       
    35   int *linearmap;
       
    36 
       
    37   vorbis_info_floor0 *vi;
       
    38   ogg_int32_t *lsp_look;
       
    39 
       
    40 } vorbis_look_floor0;
       
    41 
    30 
    42 /*************** LSP decode ********************/
    31 /*************** LSP decode ********************/
    43 
    32 
    44 #include "lsp_lookup.h"
    33 #include "lsp_lookup.h"
    45 
    34 
    46 /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
    35 /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
    47    16.16 format 
    36    16.16 format 
    48    returns in m.8 format */
    37    returns in m.8 format */
    49 
    38 
    50 static long ADJUST_SQRT2[2]={8192,5792};
    39 static long ADJUST_SQRT2[2]={8192,5792};
    51 STIN ogg_int32_t vorbis_invsqlook_i(long a,long e){
    40 static inline ogg_int32_t vorbis_invsqlook_i(long a,long e){
    52   long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); 
    41   long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); 
    53   long d=a&INVSQ_LOOKUP_I_MASK;                              /*  0.10 */
    42   long d=a&INVSQ_LOOKUP_I_MASK;                              /*  0.10 */
    54   long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
    43   long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
    55     ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT);        /* result 1.16 */
    44     ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT);        /* result 1.16 */
    56   val*=ADJUST_SQRT2[e&1];
    45   val*=ADJUST_SQRT2[e&1];
    58   return(val>>e);
    47   return(val>>e);
    59 }
    48 }
    60 
    49 
    61 /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
    50 /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
    62 /* a is in n.12 format */
    51 /* a is in n.12 format */
    63 STIN ogg_int32_t vorbis_fromdBlook_i(long a){
    52 #ifdef _LOW_ACCURACY_
    64   int i=(-a)>>(12-FROMdB2_SHIFT);
    53 static inline ogg_int32_t vorbis_fromdBlook_i(long a){
    65   if(i<0) return 0x7fffffff;
    54   if(a>0) return 0x7fffffff;
    66   if(i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))return 0;
    55   if(a<(-140<<12)) return 0;
    67   
    56   return FLOOR_fromdB_LOOKUP[((a+140)*467)>>20]<<9;
    68   return FROMdB_LOOKUP[i>>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK];
    57 }
    69 }
    58 #else
       
    59 static inline ogg_int32_t vorbis_fromdBlook_i(long a){
       
    60   if(a>0) return 0x7fffffff;
       
    61   if(a<(-140<<12)) return 0;
       
    62   return FLOOR_fromdB_LOOKUP[((a+(140<<12))*467)>>20];
       
    63 }
       
    64 #endif
    70 
    65 
    71 /* interpolated lookup based cos function, domain 0 to PI only */
    66 /* interpolated lookup based cos function, domain 0 to PI only */
    72 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
    67 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
    73 STIN ogg_int32_t vorbis_coslook_i(long a){
    68 static inline ogg_int32_t vorbis_coslook_i(long a){
    74   int i=a>>COS_LOOKUP_I_SHIFT;
    69   int i=a>>COS_LOOKUP_I_SHIFT;
    75   int d=a&COS_LOOKUP_I_MASK;
    70   int d=a&COS_LOOKUP_I_MASK;
    76   return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    71   return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    77 			   COS_LOOKUP_I_SHIFT);
    72 			   COS_LOOKUP_I_SHIFT);
    78 }
    73 }
    79 
    74 
    80 /* interpolated lookup based cos function */
    75 /* interpolated half-wave lookup based cos function */
    81 /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
    76 /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
    82 STIN ogg_int32_t vorbis_coslook2_i(long a){
    77 static inline ogg_int32_t vorbis_coslook2_i(long a){
    83   a=a&0x1ffff;
    78   int i=a>>COS_LOOKUP_I_SHIFT;
    84 
    79   int d=a&COS_LOOKUP_I_MASK;
    85   if(a>0x10000)a=0x20000-a;
    80   return ((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
    86   {               
    81 	  d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    87     int i=a>>COS_LOOKUP_I_SHIFT;
    82     (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
    88     int d=a&COS_LOOKUP_I_MASK;
    83 }
    89     a=((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
    84 
    90        d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    85 static const ogg_uint16_t barklook[54]={
    91       (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
    86   0,51,102,154,            206,258,311,365,
    92   }
    87   420,477,535,594,         656,719,785,854,
    93   
    88   926,1002,1082,1166,      1256,1352,1454,1564,
    94   return(a);
    89   1683,1812,1953,2107,     2276,2463,2670,2900,
    95 }
    90   3155,3440,3756,4106,     4493,4919,5387,5901,
    96 
    91   6466,7094,7798,8599,     9528,10623,11935,13524,
    97 static const int barklook[28]={
    92   15453,17775,20517,23667, 27183,31004
    98   0,100,200,301,          405,516,635,766,
       
    99   912,1077,1263,1476,     1720,2003,2333,2721,
       
   100   3184,3742,4428,5285,    6376,7791,9662,12181,
       
   101   15624,20397,27087,36554
       
   102 };
    93 };
   103 
    94 
   104 /* used in init only; interpolate the long way */
    95 /* used in init only; interpolate the long way */
   105 STIN ogg_int32_t toBARK(int n){
    96 static inline ogg_int32_t toBARK(int n){
   106   int i;
    97   int i;
   107   for(i=0;i<27;i++) 
    98   for(i=0;i<54;i++) 
   108     if(n>=barklook[i] && n<barklook[i+1])break;
    99     if(n>=barklook[i] && n<barklook[i+1])break;
   109   
   100   
   110   if(i==27){
   101   if(i==54){
   111     return 27<<15;
   102     return 54<<14;
   112   }else{
   103   }else{
   113     int gap=barklook[i+1]-barklook[i];
   104     return (i<<14)+(((n-barklook[i])*  
   114     int del=n-barklook[i];
   105 		     ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17);
   115 
       
   116     return((i<<15)+((del<<15)/gap));
       
   117   }
   106   }
   118 }
   107 }
   119 
   108 
   120 static const unsigned char MLOOP_1[64]={
   109 static const unsigned char MLOOP_1[64]={
   121    0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
   110    0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
   131   9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
   120   9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
   132 };
   121 };
   133 
   122 
   134 static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
   123 static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
   135 
   124 
   136 void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
   125 void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
   137 			 ogg_int32_t *lsp,int m,
   126 			 ogg_int32_t *lsp,int m,
   138 			 ogg_int32_t amp,
   127 			 ogg_int32_t amp,
   139 			 ogg_int32_t ampoffset,
   128 			 ogg_int32_t ampoffset,
   140 			 ogg_int32_t *icos){
   129 			 ogg_int32_t nyq){
   141 
   130 
   142   /* 0 <= m < 256 */
   131   /* 0 <= m < 256 */
   143 
   132 
   144   /* set up for using all int later */
   133   /* set up for using all int later */
   145   int i;
   134   int i;
   146   int ampoffseti=ampoffset*4096;
   135   int ampoffseti=ampoffset*4096;
   147   int ampi=amp;
   136   int ampi=amp;
   148   ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
   137   ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
       
   138 
       
   139   ogg_uint32_t inyq= (1UL<<31) / toBARK(nyq);
       
   140   ogg_uint32_t imap= (1UL<<31) / ln;
       
   141   ogg_uint32_t tBnyq1 = toBARK(nyq)<<1;
       
   142 
       
   143   /* Besenham for frequency scale to avoid a division */
       
   144   int f=0;
       
   145   int fdx=n;
       
   146   int fbase=nyq/fdx;
       
   147   int ferr=0;
       
   148   int fdy=nyq-fbase*fdx;
       
   149   int map=0;
       
   150 
       
   151 #ifdef _LOW_ACCURACY_
       
   152   ogg_uint32_t nextbark=((tBnyq1<<11)/ln)>>12;
       
   153 #else
       
   154   ogg_uint32_t nextbark=MULT31(imap>>1,tBnyq1);
       
   155 #endif
       
   156   int nextf=barklook[nextbark>>14]+(((nextbark&0x3fff)*
       
   157 	    (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
       
   158 
   149   /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
   159   /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
   150   for(i=0;i<m;i++){
   160   for(i=0;i<m;i++){
   151 #ifndef _LOW_ACCURACY_
   161 #ifndef _LOW_ACCURACY_
   152     ogg_int32_t val=MULT32(lsp[i],0x517cc2);
   162     ogg_int32_t val=MULT32(lsp[i],0x517cc2);
   153 #else
   163 #else
   163     ilsp[i]=vorbis_coslook_i(val);
   173     ilsp[i]=vorbis_coslook_i(val);
   164   }
   174   }
   165 
   175 
   166   i=0;
   176   i=0;
   167   while(i<n){
   177   while(i<n){
   168     int j,k=map[i];
   178     int j;
   169     ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
   179     ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
   170     ogg_uint32_t qi=46341;
   180     ogg_uint32_t qi=46341;
   171     ogg_int32_t qexp=0,shift;
   181     ogg_int32_t qexp=0,shift;
   172     ogg_int32_t wi=icos[k];
   182     ogg_int32_t wi;
       
   183 
       
   184     wi=vorbis_coslook2_i((map*imap)>>15);
       
   185 
   173 
   186 
   174 #ifdef _V_LSP_MATH_ASM
   187 #ifdef _V_LSP_MATH_ASM
   175     lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
   188     lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
   176 
   189 
   177     pi=((pi*pi)>>16);
   190     pi=((pi*pi)>>16);
   200     qi*=labs(ilsp[0]-wi);
   213     qi*=labs(ilsp[0]-wi);
   201     pi*=labs(ilsp[1]-wi);
   214     pi*=labs(ilsp[1]-wi);
   202 
   215 
   203     for(j=3;j<m;j+=2){
   216     for(j=3;j<m;j+=2){
   204       if(!(shift=MLOOP_1[(pi|qi)>>25]))
   217       if(!(shift=MLOOP_1[(pi|qi)>>25]))
   205 	if(!(shift=MLOOP_2[(pi|qi)>>19]))
   218       	if(!(shift=MLOOP_2[(pi|qi)>>19]))
   206 	  shift=MLOOP_3[(pi|qi)>>16];
   219       	  shift=MLOOP_3[(pi|qi)>>16];
       
   220       
   207       qi=(qi>>shift)*labs(ilsp[j-1]-wi);
   221       qi=(qi>>shift)*labs(ilsp[j-1]-wi);
   208       pi=(pi>>shift)*labs(ilsp[j]-wi);
   222       pi=(pi>>shift)*labs(ilsp[j]-wi);
   209       qexp+=shift;
   223       qexp+=shift;
   210     }
   224     }
   211     if(!(shift=MLOOP_1[(pi|qi)>>25]))
   225     if(!(shift=MLOOP_1[(pi|qi)>>25]))
   212       if(!(shift=MLOOP_2[(pi|qi)>>19]))
   226       if(!(shift=MLOOP_2[(pi|qi)>>19]))
   213 	shift=MLOOP_3[(pi|qi)>>16];
   227 	shift=MLOOP_3[(pi|qi)>>16];
   214 
   228     
   215     /* pi,qi normalized collectively, both tracked using qexp */
   229     /* pi,qi normalized collectively, both tracked using qexp */
   216 
   230 
   217     if(m&1){
   231     if(m&1){
   218       /* odd order filter; slightly assymetric */
   232       /* odd order filter; slightly assymetric */
   219       /* the last coefficient */
   233       /* the last coefficient */
   277     
   291     
   278 #ifdef _LOW_ACCURACY_
   292 #ifdef _LOW_ACCURACY_
   279     amp>>=9;
   293     amp>>=9;
   280 #endif
   294 #endif
   281     curve[i]= MULT31_SHIFT15(curve[i],amp);
   295     curve[i]= MULT31_SHIFT15(curve[i],amp);
   282     while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp);
   296 
       
   297     while(++i<n){
       
   298 	
       
   299       /* line plot to get new f */
       
   300       ferr+=fdy;
       
   301       if(ferr>=fdx){
       
   302 	ferr-=fdx;
       
   303 	f++;
       
   304       }
       
   305       f+=fbase;
       
   306       
       
   307       if(f>=nextf)break;
       
   308 
       
   309       curve[i]= MULT31_SHIFT15(curve[i],amp);
       
   310     }
       
   311 
       
   312     while(1){
       
   313       map++;
       
   314 
       
   315       if(map+1<ln){
       
   316 	
       
   317 #ifdef _LOW_ACCURACY_
       
   318 	nextbark=((tBnyq1<<11)/ln*(map+1))>>12;
       
   319 #else
       
   320 	nextbark=MULT31((map+1)*(imap>>1),tBnyq1);
       
   321 #endif
       
   322 	nextf=barklook[nextbark>>14]+
       
   323 	  (((nextbark&0x3fff)*
       
   324 	    (barklook[(nextbark>>14)+1]-barklook[nextbark>>14]))>>14);
       
   325 	if(f<=nextf)break;
       
   326 	
       
   327       }else{
       
   328 	nextf=9999999;
       
   329 	break;
       
   330       }
       
   331     }
       
   332     if(map>=ln){
       
   333       map=ln-1; /* guard against the approximation */      
       
   334       nextf=9999999;
       
   335     }
   283   }
   336   }
   284 }
   337 }
   285 
   338 
   286 /*************** vorbis decode glue ************/
   339 /*************** vorbis decode glue ************/
   287 
   340 
   288 static void floor0_free_info(vorbis_info_floor *i){
   341 void floor0_free_info(vorbis_info_floor *i){
   289   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   342   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   290   if(info){
   343   if(info)_ogg_free(info);
   291     memset(info,0,sizeof(*info));
   344 }
   292     _ogg_free(info);
   345 
   293   }
   346 vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
   294 }
       
   295 
       
   296 static void floor0_free_look(vorbis_look_floor *i){
       
   297   vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
       
   298   if(look){
       
   299 
       
   300     if(look->linearmap)_ogg_free(look->linearmap);
       
   301     if(look->lsp_look)_ogg_free(look->lsp_look);
       
   302     memset(look,0,sizeof(*look));
       
   303     _ogg_free(look);
       
   304   }
       
   305 }
       
   306 
       
   307 static vorbis_info_floor *floor0_unpack (vorbis_info *vi,oggpack_buffer *opb){
       
   308   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
   347   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
   309   int j;
   348   int j;
   310 
   349 
   311   vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
   350   vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
   312   info->order=oggpack_read(opb,8);
   351   info->order=oggpack_read(opb,8);
   317   info->numbooks=oggpack_read(opb,4)+1;
   356   info->numbooks=oggpack_read(opb,4)+1;
   318   
   357   
   319   if(info->order<1)goto err_out;
   358   if(info->order<1)goto err_out;
   320   if(info->rate<1)goto err_out;
   359   if(info->rate<1)goto err_out;
   321   if(info->barkmap<1)goto err_out;
   360   if(info->barkmap<1)goto err_out;
   322   if(info->numbooks<1)goto err_out;
       
   323     
   361     
   324   for(j=0;j<info->numbooks;j++){
   362   for(j=0;j<info->numbooks;j++){
   325     info->books[j]=oggpack_read(opb,8);
   363     info->books[j]=oggpack_read(opb,8);
   326     if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
   364     if(info->books[j]>=ci->books)goto err_out;
   327   }
   365   }
       
   366 
       
   367   if(oggpack_eop(opb))goto err_out;
   328   return(info);
   368   return(info);
   329 
   369 
   330  err_out:
   370  err_out:
   331   floor0_free_info(info);
   371   floor0_free_info(info);
   332   return(NULL);
   372   return(NULL);
   333 }
   373 }
   334 
   374 
   335 /* initialize Bark scale and normalization lookups.  We could do this
   375 int floor0_memosize(vorbis_info_floor *i){
   336    with static tables, but Vorbis allows a number of possible
       
   337    combinations, so it's best to do it computationally.
       
   338 
       
   339    The below is authoritative in terms of defining scale mapping.
       
   340    Note that the scale depends on the sampling rate as well as the
       
   341    linear block and mapping sizes */
       
   342 
       
   343 static vorbis_look_floor *floor0_look (vorbis_dsp_state *vd,vorbis_info_mode *mi,
       
   344                               vorbis_info_floor *i){
       
   345   int j;
       
   346   vorbis_info        *vi=vd->vi;
       
   347   codec_setup_info   *ci=(codec_setup_info *)vi->codec_setup;
       
   348   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   376   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   349   vorbis_look_floor0 *look=(vorbis_look_floor0 *)_ogg_calloc(1,sizeof(*look));
   377   return info->order+1;
   350   look->m=info->order;
   378 }
   351   look->n=ci->blocksizes[mi->blockflag]/2;
   379 
   352   look->ln=info->barkmap;
   380 ogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i,
   353   look->vi=info;
   381 			     ogg_int32_t *lsp){
   354 
   382   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   355   /* the mapping from a linear scale to a smaller bark scale is
       
   356      straightforward.  We do *not* make sure that the linear mapping
       
   357      does not skip bark-scale bins; the decoder simply skips them and
       
   358      the encoder may do what it wishes in filling them.  They're
       
   359      necessary in some mapping combinations to keep the scale spacing
       
   360      accurate */
       
   361   look->linearmap=(int *)_ogg_malloc((look->n+1)*sizeof(*look->linearmap));
       
   362   for(j=0;j<look->n;j++){
       
   363 
       
   364     int val=(look->ln*
       
   365 	     ((toBARK(info->rate/2*j/look->n)<<11)/toBARK(info->rate/2)))>>11;
       
   366 
       
   367     if(val>=look->ln)val=look->ln-1; /* guard against the approximation */
       
   368     look->linearmap[j]=val;
       
   369   }
       
   370   look->linearmap[j]=-1;
       
   371 
       
   372   look->lsp_look=(ogg_int32_t *)_ogg_malloc(look->ln*sizeof(*look->lsp_look));
       
   373   for(j=0;j<look->ln;j++)
       
   374     look->lsp_look[j]=vorbis_coslook2_i(0x10000*j/look->ln);
       
   375 
       
   376   return look;
       
   377 }
       
   378 
       
   379 static void *floor0_inverse1(vorbis_block *vb,vorbis_look_floor *i){
       
   380   vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
       
   381   vorbis_info_floor0 *info=look->vi;
       
   382   int j,k;
   383   int j,k;
   383   
   384   
   384   int ampraw=oggpack_read(&vb->opb,info->ampbits);
   385   int ampraw=oggpack_read(&vd->opb,info->ampbits);
   385   if(ampraw>0){ /* also handles the -1 out of data case */
   386   if(ampraw>0){ /* also handles the -1 out of data case */
   386     long maxval=(1<<info->ampbits)-1;
   387     long maxval=(1<<info->ampbits)-1;
   387     int amp=((ampraw*info->ampdB)<<4)/maxval;
   388     int amp=((ampraw*info->ampdB)<<4)/maxval;
   388     int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
   389     int booknum=oggpack_read(&vd->opb,_ilog(info->numbooks));
   389     
   390     
   390     if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
   391     if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
   391       codec_setup_info  *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
   392       codec_setup_info  *ci=(codec_setup_info *)vd->vi->codec_setup;
   392       codebook *b=ci->fullbooks+info->books[booknum];
   393       codebook *b=ci->book_param+info->books[booknum];
   393       ogg_int32_t last=0;
   394       ogg_int32_t last=0;
   394       ogg_int32_t *lsp=(ogg_int32_t *)_vorbis_block_alloc(vb,sizeof(*lsp)*(look->m+1));
       
   395             
   395             
   396       for(j=0;j<look->m;j+=b->dim)
   396       for(j=0;j<info->order;j+=b->dim)
   397 	if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim,-24)==-1)goto eop;
   397 	if(vorbis_book_decodev_set(b,lsp+j,&vd->opb,b->dim,-24)==-1)goto eop;
   398       for(j=0;j<look->m;){
   398       for(j=0;j<info->order;){
   399 	for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
   399 	for(k=0;k<b->dim;k++,j++)lsp[j]+=last;
   400 	last=lsp[j-1];
   400 	last=lsp[j-1];
   401       }
   401       }
   402       
   402       
   403       lsp[look->m]=amp;
   403       lsp[info->order]=amp;
   404       return(lsp);
   404       return(lsp);
   405     }
   405     }
   406   }
   406   }
   407  eop:
   407  eop:
   408   return(NULL);
   408   return(NULL);
   409 }
   409 }
   410 
   410 
   411 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
   411 int floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i,
   412 			   void *memo,ogg_int32_t *out){
   412 			   ogg_int32_t *lsp,ogg_int32_t *out){
   413   vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
   413   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   414   vorbis_info_floor0 *info=look->vi;
   414   codec_setup_info  *ci=(codec_setup_info *)vd->vi->codec_setup;
   415   
   415   
   416   if(memo){
   416   if(lsp){
   417     ogg_int32_t *lsp=(ogg_int32_t *)memo;
   417     ogg_int32_t amp=lsp[info->order];
   418     ogg_int32_t amp=lsp[look->m];
       
   419 
   418 
   420     /* take the coefficients back to a spectral envelope curve */
   419     /* take the coefficients back to a spectral envelope curve */
   421     vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
   420     vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap,
   422 			lsp,look->m,amp,info->ampdB,look->lsp_look);
   421 			lsp,info->order,amp,info->ampdB,
       
   422 			info->rate>>1);
   423     return(1);
   423     return(1);
   424   }
   424   }
   425   memset(out,0,sizeof(*out)*look->n);
   425   memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2);
   426   return(0);
   426   return(0);
   427 }
   427 }
   428 
   428 
   429 /* export hooks */
       
   430 vorbis_func_floor floor0_exportbundle={
       
   431   &floor0_unpack,&floor0_look,&floor0_free_info,
       
   432   &floor0_free_look,&floor0_inverse1,&floor0_inverse2
       
   433 };
       
   434 
       
   435