18e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/********************************************************************
28e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
38e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
48e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
58e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
68e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
78e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
88e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2009             *
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/                  *
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: floor backend 1 implementation
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: floor1.c 17079 2010-03-26 06:51:41Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h>
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h>
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <ogg/ogg.h>
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "registry.h"
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codebook.h"
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "scales.h"
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdio.h>
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#define floor1_rangedB 140 /* floor 1 fixed at -140dB to 0dB range */
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct lsfit_acc{
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x0;
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x1;
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int xa;
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ya;
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x2a;
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int y2a;
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int xya;
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int an;
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int xb;
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int yb;
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x2b;
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int y2b;
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int xyb;
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int bn;
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} lsfit_acc;
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/***********************************************/
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void floor1_free_info(vorbis_info_floor *i){
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info){
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(info,0,sizeof(*info));
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(info);
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void floor1_free_look(vorbis_look_floor *i){
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor1 *look=(vorbis_look_floor1 *)i;
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(look){
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /*fprintf(stderr,"floor 1 bit usage %f:%f (%f total)\n",
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (float)look->phrasebits/look->frames,
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (float)look->postbits/look->frames,
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (float)(look->postbits+look->phrasebits)/look->frames);*/
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(look,0,sizeof(*look));
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(look);
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int ilog(unsigned int v){
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=0;
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(v){
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ret++;
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v>>=1;
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int ilog2(unsigned int v){
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=0;
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(v)--v;
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(v){
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ret++;
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v>>=1;
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void floor1_pack (vorbis_info_floor *i,oggpack_buffer *opb){
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=(vorbis_info_floor1 *)i;
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,k;
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int count=0;
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int rangebits;
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int maxposit=info->postlist[1];
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int maxclass=-1;
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* save out partitions */
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->partitions,5); /* only 0 to 31 legal */
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<info->partitions;j++){
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,info->partitionclass[j],4); /* only 0 to 15 legal */
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* save out partition classes */
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<maxclass+1;j++){
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,info->class_dim[j]-1,3); /* 1 to 8 */
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,info->class_subs[j],2); /* 0 to 3 */
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->class_subs[j])oggpack_write(opb,info->class_book[j],8);
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(k=0;k<(1<<info->class_subs[j]);k++)
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_write(opb,info->class_subbook[j][k]+1,8);
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* save out the post list */
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->mult-1,2);     /* only 1,2,3,4 legal now */
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,ilog2(maxposit),4);
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  rangebits=ilog2(maxposit);
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0,k=0;j<info->partitions;j++){
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    count+=info->class_dim[info->partitionclass[j]];
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(;k<count;k++)
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_write(opb,info->postlist[k+2],rangebits);
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int icomp(const void *a,const void *b){
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(**(int **)a-**(int **)b);
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic vorbis_info_floor *floor1_unpack (vorbis_info *vi,oggpack_buffer *opb){
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,k,count=0,maxclass=-1,rangebits;
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=_ogg_calloc(1,sizeof(*info));
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* read partitions */
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->partitions=oggpack_read(opb,5); /* only 0 to 31 legal */
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<info->partitions;j++){
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->partitionclass[j]=oggpack_read(opb,4); /* only 0 to 15 legal */
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->partitionclass[j]<0)goto err_out;
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(maxclass<info->partitionclass[j])maxclass=info->partitionclass[j];
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* read partition classes */
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<maxclass+1;j++){
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->class_dim[j]=oggpack_read(opb,3)+1; /* 1 to 8 */
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->class_subs[j]=oggpack_read(opb,2); /* 0,1,2,3 bits */
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->class_subs[j]<0)
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      goto err_out;
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->class_subs[j])info->class_book[j]=oggpack_read(opb,8);
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->class_book[j]<0 || info->class_book[j]>=ci->books)
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      goto err_out;
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(k=0;k<(1<<info->class_subs[j]);k++){
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      info->class_subbook[j][k]=oggpack_read(opb,8)-1;
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(info->class_subbook[j][k]<-1 || info->class_subbook[j][k]>=ci->books)
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        goto err_out;
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* read the post list */
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->mult=oggpack_read(opb,2)+1;     /* only 1,2,3,4 legal now */
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  rangebits=oggpack_read(opb,4);
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(rangebits<0)goto err_out;
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0,k=0;j<info->partitions;j++){
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    count+=info->class_dim[info->partitionclass[j]];
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(;k<count;k++){
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int t=info->postlist[k+2]=oggpack_read(opb,rangebits);
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(t<0 || t>=(1<<rangebits))
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        goto err_out;
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->postlist[0]=0;
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->postlist[1]=1<<rangebits;
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* don't allow repeated values in post list as they'd result in
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     zero-length segments */
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int *sortpointer[VIF_POSIT+2];
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<count+2;j++)sortpointer[j]=info->postlist+j;
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    qsort(sortpointer,count+2,sizeof(*sortpointer),icomp);
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=1;j<count+2;j++)
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(*sortpointer[j-1]==*sortpointer[j])goto err_out;
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(info);
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels err_out:
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  floor1_free_info(info);
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(NULL);
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic vorbis_look_floor *floor1_look(vorbis_dsp_state *vd,
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                      vorbis_info_floor *in){
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int *sortpointer[VIF_POSIT+2];
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=(vorbis_info_floor1 *)in;
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor1 *look=_ogg_calloc(1,sizeof(*look));
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,j,n=0;
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->vi=info;
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->n=info->postlist[1];
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* we drop each position value in-between already decoded values,
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     and use linear interpolation to predict each new value past the
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     edges.  The positions are read in the order of the position
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     list... we precompute the bounding positions in the lookup.  Of
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     course, the neighbors can change (if a position is declined), but
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     this is an initial mapping */
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<info->partitions;i++)n+=info->class_dim[info->partitionclass[i]];
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  n+=2;
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->posts=n;
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* also store a sorted position index */
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<n;i++)sortpointer[i]=info->postlist+i;
2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  qsort(sortpointer,n,sizeof(*sortpointer),icomp);
2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* points from sort order back to range number */
2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<n;i++)look->forward_index[i]=sortpointer[i]-info->postlist;
2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* points from range order to sorted position */
2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<n;i++)look->reverse_index[look->forward_index[i]]=i;
2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* we actually need the post values too */
2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<n;i++)look->sorted_index[i]=info->postlist[look->forward_index[i]];
2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* quantize values to multiplier spec */
2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  switch(info->mult){
2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  case 1: /* 1024 -> 256 */
2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->quant_q=256;
2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    break;
2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  case 2: /* 1024 -> 128 */
2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->quant_q=128;
2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    break;
2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  case 3: /* 1024 -> 86 */
2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->quant_q=86;
2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    break;
2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  case 4: /* 1024 -> 64 */
2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->quant_q=64;
2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    break;
2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* discover our neighbors for decode where we don't use fit flags
2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     (that would push the neighbors outward) */
2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<n-2;i++){
2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int lo=0;
2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int hi=1;
2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int lx=0;
2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int hx=look->n;
2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int currentx=info->postlist[i+2];
2548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<i+2;j++){
2558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int x=info->postlist[j];
2568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(x>lx && x<currentx){
2578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        lo=j;
2588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        lx=x;
2598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(x<hx && x>currentx){
2618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hi=j;
2628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hx=x;
2638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
2648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->loneighbor[i]=lo;
2668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->hineighbor[i]=hi;
2678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(look);
2708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int render_point(int x0,int x1,int y0,int y1,int x){
2738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  y0&=0x7fff; /* mask off flag */
2748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  y1&=0x7fff;
2758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
2778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int dy=y1-y0;
2788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int adx=x1-x0;
2798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int ady=abs(dy);
2808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int err=ady*(x-x0);
2818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int off=err/adx;
2838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(dy<0)return(y0-off);
2848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(y0+off);
2858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int vorbis_dBquant(const float *x){
2898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i= *x*7.3142857f+1023.5f;
2908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(i>1023)return(1023);
2918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(i<0)return(0);
2928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return i;
2938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic const float FLOOR1_fromdB_LOOKUP[256]={
2968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.0649863e-07F, 1.1341951e-07F, 1.2079015e-07F, 1.2863978e-07F,
2978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.3699951e-07F, 1.4590251e-07F, 1.5538408e-07F, 1.6548181e-07F,
2988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.7623575e-07F, 1.8768855e-07F, 1.9988561e-07F, 2.128753e-07F,
2998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  2.2670913e-07F, 2.4144197e-07F, 2.5713223e-07F, 2.7384213e-07F,
3008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  2.9163793e-07F, 3.1059021e-07F, 3.3077411e-07F, 3.5226968e-07F,
3018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  3.7516214e-07F, 3.9954229e-07F, 4.2550680e-07F, 4.5315863e-07F,
3028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  4.8260743e-07F, 5.1396998e-07F, 5.4737065e-07F, 5.8294187e-07F,
3038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  6.2082472e-07F, 6.6116941e-07F, 7.0413592e-07F, 7.4989464e-07F,
3048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  7.9862701e-07F, 8.5052630e-07F, 9.0579828e-07F, 9.6466216e-07F,
3058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.0273513e-06F, 1.0941144e-06F, 1.1652161e-06F, 1.2409384e-06F,
3068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.3215816e-06F, 1.4074654e-06F, 1.4989305e-06F, 1.5963394e-06F,
3078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.7000785e-06F, 1.8105592e-06F, 1.9282195e-06F, 2.0535261e-06F,
3088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  2.1869758e-06F, 2.3290978e-06F, 2.4804557e-06F, 2.6416497e-06F,
3098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  2.8133190e-06F, 2.9961443e-06F, 3.1908506e-06F, 3.3982101e-06F,
3108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  3.6190449e-06F, 3.8542308e-06F, 4.1047004e-06F, 4.3714470e-06F,
3118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  4.6555282e-06F, 4.9580707e-06F, 5.2802740e-06F, 5.6234160e-06F,
3128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  5.9888572e-06F, 6.3780469e-06F, 6.7925283e-06F, 7.2339451e-06F,
3138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  7.7040476e-06F, 8.2047000e-06F, 8.7378876e-06F, 9.3057248e-06F,
3148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  9.9104632e-06F, 1.0554501e-05F, 1.1240392e-05F, 1.1970856e-05F,
3158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.2748789e-05F, 1.3577278e-05F, 1.4459606e-05F, 1.5399272e-05F,
3168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  1.6400004e-05F, 1.7465768e-05F, 1.8600792e-05F, 1.9809576e-05F,
3178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  2.1096914e-05F, 2.2467911e-05F, 2.3928002e-05F, 2.5482978e-05F,
3188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  2.7139006e-05F, 2.8902651e-05F, 3.0780908e-05F, 3.2781225e-05F,
3198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  3.4911534e-05F, 3.7180282e-05F, 3.9596466e-05F, 4.2169667e-05F,
3208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  4.4910090e-05F, 4.7828601e-05F, 5.0936773e-05F, 5.4246931e-05F,
3218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  5.7772202e-05F, 6.1526565e-05F, 6.5524908e-05F, 6.9783085e-05F,
3228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  7.4317983e-05F, 7.9147585e-05F, 8.4291040e-05F, 8.9768747e-05F,
3238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  9.5602426e-05F, 0.00010181521F, 0.00010843174F, 0.00011547824F,
3248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00012298267F, 0.00013097477F, 0.00013948625F, 0.00014855085F,
3258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00015820453F, 0.00016848555F, 0.00017943469F, 0.00019109536F,
3268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00020351382F, 0.00021673929F, 0.00023082423F, 0.00024582449F,
3278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00026179955F, 0.00027881276F, 0.00029693158F, 0.00031622787F,
3288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00033677814F, 0.00035866388F, 0.00038197188F, 0.00040679456F,
3298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00043323036F, 0.00046138411F, 0.00049136745F, 0.00052329927F,
3308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00055730621F, 0.00059352311F, 0.00063209358F, 0.00067317058F,
3318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00071691700F, 0.00076350630F, 0.00081312324F, 0.00086596457F,
3328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.00092223983F, 0.00098217216F, 0.0010459992F, 0.0011139742F,
3338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0011863665F, 0.0012634633F, 0.0013455702F, 0.0014330129F,
3348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0015261382F, 0.0016253153F, 0.0017309374F, 0.0018434235F,
3358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0019632195F, 0.0020908006F, 0.0022266726F, 0.0023713743F,
3368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0025254795F, 0.0026895994F, 0.0028643847F, 0.0030505286F,
3378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0032487691F, 0.0034598925F, 0.0036847358F, 0.0039241906F,
3388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0041792066F, 0.0044507950F, 0.0047400328F, 0.0050480668F,
3398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0053761186F, 0.0057254891F, 0.0060975636F, 0.0064938176F,
3408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0069158225F, 0.0073652516F, 0.0078438871F, 0.0083536271F,
3418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.0088964928F, 0.009474637F, 0.010090352F, 0.010746080F,
3428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.011444421F, 0.012188144F, 0.012980198F, 0.013823725F,
3438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.014722068F, 0.015678791F, 0.016697687F, 0.017782797F,
3448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.018938423F, 0.020169149F, 0.021479854F, 0.022875735F,
3458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.024362330F, 0.025945531F, 0.027631618F, 0.029427276F,
3468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.031339626F, 0.033376252F, 0.035545228F, 0.037855157F,
3478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.040315199F, 0.042935108F, 0.045725273F, 0.048696758F,
3488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.051861348F, 0.055231591F, 0.058820850F, 0.062643361F,
3498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.066714279F, 0.071049749F, 0.075666962F, 0.080584227F,
3508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.085821044F, 0.091398179F, 0.097337747F, 0.10366330F,
3518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.11039993F, 0.11757434F, 0.12521498F, 0.13335215F,
3528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.14201813F, 0.15124727F, 0.16107617F, 0.17154380F,
3538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.18269168F, 0.19456402F, 0.20720788F, 0.22067342F,
3548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.23501402F, 0.25028656F, 0.26655159F, 0.28387361F,
3558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.30232132F, 0.32196786F, 0.34289114F, 0.36517414F,
3568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.38890521F, 0.41417847F, 0.44109412F, 0.46975890F,
3578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.50028648F, 0.53279791F, 0.56742212F, 0.60429640F,
3588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.64356699F, 0.68538959F, 0.72993007F, 0.77736504F,
3598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  0.82788260F, 0.88168307F, 0.9389798F, 1.F,
3608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
3618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void render_line(int n, int x0,int x1,int y0,int y1,float *d){
3638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int dy=y1-y0;
3648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int adx=x1-x0;
3658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ady=abs(dy);
3668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int base=dy/adx;
3678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int sy=(dy<0?base-1:base+1);
3688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x=x0;
3698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int y=y0;
3708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int err=0;
3718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ady-=abs(base*adx);
3738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(n>x1)n=x1;
3758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(x<n)
3778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    d[x]*=FLOOR1_fromdB_LOOKUP[y];
3788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(++x<n){
3808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    err=err+ady;
3818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(err>=adx){
3828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      err-=adx;
3838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      y+=sy;
3848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
3858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      y+=base;
3868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    d[x]*=FLOOR1_fromdB_LOOKUP[y];
3888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void render_line0(int n, int x0,int x1,int y0,int y1,int *d){
3928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int dy=y1-y0;
3938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int adx=x1-x0;
3948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ady=abs(dy);
3958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int base=dy/adx;
3968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int sy=(dy<0?base-1:base+1);
3978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x=x0;
3988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int y=y0;
3998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int err=0;
4008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ady-=abs(base*adx);
4028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(n>x1)n=x1;
4048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(x<n)
4068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    d[x]=y;
4078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(++x<n){
4098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    err=err+ady;
4108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(err>=adx){
4118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      err-=adx;
4128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      y+=sy;
4138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
4148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      y+=base;
4158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    d[x]=y;
4178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* the floor has already been filtered to only include relevant sections */
4218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int accumulate_fit(const float *flr,const float *mdct,
4228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          int x0, int x1,lsfit_acc *a,
4238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          int n,vorbis_info_floor1 *info){
4248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i;
4258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int xa=0,ya=0,x2a=0,y2a=0,xya=0,na=0, xb=0,yb=0,x2b=0,y2b=0,xyb=0,nb=0;
4278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(a,0,sizeof(*a));
4298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->x0=x0;
4308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->x1=x1;
4318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(x1>=n)x1=n-1;
4328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=x0;i<=x1;i++){
4348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int quantized=vorbis_dBquant(flr+i);
4358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(quantized){
4368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(mdct[i]+info->twofitatten>=flr[i]){
4378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        xa  += i;
4388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ya  += quantized;
4398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        x2a += i*i;
4408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        y2a += quantized*quantized;
4418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        xya += i*quantized;
4428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        na++;
4438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
4448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        xb  += i;
4458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        yb  += quantized;
4468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        x2b += i*i;
4478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        y2b += quantized*quantized;
4488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        xyb += i*quantized;
4498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        nb++;
4508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
4518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->xa=xa;
4558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->ya=ya;
4568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->x2a=x2a;
4578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->y2a=y2a;
4588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->xya=xya;
4598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->an=na;
4608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->xb=xb;
4628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->yb=yb;
4638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->x2b=x2b;
4648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->y2b=y2b;
4658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->xyb=xyb;
4668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  a->bn=nb;
4678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(na);
4698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int fit_line(lsfit_acc *a,int fits,int *y0,int *y1,
4728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    vorbis_info_floor1 *info){
4738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  double xb=0,yb=0,x2b=0,y2b=0,xyb=0,bn=0;
4748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i;
4758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x0=a[0].x0;
4768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x1=a[fits-1].x1;
4778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<fits;i++){
4798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    double weight = (a[i].bn+a[i].an)*info->twofitweight/(a[i].an+1)+1.;
4808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    xb+=a[i].xb + a[i].xa * weight;
4828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    yb+=a[i].yb + a[i].ya * weight;
4838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    x2b+=a[i].x2b + a[i].x2a * weight;
4848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    y2b+=a[i].y2b + a[i].y2a * weight;
4858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    xyb+=a[i].xyb + a[i].xya * weight;
4868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bn+=a[i].bn + a[i].an * weight;
4878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(*y0>=0){
4908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    xb+=   x0;
4918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    yb+=  *y0;
4928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    x2b+=  x0 *  x0;
4938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    y2b+= *y0 * *y0;
4948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    xyb+= *y0 *  x0;
4958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bn++;
4968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(*y1>=0){
4998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    xb+=   x1;
5008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    yb+=  *y1;
5018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    x2b+=  x1 *  x1;
5028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    y2b+= *y1 * *y1;
5038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    xyb+= *y1 *  x1;
5048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bn++;
5058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
5088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    double denom=(bn*x2b-xb*xb);
5098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(denom>0.){
5118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      double a=(yb*x2b-xyb*xb)/denom;
5128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      double b=(bn*xyb-xb*yb)/denom;
5138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      *y0=rint(a+b*x0);
5148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      *y1=rint(a+b*x1);
5158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* limit to our range! */
5178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(*y0>1023)*y0=1023;
5188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(*y1>1023)*y1=1023;
5198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(*y0<0)*y0=0;
5208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(*y1<0)*y1=0;
5218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return 0;
5238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
5248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      *y0=0;
5258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      *y1=0;
5268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return 1;
5278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
5308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int inspect_error(int x0,int x1,int y0,int y1,const float *mask,
5328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                         const float *mdct,
5338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                         vorbis_info_floor1 *info){
5348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int dy=y1-y0;
5358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int adx=x1-x0;
5368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ady=abs(dy);
5378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int base=dy/adx;
5388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int sy=(dy<0?base-1:base+1);
5398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int x=x0;
5408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int y=y0;
5418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int err=0;
5428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int val=vorbis_dBquant(mask+x);
5438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int mse=0;
5448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=0;
5458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  ady-=abs(base*adx);
5478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  mse=(y-val);
5498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  mse*=mse;
5508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  n++;
5518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(mdct[x]+info->twofitatten>=mask[x]){
5528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(y+info->maxover<val)return(1);
5538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(y-info->maxunder>val)return(1);
5548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(++x<x1){
5578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    err=err+ady;
5588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(err>=adx){
5598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      err-=adx;
5608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      y+=sy;
5618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else{
5628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      y+=base;
5638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    val=vorbis_dBquant(mask+x);
5668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    mse+=((y-val)*(y-val));
5678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    n++;
5688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(mdct[x]+info->twofitatten>=mask[x]){
5698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(val){
5708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(y+info->maxover<val)return(1);
5718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(y-info->maxunder>val)return(1);
5728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
5738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->maxover*info->maxover/n>info->maxerr)return(0);
5778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->maxunder*info->maxunder/n>info->maxerr)return(0);
5788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(mse/n>info->maxerr)return(1);
5798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
5808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
5818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int post_Y(int *A,int *B,int pos){
5838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(A[pos]<0)
5848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return B[pos];
5858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(B[pos]<0)
5868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return A[pos];
5878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return (A[pos]+B[pos])>>1;
5898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
5908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint *floor1_fit(vorbis_block *vb,vorbis_look_floor1 *look,
5928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          const float *logmdct,   /* in */
5938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          const float *logmask){
5948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j;
5958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=look->vi;
5968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long n=look->n;
5978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long posts=look->posts;
5988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long nonzero=0;
5998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  lsfit_acc fits[VIF_POSIT+1];
6008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int fit_valueA[VIF_POSIT+2]; /* index by range list position */
6018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int fit_valueB[VIF_POSIT+2]; /* index by range list position */
6028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int loneighbor[VIF_POSIT+2]; /* sorted index of range list position (+2) */
6048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int hineighbor[VIF_POSIT+2];
6058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int *output=NULL;
6068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int memo[VIF_POSIT+2];
6078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<posts;i++)fit_valueA[i]=-200; /* mark all unused */
6098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<posts;i++)fit_valueB[i]=-200; /* mark all unused */
6108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<posts;i++)loneighbor[i]=0; /* 0 for the implicit 0 post */
6118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<posts;i++)hineighbor[i]=1; /* 1 for the implicit post at n */
6128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<posts;i++)memo[i]=-1;      /* no neighbor yet */
6138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* quantize the relevant floor points and collect them into line fit
6158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     structures (one per minimal division) at the same time */
6168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(posts==0){
6178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    nonzero+=accumulate_fit(logmask,logmdct,0,n,fits,n,info);
6188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
6198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<posts-1;i++)
6208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      nonzero+=accumulate_fit(logmask,logmdct,look->sorted_index[i],
6218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              look->sorted_index[i+1],fits+i,
6228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              n,info);
6238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(nonzero){
6268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* start by fitting the implicit base case.... */
6278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int y0=-200;
6288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int y1=-200;
6298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_line(fits,posts-1,&y0,&y1,info);
6308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_valueA[0]=y0;
6328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_valueB[0]=y0;
6338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_valueB[1]=y1;
6348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_valueA[1]=y1;
6358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* Non degenerate case */
6378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* start progressive splitting.  This is a greedy, non-optimal
6388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       algorithm, but simple and close enough to the best
6398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       answer. */
6408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=2;i<posts;i++){
6418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int sortpos=look->reverse_index[i];
6428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int ln=loneighbor[sortpos];
6438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int hn=hineighbor[sortpos];
6448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* eliminate repeat searches of a particular range with a memo */
6468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(memo[ln]!=hn){
6478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* haven't performed this error search yet */
6488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int lsortpos=look->reverse_index[ln];
6498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int hsortpos=look->reverse_index[hn];
6508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        memo[ln]=hn;
6518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        {
6538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* A note: we want to bound/minimize *local*, not global, error */
6548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int lx=info->postlist[ln];
6558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int hx=info->postlist[hn];
6568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int ly=post_Y(fit_valueA,fit_valueB,ln);
6578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int hy=post_Y(fit_valueA,fit_valueB,hn);
6588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(ly==-1 || hy==-1){
6608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            exit(1);
6618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
6628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(inspect_error(lx,hx,ly,hy,logmask,logmdct,info)){
6648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            /* outside error bounds/begin search area.  Split it. */
6658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int ly0=-200;
6668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int ly1=-200;
6678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int hy0=-200;
6688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int hy1=-200;
6698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int ret0=fit_line(fits+lsortpos,sortpos-lsortpos,&ly0,&ly1,info);
6708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int ret1=fit_line(fits+sortpos,hsortpos-sortpos,&hy0,&hy1,info);
6718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(ret0){
6738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              ly0=ly;
6748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              ly1=hy0;
6758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
6768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(ret1){
6778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              hy0=ly1;
6788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              hy1=hy;
6798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
6808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(ret0 && ret1){
6828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fit_valueA[i]=-200;
6838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fit_valueB[i]=-200;
6848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }else{
6858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              /* store new edge values */
6868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fit_valueB[ln]=ly0;
6878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              if(ln==0)fit_valueA[ln]=ly0;
6888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fit_valueA[i]=ly1;
6898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fit_valueB[i]=hy0;
6908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fit_valueA[hn]=hy1;
6918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              if(hn==1)fit_valueB[hn]=hy1;
6928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              if(ly1>=0 || hy0>=0){
6948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                /* store new neighbor values */
6958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                for(j=sortpos-1;j>=0;j--)
6968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  if(hineighbor[j]==hn)
6978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    hineighbor[j]=i;
6988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  else
6998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    break;
7008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                for(j=sortpos+1;j<posts;j++)
7018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  if(loneighbor[j]==ln)
7028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    loneighbor[j]=i;
7038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  else
7048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    break;
7058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              }
7068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
7078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }else{
7088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fit_valueA[i]=-200;
7098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fit_valueB[i]=-200;
7108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
7118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
7128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
7138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
7148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
7168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    output[0]=post_Y(fit_valueA,fit_valueB,0);
7188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    output[1]=post_Y(fit_valueA,fit_valueB,1);
7198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* fill in posts marked as not using a fit; we will zero
7218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       back out to 'unused' when encoding them so long as curve
7228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels       interpolation doesn't force them into use */
7238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=2;i<posts;i++){
7248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int ln=look->loneighbor[i-2];
7258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int hn=look->hineighbor[i-2];
7268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int x0=info->postlist[ln];
7278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int x1=info->postlist[hn];
7288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int y0=output[ln];
7298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int y1=output[hn];
7308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
7328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int vx=post_Y(fit_valueA,fit_valueB,i);
7338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(vx>=0 && predicted!=vx){
7358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        output[i]=vx;
7368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
7378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        output[i]= predicted|0x8000;
7388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
7398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
7408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(output);
7438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint *floor1_interpolate_fit(vorbis_block *vb,vorbis_look_floor1 *look,
7478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          int *A,int *B,
7488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          int del){
7498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i;
7518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long posts=look->posts;
7528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int *output=NULL;
7538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(A && B){
7558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    output=_vorbis_block_alloc(vb,sizeof(*output)*posts);
7568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* overly simpleminded--- look again post 1.2 */
7588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<posts;i++){
7598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      output[i]=((65536-del)*(A[i]&0x7fff)+del*(B[i]&0x7fff)+32768)>>16;
7608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(A[i]&0x8000 && B[i]&0x8000)output[i]|=0x8000;
7618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
7628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(output);
7658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint floor1_encode(oggpack_buffer *opb,vorbis_block *vb,
7698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  vorbis_look_floor1 *look,
7708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  int *post,int *ilogmask){
7718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j;
7738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=look->vi;
7748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long posts=look->posts;
7758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info *ci=vb->vd->vi->codec_setup;
7768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int out[VIF_POSIT+2];
7778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  static_codebook **sbooks=ci->book_param;
7788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codebook *books=ci->fullbooks;
7798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* quantize values to multiplier spec */
7818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(post){
7828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<posts;i++){
7838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int val=post[i]&0x7fff;
7848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      switch(info->mult){
7858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      case 1: /* 1024 -> 256 */
7868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        val>>=2;
7878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        break;
7888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      case 2: /* 1024 -> 128 */
7898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        val>>=3;
7908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        break;
7918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      case 3: /* 1024 -> 86 */
7928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        val/=12;
7938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        break;
7948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      case 4: /* 1024 -> 64 */
7958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        val>>=4;
7968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        break;
7978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
7988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      post[i]=val | (post[i]&0x8000);
7998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    out[0]=post[0];
8028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    out[1]=post[1];
8038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* find prediction values for each post and subtract them */
8058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=2;i<posts;i++){
8068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int ln=look->loneighbor[i-2];
8078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int hn=look->hineighbor[i-2];
8088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int x0=info->postlist[ln];
8098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int x1=info->postlist[hn];
8108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int y0=post[ln];
8118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int y1=post[hn];
8128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int predicted=render_point(x0,x1,y0,y1,info->postlist[i]);
8148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if((post[i]&0x8000) || (predicted==post[i])){
8168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        post[i]=predicted|0x8000; /* in case there was roundoff jitter
8178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                     in interpolation */
8188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        out[i]=0;
8198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
8208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int headroom=(look->quant_q-predicted<predicted?
8218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      look->quant_q-predicted:predicted);
8228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int val=post[i]-predicted;
8248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* at this point the 'deviation' value is in the range +/- max
8268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           range, but the real, unique range can always be mapped to
8278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           only [0-maxrange).  So we want to wrap the deviation into
8288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           this limited range, but do it in the way that least screws
8298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           an essentially gaussian probability distribution. */
8308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(val<0)
8328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(val<-headroom)
8338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val=headroom-val-1;
8348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          else
8358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val=-1-(val<<1);
8368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        else
8378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(val>=headroom)
8388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val= val+headroom;
8398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          else
8408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val<<=1;
8418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        out[i]=val;
8438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        post[ln]&=0x7fff;
8448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        post[hn]&=0x7fff;
8458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
8468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* we have everything we need. pack it out */
8498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* mark nontrivial floor */
8508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,1,1);
8518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* beginning/end post */
8538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->frames++;
8548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->postbits+=ilog(look->quant_q-1)*2;
8558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,out[0],ilog(look->quant_q-1));
8568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,out[1],ilog(look->quant_q-1));
8578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* partition by partition */
8608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0,j=2;i<info->partitions;i++){
8618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int class=info->partitionclass[i];
8628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int cdim=info->class_dim[class];
8638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int csubbits=info->class_subs[class];
8648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int csub=1<<csubbits;
8658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int bookas[8]={0,0,0,0,0,0,0,0};
8668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int cval=0;
8678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int cshift=0;
8688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int k,l;
8698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* generate the partition's first stage cascade value */
8718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(csubbits){
8728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int maxval[8];
8738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<csub;k++){
8748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int booknum=info->class_subbook[class][k];
8758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(booknum<0){
8768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            maxval[k]=1;
8778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }else{
8788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            maxval[k]=sbooks[info->class_subbook[class][k]]->entries;
8798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
8808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
8818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<cdim;k++){
8828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(l=0;l<csub;l++){
8838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int val=out[j+k];
8848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(val<maxval[l]){
8858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              bookas[k]=l;
8868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              break;
8878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
8888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
8898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          cval|= bookas[k]<<cshift;
8908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          cshift+=csubbits;
8918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
8928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* write it */
8938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        look->phrasebits+=
8948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          vorbis_book_encode(books+info->class_book[class],cval,opb);
8958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_FLOOR1
8978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        {
8988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          FILE *of;
8998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          char buffer[80];
9008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          sprintf(buffer,"line_%dx%ld_class%d.vqd",
9018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  vb->pcmend/2,posts-2,class);
9028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          of=fopen(buffer,"a");
9038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          fprintf(of,"%d\n",cval);
9048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          fclose(of);
9058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
9068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
9078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* write post values */
9108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<cdim;k++){
9118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int book=info->class_subbook[class][bookas[k]];
9128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(book>=0){
9138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* hack to allow training with 'bad' books */
9148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(out[j+k]<(books+book)->entries)
9158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            look->postbits+=vorbis_book_encode(books+book,
9168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                               out[j+k],opb);
9178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /*else
9188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fprintf(stderr,"+!");*/
9198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_FLOOR1
9218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          {
9228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            FILE *of;
9238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            char buffer[80];
9248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            sprintf(buffer,"line_%dx%ld_%dsub%d.vqd",
9258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    vb->pcmend/2,posts-2,class,bookas[k]);
9268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            of=fopen(buffer,"a");
9278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fprintf(of,"%d\n",out[j+k]);
9288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fclose(of);
9298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
9308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
9318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
9328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      j+=cdim;
9348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    {
9378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* generate quantized floor equivalent to what we'd unpack in decode */
9388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* render the lines */
9398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int hx=0;
9408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int lx=0;
9418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int ly=post[0]*info->mult;
9428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int n=ci->blocksizes[vb->W]/2;
9438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=1;j<look->posts;j++){
9458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int current=look->forward_index[j];
9468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int hy=post[current]&0x7fff;
9478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(hy==post[current]){
9488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hy*=info->mult;
9508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          hx=info->postlist[current];
9518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          render_line0(n,lx,hx,ly,hy,ilogmask);
9538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          lx=hx;
9558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          ly=hy;
9568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
9578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=hx;j<vb->pcmend/2;j++)ilogmask[j]=ly; /* be certain */
9598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      return(1);
9608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
9618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
9628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,0,1);
9638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(ilogmask,0,vb->pcmend/2*sizeof(*ilogmask));
9648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
9658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
9668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
9678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic void *floor1_inverse1(vorbis_block *vb,vorbis_look_floor *in){
9698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
9708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=look->vi;
9718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info   *ci=vb->vd->vi->codec_setup;
9728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,j,k;
9748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codebook *books=ci->fullbooks;
9758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* unpack wrapped/predicted values from stream */
9778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(oggpack_read(&vb->opb,1)==1){
9788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int *fit_value=_vorbis_block_alloc(vb,(look->posts)*sizeof(*fit_value));
9798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_value[0]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
9818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fit_value[1]=oggpack_read(&vb->opb,ilog(look->quant_q-1));
9828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* partition by partition */
9848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0,j=2;i<info->partitions;i++){
9858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int class=info->partitionclass[i];
9868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int cdim=info->class_dim[class];
9878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int csubbits=info->class_subs[class];
9888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int csub=1<<csubbits;
9898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int cval=0;
9908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* decode the partition's first stage cascade value */
9928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(csubbits){
9938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        cval=vorbis_book_decode(books+info->class_book[class],&vb->opb);
9948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(cval==-1)goto eop;
9968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
9978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
9988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<cdim;k++){
9998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int book=info->class_subbook[class][cval&(csub-1)];
10008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        cval>>=csubbits;
10018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(book>=0){
10028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if((fit_value[j+k]=vorbis_book_decode(books+book,&vb->opb))==-1)
10038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            goto eop;
10048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
10058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          fit_value[j+k]=0;
10068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
10078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      j+=cdim;
10098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
10108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* unwrap positive values and reconsitute via linear interpolation */
10128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=2;i<look->posts;i++){
10138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int predicted=render_point(info->postlist[look->loneighbor[i-2]],
10148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 info->postlist[look->hineighbor[i-2]],
10158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 fit_value[look->loneighbor[i-2]],
10168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 fit_value[look->hineighbor[i-2]],
10178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                 info->postlist[i]);
10188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int hiroom=look->quant_q-predicted;
10198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int loroom=predicted;
10208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int room=(hiroom<loroom?hiroom:loroom)<<1;
10218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int val=fit_value[i];
10228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(val){
10248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(val>=room){
10258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(hiroom>loroom){
10268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val = val-loroom;
10278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }else{
10288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val = -1-(val-hiroom);
10298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
10308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }else{
10318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(val&1){
10328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val= -((val+1)>>1);
10338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }else{
10348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val>>=1;
10358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
10368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
10378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fit_value[i]=val+predicted;
10398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fit_value[look->loneighbor[i-2]]&=0x7fff;
10408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fit_value[look->hineighbor[i-2]]&=0x7fff;
10418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }else{
10438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fit_value[i]=predicted|0x8000;
10448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
10478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(fit_value);
10498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
10508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels eop:
10518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(NULL);
10528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
10538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int floor1_inverse2(vorbis_block *vb,vorbis_look_floor *in,void *memo,
10558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                          float *out){
10568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_floor1 *look=(vorbis_look_floor1 *)in;
10578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_floor1 *info=look->vi;
10588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info   *ci=vb->vd->vi->codec_setup;
10608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int                  n=ci->blocksizes[vb->W]/2;
10618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j;
10628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(memo){
10648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* render the lines */
10658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int *fit_value=(int *)memo;
10668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int hx=0;
10678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int lx=0;
10688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int ly=fit_value[0]*info->mult;
10698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=1;j<look->posts;j++){
10708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int current=look->forward_index[j];
10718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int hy=fit_value[current]&0x7fff;
10728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(hy==fit_value[current]){
10738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hy*=info->mult;
10758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        hx=info->postlist[current];
10768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        render_line(n,lx,hx,ly,hy,out);
10788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        lx=hx;
10808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ly=hy;
10818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
10828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
10838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=hx;j<n;j++)out[j]*=FLOOR1_fromdB_LOOKUP[ly]; /* be certain */
10848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(1);
10858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
10868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(out,0,sizeof(*out)*n);
10878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
10888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
10898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
10908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* export hooks */
10918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsconst vorbis_func_floor floor1_exportbundle={
10928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &floor1_pack,&floor1_unpack,&floor1_look,&floor1_free_info,
10938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &floor1_free_look,&floor1_inverse1,&floor1_inverse2
10948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
1095