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-2010             *
98e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels * by the Xiph.Org Foundation http://www.xiph.org/                  *
108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels *                                                                  *
118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************
128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels function: residue backend 0, 1 and 2 implementation
148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels last mod: $Id: res0.c 16962 2010-03-11 07:30:34Z xiphmont $
158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels ********************************************************************/
178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* Slow, slow, slow, simpleminded and did I mention it was slow?  The
198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   encode/decode loops are coded for clarity and performance is not
208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   yet even a nagging little idea lurking in the shadows.  Oh and BTW,
218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   it's slow. */
228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdlib.h>
248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <string.h>
258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <math.h>
268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <ogg/ogg.h>
278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "vorbis/codec.h"
288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codec_internal.h"
298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "registry.h"
308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "codebook.h"
318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "misc.h"
328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include "os.h"
338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels//#define TRAIN_RES 1
358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels//#define TRAIN_RESAUX 1
368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#include <stdio.h>
398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelstypedef struct {
428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info;
438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int         parts;
458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int         stages;
468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codebook   *fullbooks;
478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codebook   *phrasebook;
488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codebook ***partbooks;
498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int         partvals;
518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int       **decodemap;
528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long      postbits;
548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long      phrasebits;
558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long      frames;
568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int        train_seq;
598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long      *training_data[8][64];
608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float      training_max[8][64];
618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float      training_min[8][64];
628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float     tmin;
638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float     tmax;
648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int       submap;
658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels} vorbis_look_residue0;
688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid res0_free_info(vorbis_info_residue *i){
708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info){
728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(info,0,sizeof(*info));
738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(info);
748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid res0_free_look(vorbis_look_residue *i){
788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j;
798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(i){
808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RES
848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    {
858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int j,k,l;
868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<look->parts;j++){
878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /*fprintf(stderr,"partition %d: ",j);*/
888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<8;k++)
898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(look->training_data[k][j]){
908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            char buffer[80];
918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            FILE *of;
928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            codebook *statebook=look->partbooks[j][k];
938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            /* long and short into the same bucket by current convention */
958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k);
968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            of=fopen(buffer,"a");
978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            for(l=0;l<statebook->entries;l++)
998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]);
1008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fclose(of);
1028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            /*fprintf(stderr,"%d(%.2f|%.2f) ",k,
1048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              look->training_min[k][j],look->training_max[k][j]);*/
1058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            _ogg_free(look->training_data[k][j]);
1078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            look->training_data[k][j]=NULL;
1088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
1098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /*fprintf(stderr,"\n");*/
1108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
1118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax);
1138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
1158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (float)look->phrasebits/look->frames,
1168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (float)look->postbits/look->frames,
1178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (float)(look->postbits+look->phrasebits)/look->frames);*/
1188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
1198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /*vorbis_info_residue0 *info=look->info;
1228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,
1248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            "%ld frames encoded in %ld phrasebits and %ld residue bits "
1258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            "(%g/frame) \n",look->frames,look->phrasebits,
1268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            look->resbitsflat,
1278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            (look->phrasebits+look->resbitsflat)/(float)look->frames);
1288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<look->parts;j++){
1308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      long acc=0;
1318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fprintf(stderr,"\t[%d] == ",j);
1328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<look->stages;k++)
1338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if((info->secondstages[j]>>k)&1){
1348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          fprintf(stderr,"%ld,",look->resbits[j][k]);
1358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          acc+=look->resbits[j][k];
1368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
1378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
1398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              acc?(float)acc/(look->resvals[j]*info->grouping):0);
1408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
1418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"\n");*/
1428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<look->parts;j++)
1448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
1458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(look->partbooks);
1468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<look->partvals;j++)
1478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      _ogg_free(look->decodemap[j]);
1488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(look->decodemap);
1498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(look,0,sizeof(*look));
1518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    _ogg_free(look);
1528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int ilog(unsigned int v){
1568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=0;
1578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(v){
1588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ret++;
1598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v>>=1;
1608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
1628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int icount(unsigned int v){
1658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ret=0;
1668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  while(v){
1678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    ret+=v&1;
1688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    v>>=1;
1698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(ret);
1718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
1728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvoid res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
1758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
1768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,acc=0;
1778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->begin,24);
1788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->end,24);
1798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->grouping-1,24);  /* residue vectors to group and
1818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                             code with a partitioned book */
1828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
1838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  oggpack_write(opb,info->groupbook,8);  /* group huffman book */
1848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
1858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* secondstages is a bitmask; as encoding progresses pass by pass, a
1868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     bitmask of one indicates this partition class has bits to write
1878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     this pass */
1888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<info->partitions;j++){
1898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(ilog(info->secondstages[j])>3){
1908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* yes, this is a minor hack due to not thinking ahead */
1918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_write(opb,info->secondstages[j],3);
1928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_write(opb,1,1);
1938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_write(opb,info->secondstages[j]>>3,5);
1948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }else
1958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
1968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    acc+=icount(info->secondstages[j]);
1978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
1988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<acc;j++)
1998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    oggpack_write(opb,info->booklist[j],8);
2008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* vorbis_info is for range checking */
2048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
2058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,acc=0;
2068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info));
2078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vi->codec_setup;
2088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->begin=oggpack_read(opb,24);
2108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->end=oggpack_read(opb,24);
2118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->grouping=oggpack_read(opb,24)+1;
2128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->partitions=oggpack_read(opb,6)+1;
2138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  info->groupbook=oggpack_read(opb,8);
2148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* check for premature EOP */
2168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->groupbook<0)goto errout;
2178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<info->partitions;j++){
2198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int cascade=oggpack_read(opb,3);
2208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int cflag=oggpack_read(opb,1);
2218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(cflag<0) goto errout;
2228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(cflag){
2238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int c=oggpack_read(opb,5);
2248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(c<0) goto errout;
2258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      cascade|=(c<<3);
2268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->secondstages[j]=cascade;
2288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    acc+=icount(cascade);
2308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<acc;j++){
2328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int book=oggpack_read(opb,8);
2338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(book<0) goto errout;
2348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->booklist[j]=book;
2358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(info->groupbook>=ci->books)goto errout;
2388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<acc;j++){
2398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(info->booklist[j]>=ci->books)goto errout;
2408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
2418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* verify the phrasebook is not specifying an impossible or
2448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     inconsistent partitioning scheme. */
2458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* modify the phrasebook ranging check from r16327; an early beta
2468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     encoder had a bug where it used an oversized phrasebook by
2478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     accident.  These files should continue to be playable, but don't
2488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     allow an exploit */
2498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
2508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int entries = ci->book_param[info->groupbook]->entries;
2518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int dim = ci->book_param[info->groupbook]->dim;
2528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int partvals = 1;
2538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    while(dim>0){
2548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      partvals *= info->partitions;
2558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(partvals > entries) goto errout;
2568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      dim--;
2578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    info->partvals = partvals;
2598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
2608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(info);
2628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels errout:
2638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  res0_free_info(info);
2648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(NULL);
2658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
2668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsvorbis_look_residue *res0_look(vorbis_dsp_state *vd,
2688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                               vorbis_info_residue *vr){
2698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
2708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look));
2718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  codec_setup_info     *ci=vd->vi->codec_setup;
2728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int j,k,acc=0;
2748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int dim;
2758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int maxstage=0;
2768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->info=info;
2778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->parts=info->partitions;
2798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->fullbooks=ci->fullbooks;
2808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->phrasebook=ci->fullbooks+info->groupbook;
2818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  dim=look->phrasebook->dim;
2828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
2848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
2858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<look->parts;j++){
2868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int stages=ilog(info->secondstages[j]);
2878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(stages){
2888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(stages>maxstage)maxstage=stages;
2898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
2908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<stages;k++)
2918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(info->secondstages[j]&(1<<k)){
2928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
2938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RES
2948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries,
2958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                           sizeof(***look->training_data));
2968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
2978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
2988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
2998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->partvals=1;
3028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<dim;j++)
3038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      look->partvals*=look->parts;
3048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->stages=maxstage;
3068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap));
3078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(j=0;j<look->partvals;j++){
3088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long val=j;
3098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long mult=look->partvals/look->parts;
3108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j]));
3118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(k=0;k<dim;k++){
3128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      long deco=val/mult;
3138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      val-=deco*mult;
3148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      mult/=look->parts;
3158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      look->decodemap[j][k]=deco;
3168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
3198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
3208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    static int train_seq=0;
3218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    look->train_seq=train_seq++;
3228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
3248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(look);
3258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* break an abstraction and copy some code for performance purposes */
3288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int local_book_besterror(codebook *book,int *a){
3298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int dim=book->dim;
3308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,j,o;
3318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int minval=book->minval;
3328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int del=book->delta;
3338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int qv=book->quantvals;
3348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int ze=(qv>>1);
3358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int index=0;
3368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
3378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int p[8]={0,0,0,0,0,0,0,0};
3388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(del!=1){
3408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0,o=dim;i<dim;i++){
3418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int v = (a[--o]-minval+(del>>1))/del;
3428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
3438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
3448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      p[o]=v*del+minval;
3458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
3478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0,o=dim;i<dim;i++){
3488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int v = a[--o]-minval;
3498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
3508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
3518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      p[o]=v*del+minval;
3528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(book->c->lengthlist[index]<=0){
3568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    const static_codebook *c=book->c;
3578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int best=-1;
3588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
3598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int e[8]={0,0,0,0,0,0,0,0};
3608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int maxval = book->minval + book->delta*(book->quantvals-1);
3618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<book->entries;i++){
3628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(c->lengthlist[i]>0){
3638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        int this=0;
3648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(j=0;j<dim;j++){
3658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int val=(e[j]-a[j]);
3668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          this+=val*val;
3678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
3688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(best==-1 || this<best){
3698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          memcpy(p,e,sizeof(p));
3708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          best=this;
3718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          index=i;
3728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
3738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
3748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* assumes the value patterning created by the tools in vq/ */
3758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      j=0;
3768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      while(e[j]>=maxval)
3778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        e[j++]=0;
3788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(e[j]>=0)
3798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        e[j]+=book->delta;
3808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      e[j]= -e[j];
3818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
3828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(index>-1){
3858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<dim;i++)
3868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      *a++ -= p[i];
3878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
3888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(index);
3908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
3918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int _encodepart(oggpack_buffer *opb,int *vec, int n,
3938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       codebook *book,long *acc){
3948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,bits=0;
3958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int dim=book->dim;
3968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int step=n/dim;
3978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
3988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<step;i++){
3998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int entry=local_book_besterror(book,vec+i*dim);
4008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RES
4028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(entry>=0)
4038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      acc[entry]++;
4048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
4058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    bits+=vorbis_book_encode(book,entry,opb);
4078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(bits);
4118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
4148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                       int **in,int ch){
4158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j,k;
4168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
4178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=look->info;
4188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* move all this setup out later */
4208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int samples_per_partition=info->grouping;
4218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int possible_partitions=info->partitions;
4228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=info->end-info->begin;
4238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int partvals=n/samples_per_partition;
4258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword));
4268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  float scale=100./samples_per_partition;
4278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* we find the partition type for each partition of each
4298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     channel.  We'll go back and do the interleaved encoding in a
4308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     bit.  For now, clarity */
4318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++){
4338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i]));
4348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i]));
4358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<partvals;i++){
4388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int offset=i*samples_per_partition+info->begin;
4398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<ch;j++){
4408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int max=0;
4418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      int ent=0;
4428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<samples_per_partition;k++){
4438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]);
4448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        ent+=abs(in[j][offset+k]);
4458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
4468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      ent*=scale;
4478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<possible_partitions-1;k++)
4498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(max<=info->classmetric1[k] &&
4508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels           (info->classmetric2[k]<0 || ent<info->classmetric2[k]))
4518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          break;
4528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      partword[j][i]=k;
4548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RESAUX
4588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  {
4598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    FILE *of;
4608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    char buffer[80];
4618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<ch;i++){
4638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      sprintf(buffer,"resaux_%d.vqd",look->train_seq);
4648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      of=fopen(buffer,"a");
4658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(j=0;j<partvals;j++)
4668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        fprintf(of,"%ld, ",partword[i][j]);
4678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fprintf(of,"\n");
4688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      fclose(of);
4698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
4708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
4718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
4728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->frames++;
4738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(partword);
4758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
4768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* designed for stereo or other modes where the partition size is an
4788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   integer multiple of the number of channels encoded in the current
4798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   submap */
4808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in,
4818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      int ch){
4828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j,k,l;
4838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
4848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=look->info;
4858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* move all this setup out later */
4878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int samples_per_partition=info->grouping;
4888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int possible_partitions=info->partitions;
4898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=info->end-info->begin;
4908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int partvals=n/samples_per_partition;
4928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long **partword=_vorbis_block_alloc(vb,sizeof(*partword));
4938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
4958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  FILE *of;
4968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  char buffer[80];
4978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
4988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
4998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0]));
5008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(partword[0],0,partvals*sizeof(*partword[0]));
5018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0,l=info->begin/ch;i<partvals;i++){
5038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int magmax=0;
5048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int angmax=0;
5058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<samples_per_partition;j+=ch){
5068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(abs(in[0][l])>magmax)magmax=abs(in[0][l]);
5078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=1;k<ch;k++)
5088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(abs(in[k][l])>angmax)angmax=abs(in[k][l]);
5098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      l++;
5108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<possible_partitions-1;j++)
5138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(magmax<=info->classmetric1[j] &&
5148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         angmax<=info->classmetric2[j])
5158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        break;
5168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    partword[0][i]=j;
5188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
5208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RESAUX
5228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  sprintf(buffer,"resaux_%d.vqd",look->train_seq);
5238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  of=fopen(buffer,"a");
5248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<partvals;i++)
5258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(of,"%ld, ",partword[0][i]);
5268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fprintf(of,"\n");
5278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  fclose(of);
5288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
5298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->frames++;
5318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(partword);
5338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
5348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int _01forward(oggpack_buffer *opb,
5368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      vorbis_block *vb,vorbis_look_residue *vl,
5378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      int **in,int ch,
5388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      long **partword,
5398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      int (*encode)(oggpack_buffer *,int *,int,
5408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                    codebook *,long *),
5418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      int submap){
5428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j,k,s;
5438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
5448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=look->info;
5458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RES
5478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  look->submap=submap;
5488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
5498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* move all this setup out later */
5518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int samples_per_partition=info->grouping;
5528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int possible_partitions=info->partitions;
5538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int partitions_per_word=look->phrasebook->dim;
5548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=info->end-info->begin;
5558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int partvals=n/samples_per_partition;
5578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long resbits[128];
5588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long resvals[128];
5598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RES
5618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++)
5628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=info->begin;j<info->end;j++){
5638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(in[i][j]>look->tmax)look->tmax=in[i][j];
5648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(in[i][j]<look->tmin)look->tmin=in[i][j];
5658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
5668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
5678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(resbits,0,sizeof(resbits));
5698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  memset(resvals,0,sizeof(resvals));
5708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* we code the partition words for each channel, then the residual
5728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     words for a partition per channel until we've written all the
5738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     residual words for that partition word.  Then write the next
5748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     partition channel words... */
5758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(s=0;s<look->stages;s++){
5778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<partvals;){
5798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* first we encode a partition codeword for each channel */
5818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      if(s==0){
5828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(j=0;j<ch;j++){
5838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          long val=partword[j][i];
5848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(k=1;k<partitions_per_word;k++){
5858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            val*=possible_partitions;
5868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(i+k<partvals)
5878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              val+=partword[j][i+k];
5888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
5898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* training hack */
5918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(val<look->phrasebook->entries)
5928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb);
5938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#if 0 /*def TRAIN_RES*/
5948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          else
5958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            fprintf(stderr,"!");
5968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
5978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
5988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
5998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
6008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* now we encode interleaved residual values for the partitions */
6028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
6038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        long offset=i*samples_per_partition+info->begin;
6048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(j=0;j<ch;j++){
6068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(s==0)resvals[partword[j][i]]+=samples_per_partition;
6078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(info->secondstages[partword[j][i]]&(1<<s)){
6088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            codebook *statebook=look->partbooks[partword[j][i]][s];
6098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(statebook){
6108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              int ret;
6118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              long *accumulator=NULL;
6128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#ifdef TRAIN_RES
6148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              accumulator=look->training_data[s][partword[j][i]];
6158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              {
6168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                int l;
6178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                int *samples=in[j]+offset;
6188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                for(l=0;l<samples_per_partition;l++){
6198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  if(samples[l]<look->training_min[s][partword[j][i]])
6208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    look->training_min[s][partword[j][i]]=samples[l];
6218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  if(samples[l]>look->training_max[s][partword[j][i]])
6228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                    look->training_max[s][partword[j][i]]=samples[l];
6238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                }
6248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              }
6258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels#endif
6268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              ret=encode(opb,in[j]+offset,samples_per_partition,
6288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                         statebook,accumulator);
6298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              look->postbits+=ret;
6318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              resbits[partword[j][i]]+=ret;
6328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
6338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
6348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
6358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
6368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
6378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
6388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /*{
6408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long total=0;
6418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    long totalbits=0;
6428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"%d :: ",vb->mode);
6438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(k=0;k<possible_partitions;k++){
6448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
6458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    total+=resvals[k];
6468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    totalbits+=resbits[k];
6478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
6488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
6508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }*/
6518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
6538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
6548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* a truncated packet here just means 'stop working'; it's not an error */
6568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsstatic int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
6578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      float **in,int ch,
6588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                      long (*decodepart)(codebook *, float *,
6598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                         oggpack_buffer *,int)){
6608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j,k,l,s;
6628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
6638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=look->info;
6648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* move all this setup out later */
6668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int samples_per_partition=info->grouping;
6678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int partitions_per_word=look->phrasebook->dim;
6688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int max=vb->pcmend>>1;
6698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int end=(info->end<max?info->end:max);
6708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=end-info->begin;
6718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(n>0){
6738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int partvals=n/samples_per_partition;
6748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
6758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int ***partword=alloca(ch*sizeof(*partword));
6768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0;j<ch;j++)
6788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
6798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(s=0;s<look->stages;s++){
6818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      /* each loop decodes on partition codeword containing
6838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels         partitions_per_word partitions */
6848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0,l=0;i<partvals;l++){
6858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(s==0){
6868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* fetch the partition word for each channel */
6878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(j=0;j<ch;j++){
6888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
6898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(temp==-1 || temp>=info->partvals)goto eopbreak;
6918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            partword[j][l]=look->decodemap[temp];
6928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(partword[j][l]==NULL)goto errout;
6938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
6948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
6958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
6968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* now we decode residual values for the partitions */
6978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
6988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          for(j=0;j<ch;j++){
6998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            long offset=info->begin+i*samples_per_partition;
7008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(info->secondstages[partword[j][l][k]]&(1<<s)){
7018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              codebook *stagebook=look->partbooks[partword[j][l][k]][s];
7028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              if(stagebook){
7038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                if(decodepart(stagebook,in[j]+offset,&vb->opb,
7048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                              samples_per_partition)==-1)goto eopbreak;
7058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              }
7068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
7078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
7088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
7098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
7108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels errout:
7128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels eopbreak:
7138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
7148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
7178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                 float **in,int *nonzero,int ch){
7188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,used=0;
7198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++)
7208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(nonzero[i])
7218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      in[used++]=in[i];
7228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(used)
7238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
7248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  else
7258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
7268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
7298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                 int **in,int *nonzero,int ch, long **partword, int submap){
7308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,used=0;
7318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++)
7328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(nonzero[i])
7338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      in[used++]=in[i];
7348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(used){
7368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return _01forward(opb,vb,vl,in,used,partword,_encodepart,submap);
7378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
7388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
7398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelslong **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
7438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  int **in,int *nonzero,int ch){
7448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,used=0;
7458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++)
7468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(nonzero[i])
7478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      in[used++]=in[i];
7488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(used)
7498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(_01class(vb,vl,in,used));
7508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  else
7518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
7528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
7558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                 float **in,int *nonzero,int ch){
7568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,used=0;
7578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++)
7588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(nonzero[i])
7598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      in[used++]=in[i];
7608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(used)
7618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
7628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  else
7638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
7648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelslong **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
7678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                  int **in,int *nonzero,int ch){
7688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int i,used=0;
7698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++)
7708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(nonzero[i])used++;
7718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(used)
7728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(_2class(vb,vl,in,ch));
7738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  else
7748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
7758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
7768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* res2 is slightly more different; all the channels are interleaved
7788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels   into a single vector and encoded. */
7798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint res2_forward(oggpack_buffer *opb,
7818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                 vorbis_block *vb,vorbis_look_residue *vl,
7828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                 int **in,int *nonzero,int ch, long **partword,int submap){
7838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,j,k,n=vb->pcmend/2,used=0;
7848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* don't duplicate the code; use a working vector hack for now and
7868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels     reshape ourselves into a single channel res1 */
7878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* ugly; reallocs for each coupling pass :-( */
7888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work));
7898e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  for(i=0;i<ch;i++){
7908e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int *pcm=in[i];
7918e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(nonzero[i])used++;
7928e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(j=0,k=i;j<n;j++,k+=ch)
7938e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      work[k]=pcm[j];
7948e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
7958e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
7968e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(used){
7978e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return _01forward(opb,vb,vl,&work,1,partword,_encodepart,submap);
7988e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }else{
7998e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    return(0);
8008e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8018e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
8028e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8038e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels/* duplicate code here as speed is somewhat more important */
8048e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsint res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
8058e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                 float **in,int *nonzero,int ch){
8068e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  long i,k,l,s;
8078e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
8088e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  vorbis_info_residue0 *info=look->info;
8098e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8108e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  /* move all this setup out later */
8118e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int samples_per_partition=info->grouping;
8128e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int partitions_per_word=look->phrasebook->dim;
8138e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int max=(vb->pcmend*ch)>>1;
8148e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int end=(info->end<max?info->end:max);
8158e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  int n=end-info->begin;
8168e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8178e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  if(n>0){
8188e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int partvals=n/samples_per_partition;
8198e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
8208e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword));
8218e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8228e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(i=0;i<ch;i++)if(nonzero[i])break;
8238e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    if(i==ch)return(0); /* no nonzero vectors */
8248e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8258e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    for(s=0;s<look->stages;s++){
8268e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      for(i=0,l=0;i<partvals;l++){
8278e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8288e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        if(s==0){
8298e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          /* fetch the partition word */
8308e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
8318e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(temp==-1 || temp>info->partvals)goto eopbreak;
8328e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          partword[l]=look->decodemap[temp];
8338e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(partword[l]==NULL)goto errout;
8348e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        }
8358e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8368e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        /* now we decode residual values for the partitions */
8378e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
8388e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          if(info->secondstages[partword[l][k]]&(1<<s)){
8398e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            codebook *stagebook=look->partbooks[partword[l][k]][s];
8408e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8418e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            if(stagebook){
8428e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels              if(vorbis_book_decodevv_add(stagebook,in,
8438e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          i*samples_per_partition+info->begin,ch,
8448e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                                          &vb->opb,samples_per_partition)==-1)
8458e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels                goto eopbreak;
8468e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels            }
8478e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels          }
8488e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels      }
8498e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels    }
8508e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  }
8518e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels errout:
8528e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels eopbreak:
8538e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  return(0);
8548e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels}
8558e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8568e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8578e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsconst vorbis_func_residue residue0_exportbundle={
8588e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  NULL,
8598e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_unpack,
8608e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_look,
8618e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_free_info,
8628e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_free_look,
8638e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  NULL,
8648e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  NULL,
8658e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_inverse
8668e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
8678e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8688e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsconst vorbis_func_residue residue1_exportbundle={
8698e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_pack,
8708e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_unpack,
8718e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_look,
8728e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_free_info,
8738e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_free_look,
8748e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res1_class,
8758e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res1_forward,
8768e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res1_inverse
8778e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
8788e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels
8798e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckelsconst vorbis_func_residue residue2_exportbundle={
8808e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_pack,
8818e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_unpack,
8828e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_look,
8838e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_free_info,
8848e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res0_free_look,
8858e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res2_class,
8868e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res2_forward,
8878e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels  &res2_inverse
8888e01cdce135d5d816f92d7bb83f9a930aa1b45aeLucas Eckels};
889