misc/libtremor/tremor/floor0.c
changeset 7849 a12155461b34
parent 7697 767d3c4153a1
equal deleted inserted replaced
7848:775a72905708 7849:a12155461b34
     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-2003    *
     9  * THE OggVorbis 'TREMOR' SOURCE CODE IS (C) COPYRIGHT 1994-2002    *
    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"
    24 #include "codebook.h"
    25 #include "codebook.h"
    25 #include "misc.h"
    26 #include "misc.h"
    26 #include "os.h"
    27 #include "block.h"
    27 
    28 
    28 #define LSP_FRACBITS 14
    29 #define LSP_FRACBITS 14
    29 extern const ogg_int32_t FLOOR_fromdB_LOOKUP[];
    30 
       
    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;
    30 
    41 
    31 /*************** LSP decode ********************/
    42 /*************** LSP decode ********************/
    32 
    43 
    33 #include "lsp_lookup.h"
    44 #include "lsp_lookup.h"
    34 
    45 
    35 /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
    46 /* interpolated 1./sqrt(p) where .5 <= a < 1. (.100000... to .111111...) in
    36    16.16 format 
    47    16.16 format 
    37    returns in m.8 format */
    48    returns in m.8 format */
    38 
    49 
    39 static long ADJUST_SQRT2[2]={8192,5792};
    50 static long ADJUST_SQRT2[2]={8192,5792};
    40 static inline ogg_int32_t vorbis_invsqlook_i(long a,long e){
    51 STIN ogg_int32_t vorbis_invsqlook_i(long a,long e){
    41   long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); 
    52   long i=(a&0x7fff)>>(INVSQ_LOOKUP_I_SHIFT-1); 
    42   long d=a&INVSQ_LOOKUP_I_MASK;                              /*  0.10 */
    53   long d=a&INVSQ_LOOKUP_I_MASK;                              /*  0.10 */
    43   long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
    54   long val=INVSQ_LOOKUP_I[i]-                                /*  1.16 */
    44     ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT);        /* result 1.16 */
    55     ((INVSQ_LOOKUP_IDel[i]*d)>>INVSQ_LOOKUP_I_SHIFT);        /* result 1.16 */
    45   val*=ADJUST_SQRT2[e&1];
    56   val*=ADJUST_SQRT2[e&1];
    47   return(val>>e);
    58   return(val>>e);
    48 }
    59 }
    49 
    60 
    50 /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
    61 /* interpolated lookup based fromdB function, domain -140dB to 0dB only */
    51 /* a is in n.12 format */
    62 /* a is in n.12 format */
    52 #ifdef _LOW_ACCURACY_
    63 STIN ogg_int32_t vorbis_fromdBlook_i(long a){
    53 static inline ogg_int32_t vorbis_fromdBlook_i(long a){
    64   int i=(-a)>>(12-FROMdB2_SHIFT);
    54   if(a>0) return 0x7fffffff;
    65   if(i<0) return 0x7fffffff;
    55   if(a<(-140<<12)) return 0;
    66   if(i>=(FROMdB_LOOKUP_SZ<<FROMdB_SHIFT))return 0;
    56   return FLOOR_fromdB_LOOKUP[((a+140)*467)>>20]<<9;
    67   
    57 }
    68   return FROMdB_LOOKUP[i>>FROMdB_SHIFT] * FROMdB2_LOOKUP[i&FROMdB2_MASK];
    58 #else
    69 }
    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
       
    65 
    70 
    66 /* interpolated lookup based cos function, domain 0 to PI only */
    71 /* interpolated lookup based cos function, domain 0 to PI only */
    67 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
    72 /* a is in 0.16 format, where 0==0, 2^^16-1==PI, return 0.14 */
    68 static inline ogg_int32_t vorbis_coslook_i(long a){
    73 STIN ogg_int32_t vorbis_coslook_i(long a){
    69   int i=a>>COS_LOOKUP_I_SHIFT;
    74   int i=a>>COS_LOOKUP_I_SHIFT;
    70   int d=a&COS_LOOKUP_I_MASK;
    75   int d=a&COS_LOOKUP_I_MASK;
    71   return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    76   return COS_LOOKUP_I[i]- ((d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    72 			   COS_LOOKUP_I_SHIFT);
    77 			   COS_LOOKUP_I_SHIFT);
    73 }
    78 }
    74 
    79 
    75 /* interpolated half-wave lookup based cos function */
    80 /* interpolated lookup based cos function */
    76 /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
    81 /* a is in 0.16 format, where 0==0, 2^^16==PI, return .LSP_FRACBITS */
    77 static inline ogg_int32_t vorbis_coslook2_i(long a){
    82 STIN ogg_int32_t vorbis_coslook2_i(long a){
    78   int i=a>>COS_LOOKUP_I_SHIFT;
    83   a=a&0x1ffff;
    79   int d=a&COS_LOOKUP_I_MASK;
    84 
    80   return ((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
    85   if(a>0x10000)a=0x20000-a;
    81 	  d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    86   {               
    82     (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
    87     int i=a>>COS_LOOKUP_I_SHIFT;
    83 }
    88     int d=a&COS_LOOKUP_I_MASK;
    84 
    89     a=((COS_LOOKUP_I[i]<<COS_LOOKUP_I_SHIFT)-
    85 static const ogg_uint16_t barklook[54]={
    90        d*(COS_LOOKUP_I[i]-COS_LOOKUP_I[i+1]))>>
    86   0,51,102,154,            206,258,311,365,
    91       (COS_LOOKUP_I_SHIFT-LSP_FRACBITS+14);
    87   420,477,535,594,         656,719,785,854,
    92   }
    88   926,1002,1082,1166,      1256,1352,1454,1564,
    93   
    89   1683,1812,1953,2107,     2276,2463,2670,2900,
    94   return(a);
    90   3155,3440,3756,4106,     4493,4919,5387,5901,
    95 }
    91   6466,7094,7798,8599,     9528,10623,11935,13524,
    96 
    92   15453,17775,20517,23667, 27183,31004
    97 static const int barklook[28]={
       
    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
    93 };
   102 };
    94 
   103 
    95 /* used in init only; interpolate the long way */
   104 /* used in init only; interpolate the long way */
    96 static inline ogg_int32_t toBARK(int n){
   105 STIN ogg_int32_t toBARK(int n){
    97   int i;
   106   int i;
    98   for(i=0;i<54;i++) 
   107   for(i=0;i<27;i++) 
    99     if(n>=barklook[i] && n<barklook[i+1])break;
   108     if(n>=barklook[i] && n<barklook[i+1])break;
   100   
   109   
   101   if(i==54){
   110   if(i==27){
   102     return 54<<14;
   111     return 27<<15;
   103   }else{
   112   }else{
   104     return (i<<14)+(((n-barklook[i])*  
   113     int gap=barklook[i+1]-barklook[i];
   105 		     ((1UL<<31)/(barklook[i+1]-barklook[i])))>>17);
   114     int del=n-barklook[i];
       
   115 
       
   116     return((i<<15)+((del<<15)/gap));
   106   }
   117   }
   107 }
   118 }
   108 
   119 
   109 static const unsigned char MLOOP_1[64]={
   120 static const unsigned char MLOOP_1[64]={
   110    0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
   121    0,10,11,11, 12,12,12,12, 13,13,13,13, 13,13,13,13,
   120   9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
   131   9,9,9,9, 9,9,9,9, 9,9,9,9, 9,9,9,9,
   121 };
   132 };
   122 
   133 
   123 static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
   134 static const unsigned char MLOOP_3[8]={0,1,2,2,3,3,3,3};
   124 
   135 
   125 void vorbis_lsp_to_curve(ogg_int32_t *curve,int n,int ln,
   136 void vorbis_lsp_to_curve(ogg_int32_t *curve,int *map,int n,int ln,
   126 			 ogg_int32_t *lsp,int m,
   137 			 ogg_int32_t *lsp,int m,
   127 			 ogg_int32_t amp,
   138 			 ogg_int32_t amp,
   128 			 ogg_int32_t ampoffset,
   139 			 ogg_int32_t ampoffset,
   129 			 ogg_int32_t nyq){
   140 			 ogg_int32_t *icos){
   130 
   141 
   131   /* 0 <= m < 256 */
   142   /* 0 <= m < 256 */
   132 
   143 
   133   /* set up for using all int later */
   144   /* set up for using all int later */
   134   int i;
   145   int i;
   135   int ampoffseti=ampoffset*4096;
   146   int ampoffseti=ampoffset*4096;
   136   int ampi=amp;
   147   int ampi=amp;
   137   ogg_int32_t *ilsp=(ogg_int32_t *)alloca(m*sizeof(*ilsp));
   148   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 
       
   159   /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
   149   /* lsp is in 8.24, range 0 to PI; coslook wants it in .16 0 to 1*/
   160   for(i=0;i<m;i++){
   150   for(i=0;i<m;i++){
   161 #ifndef _LOW_ACCURACY_
   151 #ifndef _LOW_ACCURACY_
   162     ogg_int32_t val=MULT32(lsp[i],0x517cc2);
   152     ogg_int32_t val=MULT32(lsp[i],0x517cc2);
   163 #else
   153 #else
   173     ilsp[i]=vorbis_coslook_i(val);
   163     ilsp[i]=vorbis_coslook_i(val);
   174   }
   164   }
   175 
   165 
   176   i=0;
   166   i=0;
   177   while(i<n){
   167   while(i<n){
   178     int j;
   168     int j,k=map[i];
   179     ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
   169     ogg_uint32_t pi=46341; /* 2**-.5 in 0.16 */
   180     ogg_uint32_t qi=46341;
   170     ogg_uint32_t qi=46341;
   181     ogg_int32_t qexp=0,shift;
   171     ogg_int32_t qexp=0,shift;
   182     ogg_int32_t wi;
   172     ogg_int32_t wi=icos[k];
   183 
       
   184     wi=vorbis_coslook2_i((map*imap)>>15);
       
   185 
       
   186 
   173 
   187 #ifdef _V_LSP_MATH_ASM
   174 #ifdef _V_LSP_MATH_ASM
   188     lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
   175     lsp_loop_asm(&qi,&pi,&qexp,ilsp,wi,m);
   189 
   176 
   190     pi=((pi*pi)>>16);
   177     pi=((pi*pi)>>16);
   213     qi*=labs(ilsp[0]-wi);
   200     qi*=labs(ilsp[0]-wi);
   214     pi*=labs(ilsp[1]-wi);
   201     pi*=labs(ilsp[1]-wi);
   215 
   202 
   216     for(j=3;j<m;j+=2){
   203     for(j=3;j<m;j+=2){
   217       if(!(shift=MLOOP_1[(pi|qi)>>25]))
   204       if(!(shift=MLOOP_1[(pi|qi)>>25]))
   218       	if(!(shift=MLOOP_2[(pi|qi)>>19]))
   205 	if(!(shift=MLOOP_2[(pi|qi)>>19]))
   219       	  shift=MLOOP_3[(pi|qi)>>16];
   206 	  shift=MLOOP_3[(pi|qi)>>16];
   220       
       
   221       qi=(qi>>shift)*labs(ilsp[j-1]-wi);
   207       qi=(qi>>shift)*labs(ilsp[j-1]-wi);
   222       pi=(pi>>shift)*labs(ilsp[j]-wi);
   208       pi=(pi>>shift)*labs(ilsp[j]-wi);
   223       qexp+=shift;
   209       qexp+=shift;
   224     }
   210     }
   225     if(!(shift=MLOOP_1[(pi|qi)>>25]))
   211     if(!(shift=MLOOP_1[(pi|qi)>>25]))
   226       if(!(shift=MLOOP_2[(pi|qi)>>19]))
   212       if(!(shift=MLOOP_2[(pi|qi)>>19]))
   227 	shift=MLOOP_3[(pi|qi)>>16];
   213 	shift=MLOOP_3[(pi|qi)>>16];
   228     
   214 
   229     /* pi,qi normalized collectively, both tracked using qexp */
   215     /* pi,qi normalized collectively, both tracked using qexp */
   230 
   216 
   231     if(m&1){
   217     if(m&1){
   232       /* odd order filter; slightly assymetric */
   218       /* odd order filter; slightly assymetric */
   233       /* the last coefficient */
   219       /* the last coefficient */
   291     
   277     
   292 #ifdef _LOW_ACCURACY_
   278 #ifdef _LOW_ACCURACY_
   293     amp>>=9;
   279     amp>>=9;
   294 #endif
   280 #endif
   295     curve[i]= MULT31_SHIFT15(curve[i],amp);
   281     curve[i]= MULT31_SHIFT15(curve[i],amp);
   296 
   282     while(map[++i]==k) curve[i]= MULT31_SHIFT15(curve[i],amp);
   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     }
       
   336   }
   283   }
   337 }
   284 }
   338 
   285 
   339 /*************** vorbis decode glue ************/
   286 /*************** vorbis decode glue ************/
   340 
   287 
   341 void floor0_free_info(vorbis_info_floor *i){
   288 static void floor0_free_info(vorbis_info_floor *i){
   342   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   289   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   343   if(info)_ogg_free(info);
   290   if(info){
   344 }
   291     memset(info,0,sizeof(*info));
   345 
   292     _ogg_free(info);
   346 vorbis_info_floor *floor0_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
   293   }
       
   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){
   347   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
   308   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
   348   int j;
   309   int j;
   349 
   310 
   350   vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
   311   vorbis_info_floor0 *info=(vorbis_info_floor0 *)_ogg_malloc(sizeof(*info));
   351   info->order=oggpack_read(opb,8);
   312   info->order=oggpack_read(opb,8);
   356   info->numbooks=oggpack_read(opb,4)+1;
   317   info->numbooks=oggpack_read(opb,4)+1;
   357   
   318   
   358   if(info->order<1)goto err_out;
   319   if(info->order<1)goto err_out;
   359   if(info->rate<1)goto err_out;
   320   if(info->rate<1)goto err_out;
   360   if(info->barkmap<1)goto err_out;
   321   if(info->barkmap<1)goto err_out;
       
   322   if(info->numbooks<1)goto err_out;
   361     
   323     
   362   for(j=0;j<info->numbooks;j++){
   324   for(j=0;j<info->numbooks;j++){
   363     info->books[j]=oggpack_read(opb,8);
   325     info->books[j]=oggpack_read(opb,8);
   364     if(info->books[j]>=ci->books)goto err_out;
   326     if(info->books[j]<0 || info->books[j]>=ci->books)goto err_out;
   365   }
   327   }
   366 
       
   367   if(oggpack_eop(opb))goto err_out;
       
   368   return(info);
   328   return(info);
   369 
   329 
   370  err_out:
   330  err_out:
   371   floor0_free_info(info);
   331   floor0_free_info(info);
   372   return(NULL);
   332   return(NULL);
   373 }
   333 }
   374 
   334 
   375 int floor0_memosize(vorbis_info_floor *i){
   335 /* initialize Bark scale and normalization lookups.  We could do this
       
   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;
   376   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   348   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   377   return info->order+1;
   349   vorbis_look_floor0 *look=(vorbis_look_floor0 *)_ogg_calloc(1,sizeof(*look));
   378 }
   350   look->m=info->order;
   379 
   351   look->n=ci->blocksizes[mi->blockflag]/2;
   380 ogg_int32_t *floor0_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *i,
   352   look->ln=info->barkmap;
   381 			     ogg_int32_t *lsp){
   353   look->vi=info;
   382   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   354 
       
   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;
   383   int j,k;
   382   int j,k;
   384   
   383   
   385   int ampraw=oggpack_read(&vd->opb,info->ampbits);
   384   int ampraw=oggpack_read(&vb->opb,info->ampbits);
   386   if(ampraw>0){ /* also handles the -1 out of data case */
   385   if(ampraw>0){ /* also handles the -1 out of data case */
   387     long maxval=(1<<info->ampbits)-1;
   386     long maxval=(1<<info->ampbits)-1;
   388     int amp=((ampraw*info->ampdB)<<4)/maxval;
   387     int amp=((ampraw*info->ampdB)<<4)/maxval;
   389     int booknum=oggpack_read(&vd->opb,_ilog(info->numbooks));
   388     int booknum=oggpack_read(&vb->opb,_ilog(info->numbooks));
   390     
   389     
   391     if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
   390     if(booknum!=-1 && booknum<info->numbooks){ /* be paranoid */
   392       codec_setup_info  *ci=(codec_setup_info *)vd->vi->codec_setup;
   391       codec_setup_info  *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
   393       codebook *b=ci->book_param+info->books[booknum];
   392       codebook *b=ci->fullbooks+info->books[booknum];
   394       ogg_int32_t last=0;
   393       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<info->order;j+=b->dim)
   396       for(j=0;j<look->m;j+=b->dim)
   397 	if(vorbis_book_decodev_set(b,lsp+j,&vd->opb,b->dim,-24)==-1)goto eop;
   397 	if(vorbis_book_decodev_set(b,lsp+j,&vb->opb,b->dim,-24)==-1)goto eop;
   398       for(j=0;j<info->order;){
   398       for(j=0;j<look->m;){
   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[info->order]=amp;
   403       lsp[look->m]=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 int floor0_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *i,
   411 static int floor0_inverse2(vorbis_block *vb,vorbis_look_floor *i,
   412 			   ogg_int32_t *lsp,ogg_int32_t *out){
   412 			   void *memo,ogg_int32_t *out){
   413   vorbis_info_floor0 *info=(vorbis_info_floor0 *)i;
   413   vorbis_look_floor0 *look=(vorbis_look_floor0 *)i;
   414   codec_setup_info  *ci=(codec_setup_info *)vd->vi->codec_setup;
   414   vorbis_info_floor0 *info=look->vi;
   415   
   415   
   416   if(lsp){
   416   if(memo){
   417     ogg_int32_t amp=lsp[info->order];
   417     ogg_int32_t *lsp=(ogg_int32_t *)memo;
       
   418     ogg_int32_t amp=lsp[look->m];
   418 
   419 
   419     /* take the coefficients back to a spectral envelope curve */
   420     /* take the coefficients back to a spectral envelope curve */
   420     vorbis_lsp_to_curve(out,ci->blocksizes[vd->W]/2,info->barkmap,
   421     vorbis_lsp_to_curve(out,look->linearmap,look->n,look->ln,
   421 			lsp,info->order,amp,info->ampdB,
   422 			lsp,look->m,amp,info->ampdB,look->lsp_look);
   422 			info->rate>>1);
       
   423     return(1);
   423     return(1);
   424   }
   424   }
   425   memset(out,0,sizeof(*out)*ci->blocksizes[vd->W]/2);
   425   memset(out,0,sizeof(*out)*look->n);
   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