misc/libtremor/tremor/floor1.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 1 implementation
    14  function: floor backend 1 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 
    27 #include "block.h"
    27 extern const ogg_int32_t FLOOR_fromdB_LOOKUP[];
    28 
    28 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
    29 #define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
    29 #define VIF_POSIT 63
    30 
       
    31 typedef struct {
       
    32   int forward_index[VIF_POSIT+2];
       
    33   
       
    34   int hineighbor[VIF_POSIT];
       
    35   int loneighbor[VIF_POSIT];
       
    36   int posts;
       
    37 
       
    38   int n;
       
    39   int quant_q;
       
    40   vorbis_info_floor1 *vi;
       
    41 
       
    42 } vorbis_look_floor1;
    30 
    43 
    31 /***********************************************/
    44 /***********************************************/
    32  
    45  
    33 void floor1_free_info(vorbis_info_floor *i){
    46 static void floor1_free_info(vorbis_info_floor *i){
    34   vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
    47   vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
    35   if(info){
    48   if(info){
    36     if(info->class)_ogg_free(info->class);
       
    37     if(info->partitionclass)_ogg_free(info->partitionclass);
       
    38     if(info->postlist)_ogg_free(info->postlist);
       
    39     if(info->forward_index)_ogg_free(info->forward_index);
       
    40     if(info->hineighbor)_ogg_free(info->hineighbor);
       
    41     if(info->loneighbor)_ogg_free(info->loneighbor);
       
    42     memset(info,0,sizeof(*info));
    49     memset(info,0,sizeof(*info));
    43     _ogg_free(info);
    50     _ogg_free(info);
       
    51   }
       
    52 }
       
    53 
       
    54 static void floor1_free_look(vorbis_look_floor *i){
       
    55   vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
       
    56   if(look){
       
    57     memset(look,0,sizeof(*look));
       
    58     _ogg_free(look);
    44   }
    59   }
    45 }
    60 }
    46 
    61 
    47 static int ilog(unsigned int v){
    62 static int ilog(unsigned int v){
    48   int ret=0;
    63   int ret=0;
    51     v>>=1;
    66     v>>=1;
    52   }
    67   }
    53   return(ret);
    68   return(ret);
    54 }
    69 }
    55 
    70 
    56 static int icomp(const void *a,const void *b){
    71 static vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
    57   return(**(ogg_uint16_t **)a-**(ogg_uint16_t **)b);
       
    58 }
       
    59 
       
    60 vorbis_info_floor *floor1_info_unpack (vorbis_info *vi,oggpack_buffer *opb){
       
    61   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
    72   codec_setup_info     *ci=(codec_setup_info *)vi->codec_setup;
    62   int j,k,count=0,maxclass=-1,rangebits;
    73   int j,k,count=0,maxclass=-1,rangebits;
    63   ogg_uint16_t *sortpointer[VIF_POSIT+2];
    74 
    64   
       
    65   vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
    75   vorbis_info_floor1 *info=(vorbis_info_floor1 *)_ogg_calloc(1,sizeof(*info));
    66   /* read partitions */
    76   /* read partitions */
    67   info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
    77   info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
    68   info->partitionclass=
       
    69     (char *)_ogg_malloc(info->partitions*sizeof(*info->partitionclass));
       
    70   for(j=0;j<info->partitions;j++){
    78   for(j=0;j<info->partitions;j++){
    71     info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
    79     info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
    72     if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
    80     if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
    73   }
    81   }
    74 
    82 
    75   /* read partition classes */
    83   /* read partition classes */
    76   info->class=
       
    77     (floor1class *)_ogg_malloc((maxclass+1)*sizeof(*info->class));
       
    78   for(j=0;j<maxclass+1;j++){
    84   for(j=0;j<maxclass+1;j++){
    79     info->class[j].class_dim=oggpack_read(opb,3)+1; /* 1 to 8 */
    85     info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
    80     info->class[j].class_subs=oggpack_read(opb,2); /* 0,1,2,3 bits */
    86     info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
    81     if(oggpack_eop(opb)<0) goto err_out;
    87     if(info->class_subs[j]<0)
    82     if(info->class[j].class_subs)
    88       goto err_out;
    83       info->class[j].class_book=oggpack_read(opb,8);
    89     if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
    84     else
    90     if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
    85       info->class[j].class_book=0;
    91       goto err_out;
    86     if(info->class[j].class_book>=ci->books)goto err_out;
    92     for(k=0;k<(1<<info->class_subs[j]);k++){
    87     for(k=0;k<(1<<info->class[j].class_subs);k++){
    93       info->class_subbook[j][k]=oggpack_read(opb,8)-1;
    88       info->class[j].class_subbook[k]=oggpack_read(opb,8)-1;
    94       if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
    89       if(info->class[j].class_subbook[k]>=ci->books &&
    95 	goto err_out;
    90 	 info->class[j].class_subbook[k]!=0xff)goto err_out;
       
    91     }
    96     }
    92   }
    97   }
    93 
    98 
    94   /* read the post list */
    99   /* read the post list */
    95   info->mult=oggpack_read(opb,2)+1;     /* only 1,2,3,4 legal now */ 
   100   info->mult=oggpack_read(opb,2)+1;     /* only 1,2,3,4 legal now */ 
    96   rangebits=oggpack_read(opb,4);
   101   rangebits=oggpack_read(opb,4);
    97 
   102 
    98   for(j=0,k=0;j<info->partitions;j++)
       
    99     count+=info->class[info->partitionclass[j]].class_dim; 
       
   100   info->postlist=
       
   101     (ogg_uint16_t *)_ogg_malloc((count+2)*sizeof(*info->postlist));
       
   102   info->forward_index=
       
   103     (char *)_ogg_malloc((count+2)*sizeof(*info->forward_index));
       
   104   info->loneighbor=
       
   105     (char *)_ogg_malloc(count*sizeof(*info->loneighbor));
       
   106   info->hineighbor=
       
   107     (char *)_ogg_malloc(count*sizeof(*info->hineighbor));
       
   108 
       
   109   count=0;
       
   110   for(j=0,k=0;j<info->partitions;j++){
   103   for(j=0,k=0;j<info->partitions;j++){
   111     count+=info->class[info->partitionclass[j]].class_dim; 
   104     count+=info->class_dim[info->partitionclass[j]]; 
   112     if(count>VIF_POSIT)goto err_out;
       
   113     for(;k<count;k++){
   105     for(;k<count;k++){
   114       int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
   106       int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
   115       if(t>=(1<<rangebits))goto err_out;
   107       if(t<0 || t>=(1<<rangebits))
   116     }
   108 	goto err_out;
   117   }
   109     }
   118   if(oggpack_eop(opb))goto err_out;
   110   }
   119   info->postlist[0]=0;
   111   info->postlist[0]=0;
   120   info->postlist[1]=1<<rangebits;
   112   info->postlist[1]=1<<rangebits;
   121   info->posts=count+2;
   113 
       
   114   return(info);
       
   115   
       
   116  err_out:
       
   117   floor1_free_info(info);
       
   118   return(NULL);
       
   119 }
       
   120 
       
   121 static int icomp(const void *a,const void *b){
       
   122   return(**(int **)a-**(int **)b);
       
   123 }
       
   124 
       
   125 static vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,vorbis_info_mode *mi,
       
   126                               vorbis_info_floor *in){
       
   127 
       
   128   int *sortpointer[VIF_POSIT+2];
       
   129   vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
       
   130   vorbis_look_floor1 *look=(vorbis_look_floor1 *)_ogg_calloc(1,sizeof(*look));
       
   131   int i,j,n=0;
       
   132 
       
   133   look->vi=info;
       
   134   look->n=info->postlist[1];
       
   135  
       
   136   /* we drop each position value in-between already decoded values,
       
   137      and use linear interpolation to predict each new value past the
       
   138      edges.  The positions are read in the order of the position
       
   139      list... we precompute the bounding positions in the lookup.  Of
       
   140      course, the neighbors can change (if a position is declined), but
       
   141      this is an initial mapping */
       
   142 
       
   143   for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
       
   144   n+=2;
       
   145   look->posts=n;
   122 
   146 
   123   /* also store a sorted position index */
   147   /* also store a sorted position index */
   124   for(j=0;j<info->posts;j++)sortpointer[j]=info->postlist+j;
   148   for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
   125   qsort(sortpointer,info->posts,sizeof(*sortpointer),icomp);
   149   qsort(sortpointer,n,sizeof(*sortpointer),icomp);
   126 
   150 
   127   /* points from sort order back to range number */
   151   /* points from sort order back to range number */
   128   for(j=0;j<info->posts;j++)
   152   for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
   129     info->forward_index[j]=sortpointer[j]-info->postlist;
   153   
   130   
   154   /* quantize values to multiplier spec */
       
   155   switch(info->mult){
       
   156   case 1: /* 1024 -> 256 */
       
   157     look->quant_q=256;
       
   158     break;
       
   159   case 2: /* 1024 -> 128 */
       
   160     look->quant_q=128;
       
   161     break;
       
   162   case 3: /* 1024 -> 86 */
       
   163     look->quant_q=86;
       
   164     break;
       
   165   case 4: /* 1024 -> 64 */
       
   166     look->quant_q=64;
       
   167     break;
       
   168   }
       
   169 
   131   /* discover our neighbors for decode where we don't use fit flags
   170   /* discover our neighbors for decode where we don't use fit flags
   132      (that would push the neighbors outward) */
   171      (that would push the neighbors outward) */
   133   for(j=0;j<info->posts-2;j++){
   172   for(i=0;i<n-2;i++){
   134     int lo=0;
   173     int lo=0;
   135     int hi=1;
   174     int hi=1;
   136     int lx=0;
   175     int lx=0;
   137     int hx=info->postlist[1];
   176     int hx=look->n;
   138     int currentx=info->postlist[j+2];
   177     int currentx=info->postlist[i+2];
   139     for(k=0;k<j+2;k++){
   178     for(j=0;j<i+2;j++){
   140       int x=info->postlist[k];
   179       int x=info->postlist[j];
   141       if(x>lx && x<currentx){
   180       if(x>lx && x<currentx){
   142 	lo=k;
   181 	lo=j;
   143 	lx=x;
   182 	lx=x;
   144       }
   183       }
   145       if(x<hx && x>currentx){
   184       if(x<hx && x>currentx){
   146 	hi=k;
   185 	hi=j;
   147 	hx=x;
   186 	hx=x;
   148       }
   187       }
   149     }
   188     }
   150     info->loneighbor[j]=lo;
   189     look->loneighbor[i]=lo;
   151     info->hineighbor[j]=hi;
   190     look->hineighbor[i]=hi;
   152   }
   191   }
   153 
   192 
   154   return(info);
   193   return(look);
   155   
       
   156  err_out:
       
   157   floor1_free_info(info);
       
   158   return(NULL);
       
   159 }
   194 }
   160 
   195 
   161 static int render_point(int x0,int x1,int y0,int y1,int x){
   196 static int render_point(int x0,int x1,int y0,int y1,int x){
   162   y0&=0x7fff; /* mask off flag */
   197   y0&=0x7fff; /* mask off flag */
   163   y1&=0x7fff;
   198   y1&=0x7fff;
   172     if(dy<0)return(y0-off);
   207     if(dy<0)return(y0-off);
   173     return(y0+off);
   208     return(y0+off);
   174   }
   209   }
   175 }
   210 }
   176 
   211 
       
   212 #ifdef _LOW_ACCURACY_
       
   213 #  define XdB(n) ((((n)>>8)+1)>>1)
       
   214 #else
       
   215 #  define XdB(n) (n)
       
   216 #endif
       
   217 
       
   218 static const ogg_int32_t FLOOR_fromdB_LOOKUP[256]={
       
   219   XdB(0x000000e5), XdB(0x000000f4), XdB(0x00000103), XdB(0x00000114),
       
   220   XdB(0x00000126), XdB(0x00000139), XdB(0x0000014e), XdB(0x00000163),
       
   221   XdB(0x0000017a), XdB(0x00000193), XdB(0x000001ad), XdB(0x000001c9),
       
   222   XdB(0x000001e7), XdB(0x00000206), XdB(0x00000228), XdB(0x0000024c),
       
   223   XdB(0x00000272), XdB(0x0000029b), XdB(0x000002c6), XdB(0x000002f4),
       
   224   XdB(0x00000326), XdB(0x0000035a), XdB(0x00000392), XdB(0x000003cd),
       
   225   XdB(0x0000040c), XdB(0x00000450), XdB(0x00000497), XdB(0x000004e4),
       
   226   XdB(0x00000535), XdB(0x0000058c), XdB(0x000005e8), XdB(0x0000064a),
       
   227   XdB(0x000006b3), XdB(0x00000722), XdB(0x00000799), XdB(0x00000818),
       
   228   XdB(0x0000089e), XdB(0x0000092e), XdB(0x000009c6), XdB(0x00000a69),
       
   229   XdB(0x00000b16), XdB(0x00000bcf), XdB(0x00000c93), XdB(0x00000d64),
       
   230   XdB(0x00000e43), XdB(0x00000f30), XdB(0x0000102d), XdB(0x0000113a),
       
   231   XdB(0x00001258), XdB(0x0000138a), XdB(0x000014cf), XdB(0x00001629),
       
   232   XdB(0x0000179a), XdB(0x00001922), XdB(0x00001ac4), XdB(0x00001c82),
       
   233   XdB(0x00001e5c), XdB(0x00002055), XdB(0x0000226f), XdB(0x000024ac),
       
   234   XdB(0x0000270e), XdB(0x00002997), XdB(0x00002c4b), XdB(0x00002f2c),
       
   235   XdB(0x0000323d), XdB(0x00003581), XdB(0x000038fb), XdB(0x00003caf),
       
   236   XdB(0x000040a0), XdB(0x000044d3), XdB(0x0000494c), XdB(0x00004e10),
       
   237   XdB(0x00005323), XdB(0x0000588a), XdB(0x00005e4b), XdB(0x0000646b),
       
   238   XdB(0x00006af2), XdB(0x000071e5), XdB(0x0000794c), XdB(0x0000812e),
       
   239   XdB(0x00008993), XdB(0x00009283), XdB(0x00009c09), XdB(0x0000a62d),
       
   240   XdB(0x0000b0f9), XdB(0x0000bc79), XdB(0x0000c8b9), XdB(0x0000d5c4),
       
   241   XdB(0x0000e3a9), XdB(0x0000f274), XdB(0x00010235), XdB(0x000112fd),
       
   242   XdB(0x000124dc), XdB(0x000137e4), XdB(0x00014c29), XdB(0x000161bf),
       
   243   XdB(0x000178bc), XdB(0x00019137), XdB(0x0001ab4a), XdB(0x0001c70e),
       
   244   XdB(0x0001e4a1), XdB(0x0002041f), XdB(0x000225aa), XdB(0x00024962),
       
   245   XdB(0x00026f6d), XdB(0x000297f0), XdB(0x0002c316), XdB(0x0002f109),
       
   246   XdB(0x000321f9), XdB(0x00035616), XdB(0x00038d97), XdB(0x0003c8b4),
       
   247   XdB(0x000407a7), XdB(0x00044ab2), XdB(0x00049218), XdB(0x0004de23),
       
   248   XdB(0x00052f1e), XdB(0x0005855c), XdB(0x0005e135), XdB(0x00064306),
       
   249   XdB(0x0006ab33), XdB(0x00071a24), XdB(0x0007904b), XdB(0x00080e20),
       
   250   XdB(0x00089422), XdB(0x000922da), XdB(0x0009bad8), XdB(0x000a5cb6),
       
   251   XdB(0x000b091a), XdB(0x000bc0b1), XdB(0x000c8436), XdB(0x000d5471),
       
   252   XdB(0x000e3233), XdB(0x000f1e5f), XdB(0x001019e4), XdB(0x001125c1),
       
   253   XdB(0x00124306), XdB(0x001372d5), XdB(0x0014b663), XdB(0x00160ef7),
       
   254   XdB(0x00177df0), XdB(0x001904c1), XdB(0x001aa4f9), XdB(0x001c603d),
       
   255   XdB(0x001e384f), XdB(0x00202f0f), XdB(0x0022467a), XdB(0x002480b1),
       
   256   XdB(0x0026dff7), XdB(0x002966b3), XdB(0x002c1776), XdB(0x002ef4fc),
       
   257   XdB(0x0032022d), XdB(0x00354222), XdB(0x0038b828), XdB(0x003c67c2),
       
   258   XdB(0x004054ae), XdB(0x004482e8), XdB(0x0048f6af), XdB(0x004db488),
       
   259   XdB(0x0052c142), XdB(0x005821ff), XdB(0x005ddc33), XdB(0x0063f5b0),
       
   260   XdB(0x006a74a7), XdB(0x00715faf), XdB(0x0078bdce), XdB(0x0080967f),
       
   261   XdB(0x0088f1ba), XdB(0x0091d7f9), XdB(0x009b5247), XdB(0x00a56a41),
       
   262   XdB(0x00b02a27), XdB(0x00bb9ce2), XdB(0x00c7ce12), XdB(0x00d4ca17),
       
   263   XdB(0x00e29e20), XdB(0x00f15835), XdB(0x0101074b), XdB(0x0111bb4e),
       
   264   XdB(0x01238531), XdB(0x01367704), XdB(0x014aa402), XdB(0x016020a7),
       
   265   XdB(0x017702c3), XdB(0x018f6190), XdB(0x01a955cb), XdB(0x01c4f9cf),
       
   266   XdB(0x01e269a8), XdB(0x0201c33b), XdB(0x0223265a), XdB(0x0246b4ea),
       
   267   XdB(0x026c9302), XdB(0x0294e716), XdB(0x02bfda13), XdB(0x02ed9793),
       
   268   XdB(0x031e4e09), XdB(0x03522ee4), XdB(0x03896ed0), XdB(0x03c445e2),
       
   269   XdB(0x0402efd6), XdB(0x0445ac4b), XdB(0x048cbefc), XdB(0x04d87013),
       
   270   XdB(0x05290c67), XdB(0x057ee5ca), XdB(0x05da5364), XdB(0x063bb204),
       
   271   XdB(0x06a36485), XdB(0x0711d42b), XdB(0x0787710e), XdB(0x0804b299),
       
   272   XdB(0x088a17ef), XdB(0x0918287e), XdB(0x09af747c), XdB(0x0a50957e),
       
   273   XdB(0x0afc2f19), XdB(0x0bb2ef7f), XdB(0x0c759034), XdB(0x0d44d6ca),
       
   274   XdB(0x0e2195bc), XdB(0x0f0cad0d), XdB(0x10070b62), XdB(0x1111aeea),
       
   275   XdB(0x122da66c), XdB(0x135c120f), XdB(0x149e24d9), XdB(0x15f525b1),
       
   276   XdB(0x176270e3), XdB(0x18e7794b), XdB(0x1a85c9ae), XdB(0x1c3f06d1),
       
   277   XdB(0x1e14f07d), XdB(0x200963d7), XdB(0x221e5ccd), XdB(0x2455f870),
       
   278   XdB(0x26b2770b), XdB(0x29363e2b), XdB(0x2be3db5c), XdB(0x2ebe06b6),
       
   279   XdB(0x31c7a55b), XdB(0x3503ccd4), XdB(0x3875c5aa), XdB(0x3c210f44),
       
   280   XdB(0x4009632b), XdB(0x4432b8cf), XdB(0x48a149bc), XdB(0x4d59959e),
       
   281   XdB(0x52606733), XdB(0x57bad899), XdB(0x5d6e593a), XdB(0x6380b298),
       
   282   XdB(0x69f80e9a), XdB(0x70dafda8), XdB(0x78307d76), XdB(0x7fffffff),
       
   283 };
       
   284   
   177 static void render_line(int n, int x0,int x1,int y0,int y1,ogg_int32_t *d){
   285 static void render_line(int n, int x0,int x1,int y0,int y1,ogg_int32_t *d){
   178   int dy=y1-y0;
   286   int dy=y1-y0;
   179   int adx=x1-x0;
   287   int adx=x1-x0;
   180   int ady=abs(dy);
   288   int ady=abs(dy);
   181   int base=dy/adx;
   289   int base=dy/adx;
   200     }
   308     }
   201     d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
   309     d[x]= MULT31_SHIFT15(d[x],FLOOR_fromdB_LOOKUP[y]);
   202   }
   310   }
   203 }
   311 }
   204 
   312 
   205 int floor1_memosize(vorbis_info_floor *i){
   313 static void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
   206   vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
   314   vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
   207   return info->posts;
   315   vorbis_info_floor1 *info=look->vi;
   208 }
   316   codec_setup_info   *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
   209 
       
   210 static int quant_look[4]={256,128,86,64};
       
   211 
       
   212 ogg_int32_t *floor1_inverse1(vorbis_dsp_state *vd,vorbis_info_floor *in,
       
   213 			     ogg_int32_t *fit_value){
       
   214   vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
       
   215   codec_setup_info   *ci=(codec_setup_info *)vd->vi->codec_setup;
       
   216   
   317   
   217   int i,j,k;
   318   int i,j,k;
   218   codebook *books=ci->book_param;   
   319   codebook *books=ci->fullbooks;   
   219   int quant_q=quant_look[info->mult-1];
   320   
   220 
       
   221   /* unpack wrapped/predicted values from stream */
   321   /* unpack wrapped/predicted values from stream */
   222   if(oggpack_read(&vd->opb,1)==1){
   322   if(oggpack_read(&vb->opb,1)==1){
   223     fit_value[0]=oggpack_read(&vd->opb,ilog(quant_q-1));
   323     int *fit_value=(int *)_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
   224     fit_value[1]=oggpack_read(&vd->opb,ilog(quant_q-1));
   324     
       
   325     fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
       
   326     fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
   225     
   327     
   226     /* partition by partition */
   328     /* partition by partition */
   227     /* partition by partition */
   329     /* partition by partition */
   228     for(i=0,j=2;i<info->partitions;i++){
   330     for(i=0,j=2;i<info->partitions;i++){
   229       int classv=info->partitionclass[i];
   331       int classv=info->partitionclass[i];
   230       int cdim=info->class[classv].class_dim;
   332       int cdim=info->class_dim[classv];
   231       int csubbits=info->class[classv].class_subs;
   333       int csubbits=info->class_subs[classv];
   232       int csub=1<<csubbits;
   334       int csub=1<<csubbits;
   233       int cval=0;
   335       int cval=0;
   234 
   336 
   235       /* decode the partition's first stage cascade value */
   337       /* decode the partition's first stage cascade value */
   236       if(csubbits){
   338       if(csubbits){
   237 	cval=vorbis_book_decode(books+info->class[classv].class_book,&vd->opb);
   339 	cval=vorbis_book_decode(books+info->class_book[classv],&vb->opb);
   238 
   340 
   239 	if(cval==-1)goto eop;
   341 	if(cval==-1)goto eop;
   240       }
   342       }
   241 
   343 
   242       for(k=0;k<cdim;k++){
   344       for(k=0;k<cdim;k++){
   243 	int book=info->class[classv].class_subbook[cval&(csub-1)];
   345 	int book=info->class_subbook[classv][cval&(csub-1)];
   244 	cval>>=csubbits;
   346 	cval>>=csubbits;
   245 	if(book!=0xff){
   347 	if(book>=0){
   246 	  if((fit_value[j+k]=vorbis_book_decode(books+book,&vd->opb))==-1)
   348 	  if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
   247 	    goto eop;
   349 	    goto eop;
   248 	}else{
   350 	}else{
   249 	  fit_value[j+k]=0;
   351 	  fit_value[j+k]=0;
   250 	}
   352 	}
   251       }
   353       }
   252       j+=cdim;
   354       j+=cdim;
   253     }
   355     }
   254 
   356 
   255     /* unwrap positive values and reconsitute via linear interpolation */
   357     /* unwrap positive values and reconsitute via linear interpolation */
   256     for(i=2;i<info->posts;i++){
   358     for(i=2;i<look->posts;i++){
   257       int predicted=render_point(info->postlist[info->loneighbor[i-2]],
   359       int predicted=render_point(info->postlist[look->loneighbor[i-2]],
   258 				 info->postlist[info->hineighbor[i-2]],
   360 				 info->postlist[look->hineighbor[i-2]],
   259 				 fit_value[info->loneighbor[i-2]],
   361 				 fit_value[look->loneighbor[i-2]],
   260 				 fit_value[info->hineighbor[i-2]],
   362 				 fit_value[look->hineighbor[i-2]],
   261 				 info->postlist[i]);
   363 				 info->postlist[i]);
   262       int hiroom=quant_q-predicted;
   364       int hiroom=look->quant_q-predicted;
   263       int loroom=predicted;
   365       int loroom=predicted;
   264       int room=(hiroom<loroom?hiroom:loroom)<<1;
   366       int room=(hiroom<loroom?hiroom:loroom)<<1;
   265       int val=fit_value[i];
   367       int val=fit_value[i];
   266 
   368 
   267       if(val){
   369       if(val){
   278 	    val>>=1;
   380 	    val>>=1;
   279 	  }
   381 	  }
   280 	}
   382 	}
   281 
   383 
   282 	fit_value[i]=val+predicted;
   384 	fit_value[i]=val+predicted;
   283 	fit_value[info->loneighbor[i-2]]&=0x7fff;
   385 	fit_value[look->loneighbor[i-2]]&=0x7fff;
   284 	fit_value[info->hineighbor[i-2]]&=0x7fff;
   386 	fit_value[look->hineighbor[i-2]]&=0x7fff;
   285 
   387 
   286       }else{
   388       }else{
   287 	fit_value[i]=predicted|0x8000;
   389 	fit_value[i]=predicted|0x8000;
   288       }
   390       }
   289 	
   391 	
   293   }
   395   }
   294  eop:
   396  eop:
   295   return(NULL);
   397   return(NULL);
   296 }
   398 }
   297 
   399 
   298 int floor1_inverse2(vorbis_dsp_state *vd,vorbis_info_floor *in,
   400 static int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
   299 		    ogg_int32_t *fit_value,ogg_int32_t *out){
   401 			  ogg_int32_t *out){
   300   vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
   402   vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
   301 
   403   vorbis_info_floor1 *info=look->vi;
   302   codec_setup_info   *ci=(codec_setup_info *)vd->vi->codec_setup;
   404 
   303   int                  n=ci->blocksizes[vd->W]/2;
   405   codec_setup_info   *ci=(codec_setup_info *)vb->vd->vi->codec_setup;
       
   406   int                  n=ci->blocksizes[vb->W]/2;
   304   int j;
   407   int j;
   305 
   408 
   306   if(fit_value){
   409   if(memo){
   307     /* render the lines */
   410     /* render the lines */
       
   411     int *fit_value=(int *)memo;
   308     int hx=0;
   412     int hx=0;
   309     int lx=0;
   413     int lx=0;
   310     int ly=fit_value[0]*info->mult;
   414     int ly=fit_value[0]*info->mult;
   311     for(j=1;j<info->posts;j++){
   415     for(j=1;j<look->posts;j++){
   312       int current=info->forward_index[j];
   416       int current=look->forward_index[j];
   313       int hy=fit_value[current]&0x7fff;
   417       int hy=fit_value[current]&0x7fff;
   314       if(hy==fit_value[current]){
   418       if(hy==fit_value[current]){
   315 	
   419 	
   316 	hy*=info->mult;
   420 	hy*=info->mult;
   317 	hx=info->postlist[current];
   421 	hx=info->postlist[current];
   326     return(1);
   430     return(1);
   327   }
   431   }
   328   memset(out,0,sizeof(*out)*n);
   432   memset(out,0,sizeof(*out)*n);
   329   return(0);
   433   return(0);
   330 }
   434 }
       
   435 
       
   436 /* export hooks */
       
   437 vorbis_func_floor floor1_exportbundle={
       
   438   &floor1_unpack,&floor1_look,&floor1_free_info,
       
   439   &floor1_free_look,&floor1_inverse1,&floor1_inverse2
       
   440 };
       
   441