vrshoot

diff libs/vorbis/res0.c @ 0:b2f14e535253

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 01 Feb 2014 19:58:19 +0200
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/libs/vorbis/res0.c	Sat Feb 01 19:58:19 2014 +0200
     1.3 @@ -0,0 +1,889 @@
     1.4 +/********************************************************************
     1.5 + *                                                                  *
     1.6 + * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
     1.7 + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
     1.8 + * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
     1.9 + * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
    1.10 + *                                                                  *
    1.11 + * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010             *
    1.12 + * by the Xiph.Org Foundation http://www.xiph.org/                  *
    1.13 + *                                                                  *
    1.14 + ********************************************************************
    1.15 +
    1.16 + function: residue backend 0, 1 and 2 implementation
    1.17 + last mod: $Id: res0.c 17556 2010-10-21 18:25:19Z tterribe $
    1.18 +
    1.19 + ********************************************************************/
    1.20 +
    1.21 +/* Slow, slow, slow, simpleminded and did I mention it was slow?  The
    1.22 +   encode/decode loops are coded for clarity and performance is not
    1.23 +   yet even a nagging little idea lurking in the shadows.  Oh and BTW,
    1.24 +   it's slow. */
    1.25 +
    1.26 +#include <stdlib.h>
    1.27 +#include <string.h>
    1.28 +#include <math.h>
    1.29 +#include <ogg/ogg.h>
    1.30 +#include "vorbis/codec.h"
    1.31 +#include "codec_internal.h"
    1.32 +#include "registry.h"
    1.33 +#include "codebook.h"
    1.34 +#include "misc.h"
    1.35 +#include "os.h"
    1.36 +
    1.37 +/*#define TRAIN_RES 1*/
    1.38 +/*#define TRAIN_RESAUX 1*/
    1.39 +
    1.40 +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
    1.41 +#include <stdio.h>
    1.42 +#endif
    1.43 +
    1.44 +typedef struct {
    1.45 +  vorbis_info_residue0 *info;
    1.46 +
    1.47 +  int         parts;
    1.48 +  int         stages;
    1.49 +  codebook   *fullbooks;
    1.50 +  codebook   *phrasebook;
    1.51 +  codebook ***partbooks;
    1.52 +
    1.53 +  int         partvals;
    1.54 +  int       **decodemap;
    1.55 +
    1.56 +  long      postbits;
    1.57 +  long      phrasebits;
    1.58 +  long      frames;
    1.59 +
    1.60 +#if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
    1.61 +  int        train_seq;
    1.62 +  long      *training_data[8][64];
    1.63 +  float      training_max[8][64];
    1.64 +  float      training_min[8][64];
    1.65 +  float     tmin;
    1.66 +  float     tmax;
    1.67 +  int       submap;
    1.68 +#endif
    1.69 +
    1.70 +} vorbis_look_residue0;
    1.71 +
    1.72 +void res0_free_info(vorbis_info_residue *i){
    1.73 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
    1.74 +  if(info){
    1.75 +    memset(info,0,sizeof(*info));
    1.76 +    _ogg_free(info);
    1.77 +  }
    1.78 +}
    1.79 +
    1.80 +void res0_free_look(vorbis_look_residue *i){
    1.81 +  int j;
    1.82 +  if(i){
    1.83 +
    1.84 +    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
    1.85 +
    1.86 +#ifdef TRAIN_RES
    1.87 +    {
    1.88 +      int j,k,l;
    1.89 +      for(j=0;j<look->parts;j++){
    1.90 +        /*fprintf(stderr,"partition %d: ",j);*/
    1.91 +        for(k=0;k<8;k++)
    1.92 +          if(look->training_data[k][j]){
    1.93 +            char buffer[80];
    1.94 +            FILE *of;
    1.95 +            codebook *statebook=look->partbooks[j][k];
    1.96 +
    1.97 +            /* long and short into the same bucket by current convention */
    1.98 +            sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k);
    1.99 +            of=fopen(buffer,"a");
   1.100 +
   1.101 +            for(l=0;l<statebook->entries;l++)
   1.102 +              fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]);
   1.103 +
   1.104 +            fclose(of);
   1.105 +
   1.106 +            /*fprintf(stderr,"%d(%.2f|%.2f) ",k,
   1.107 +              look->training_min[k][j],look->training_max[k][j]);*/
   1.108 +
   1.109 +            _ogg_free(look->training_data[k][j]);
   1.110 +            look->training_data[k][j]=NULL;
   1.111 +          }
   1.112 +        /*fprintf(stderr,"\n");*/
   1.113 +      }
   1.114 +    }
   1.115 +    fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax);
   1.116 +
   1.117 +    /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
   1.118 +            (float)look->phrasebits/look->frames,
   1.119 +            (float)look->postbits/look->frames,
   1.120 +            (float)(look->postbits+look->phrasebits)/look->frames);*/
   1.121 +#endif
   1.122 +
   1.123 +
   1.124 +    /*vorbis_info_residue0 *info=look->info;
   1.125 +
   1.126 +    fprintf(stderr,
   1.127 +            "%ld frames encoded in %ld phrasebits and %ld residue bits "
   1.128 +            "(%g/frame) \n",look->frames,look->phrasebits,
   1.129 +            look->resbitsflat,
   1.130 +            (look->phrasebits+look->resbitsflat)/(float)look->frames);
   1.131 +
   1.132 +    for(j=0;j<look->parts;j++){
   1.133 +      long acc=0;
   1.134 +      fprintf(stderr,"\t[%d] == ",j);
   1.135 +      for(k=0;k<look->stages;k++)
   1.136 +        if((info->secondstages[j]>>k)&1){
   1.137 +          fprintf(stderr,"%ld,",look->resbits[j][k]);
   1.138 +          acc+=look->resbits[j][k];
   1.139 +        }
   1.140 +
   1.141 +      fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
   1.142 +              acc?(float)acc/(look->resvals[j]*info->grouping):0);
   1.143 +    }
   1.144 +    fprintf(stderr,"\n");*/
   1.145 +
   1.146 +    for(j=0;j<look->parts;j++)
   1.147 +      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
   1.148 +    _ogg_free(look->partbooks);
   1.149 +    for(j=0;j<look->partvals;j++)
   1.150 +      _ogg_free(look->decodemap[j]);
   1.151 +    _ogg_free(look->decodemap);
   1.152 +
   1.153 +    memset(look,0,sizeof(*look));
   1.154 +    _ogg_free(look);
   1.155 +  }
   1.156 +}
   1.157 +
   1.158 +static int ilog(unsigned int v){
   1.159 +  int ret=0;
   1.160 +  while(v){
   1.161 +    ret++;
   1.162 +    v>>=1;
   1.163 +  }
   1.164 +  return(ret);
   1.165 +}
   1.166 +
   1.167 +static int icount(unsigned int v){
   1.168 +  int ret=0;
   1.169 +  while(v){
   1.170 +    ret+=v&1;
   1.171 +    v>>=1;
   1.172 +  }
   1.173 +  return(ret);
   1.174 +}
   1.175 +
   1.176 +
   1.177 +void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
   1.178 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
   1.179 +  int j,acc=0;
   1.180 +  oggpack_write(opb,info->begin,24);
   1.181 +  oggpack_write(opb,info->end,24);
   1.182 +
   1.183 +  oggpack_write(opb,info->grouping-1,24);  /* residue vectors to group and
   1.184 +                                             code with a partitioned book */
   1.185 +  oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
   1.186 +  oggpack_write(opb,info->groupbook,8);  /* group huffman book */
   1.187 +
   1.188 +  /* secondstages is a bitmask; as encoding progresses pass by pass, a
   1.189 +     bitmask of one indicates this partition class has bits to write
   1.190 +     this pass */
   1.191 +  for(j=0;j<info->partitions;j++){
   1.192 +    if(ilog(info->secondstages[j])>3){
   1.193 +      /* yes, this is a minor hack due to not thinking ahead */
   1.194 +      oggpack_write(opb,info->secondstages[j],3);
   1.195 +      oggpack_write(opb,1,1);
   1.196 +      oggpack_write(opb,info->secondstages[j]>>3,5);
   1.197 +    }else
   1.198 +      oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
   1.199 +    acc+=icount(info->secondstages[j]);
   1.200 +  }
   1.201 +  for(j=0;j<acc;j++)
   1.202 +    oggpack_write(opb,info->booklist[j],8);
   1.203 +
   1.204 +}
   1.205 +
   1.206 +/* vorbis_info is for range checking */
   1.207 +vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
   1.208 +  int j,acc=0;
   1.209 +  vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info));
   1.210 +  codec_setup_info     *ci=vi->codec_setup;
   1.211 +
   1.212 +  info->begin=oggpack_read(opb,24);
   1.213 +  info->end=oggpack_read(opb,24);
   1.214 +  info->grouping=oggpack_read(opb,24)+1;
   1.215 +  info->partitions=oggpack_read(opb,6)+1;
   1.216 +  info->groupbook=oggpack_read(opb,8);
   1.217 +
   1.218 +  /* check for premature EOP */
   1.219 +  if(info->groupbook<0)goto errout;
   1.220 +
   1.221 +  for(j=0;j<info->partitions;j++){
   1.222 +    int cascade=oggpack_read(opb,3);
   1.223 +    int cflag=oggpack_read(opb,1);
   1.224 +    if(cflag<0) goto errout;
   1.225 +    if(cflag){
   1.226 +      int c=oggpack_read(opb,5);
   1.227 +      if(c<0) goto errout;
   1.228 +      cascade|=(c<<3);
   1.229 +    }
   1.230 +    info->secondstages[j]=cascade;
   1.231 +
   1.232 +    acc+=icount(cascade);
   1.233 +  }
   1.234 +  for(j=0;j<acc;j++){
   1.235 +    int book=oggpack_read(opb,8);
   1.236 +    if(book<0) goto errout;
   1.237 +    info->booklist[j]=book;
   1.238 +  }
   1.239 +
   1.240 +  if(info->groupbook>=ci->books)goto errout;
   1.241 +  for(j=0;j<acc;j++){
   1.242 +    if(info->booklist[j]>=ci->books)goto errout;
   1.243 +    if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
   1.244 +  }
   1.245 +
   1.246 +  /* verify the phrasebook is not specifying an impossible or
   1.247 +     inconsistent partitioning scheme. */
   1.248 +  /* modify the phrasebook ranging check from r16327; an early beta
   1.249 +     encoder had a bug where it used an oversized phrasebook by
   1.250 +     accident.  These files should continue to be playable, but don't
   1.251 +     allow an exploit */
   1.252 +  {
   1.253 +    int entries = ci->book_param[info->groupbook]->entries;
   1.254 +    int dim = ci->book_param[info->groupbook]->dim;
   1.255 +    int partvals = 1;
   1.256 +    if (dim<1) goto errout;
   1.257 +    while(dim>0){
   1.258 +      partvals *= info->partitions;
   1.259 +      if(partvals > entries) goto errout;
   1.260 +      dim--;
   1.261 +    }
   1.262 +    info->partvals = partvals;
   1.263 +  }
   1.264 +
   1.265 +  return(info);
   1.266 + errout:
   1.267 +  res0_free_info(info);
   1.268 +  return(NULL);
   1.269 +}
   1.270 +
   1.271 +vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
   1.272 +                               vorbis_info_residue *vr){
   1.273 +  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
   1.274 +  vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look));
   1.275 +  codec_setup_info     *ci=vd->vi->codec_setup;
   1.276 +
   1.277 +  int j,k,acc=0;
   1.278 +  int dim;
   1.279 +  int maxstage=0;
   1.280 +  look->info=info;
   1.281 +
   1.282 +  look->parts=info->partitions;
   1.283 +  look->fullbooks=ci->fullbooks;
   1.284 +  look->phrasebook=ci->fullbooks+info->groupbook;
   1.285 +  dim=look->phrasebook->dim;
   1.286 +
   1.287 +  look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
   1.288 +
   1.289 +  for(j=0;j<look->parts;j++){
   1.290 +    int stages=ilog(info->secondstages[j]);
   1.291 +    if(stages){
   1.292 +      if(stages>maxstage)maxstage=stages;
   1.293 +      look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
   1.294 +      for(k=0;k<stages;k++)
   1.295 +        if(info->secondstages[j]&(1<<k)){
   1.296 +          look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
   1.297 +#ifdef TRAIN_RES
   1.298 +          look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries,
   1.299 +                                           sizeof(***look->training_data));
   1.300 +#endif
   1.301 +        }
   1.302 +    }
   1.303 +  }
   1.304 +
   1.305 +  look->partvals=1;
   1.306 +  for(j=0;j<dim;j++)
   1.307 +      look->partvals*=look->parts;
   1.308 +
   1.309 +  look->stages=maxstage;
   1.310 +  look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap));
   1.311 +  for(j=0;j<look->partvals;j++){
   1.312 +    long val=j;
   1.313 +    long mult=look->partvals/look->parts;
   1.314 +    look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j]));
   1.315 +    for(k=0;k<dim;k++){
   1.316 +      long deco=val/mult;
   1.317 +      val-=deco*mult;
   1.318 +      mult/=look->parts;
   1.319 +      look->decodemap[j][k]=deco;
   1.320 +    }
   1.321 +  }
   1.322 +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
   1.323 +  {
   1.324 +    static int train_seq=0;
   1.325 +    look->train_seq=train_seq++;
   1.326 +  }
   1.327 +#endif
   1.328 +  return(look);
   1.329 +}
   1.330 +
   1.331 +/* break an abstraction and copy some code for performance purposes */
   1.332 +static int local_book_besterror(codebook *book,int *a){
   1.333 +  int dim=book->dim;
   1.334 +  int i,j,o;
   1.335 +  int minval=book->minval;
   1.336 +  int del=book->delta;
   1.337 +  int qv=book->quantvals;
   1.338 +  int ze=(qv>>1);
   1.339 +  int index=0;
   1.340 +  /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
   1.341 +  int p[8]={0,0,0,0,0,0,0,0};
   1.342 +
   1.343 +  if(del!=1){
   1.344 +    for(i=0,o=dim;i<dim;i++){
   1.345 +      int v = (a[--o]-minval+(del>>1))/del;
   1.346 +      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
   1.347 +      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
   1.348 +      p[o]=v*del+minval;
   1.349 +    }
   1.350 +  }else{
   1.351 +    for(i=0,o=dim;i<dim;i++){
   1.352 +      int v = a[--o]-minval;
   1.353 +      int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
   1.354 +      index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
   1.355 +      p[o]=v*del+minval;
   1.356 +    }
   1.357 +  }
   1.358 +
   1.359 +  if(book->c->lengthlist[index]<=0){
   1.360 +    const static_codebook *c=book->c;
   1.361 +    int best=-1;
   1.362 +    /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
   1.363 +    int e[8]={0,0,0,0,0,0,0,0};
   1.364 +    int maxval = book->minval + book->delta*(book->quantvals-1);
   1.365 +    for(i=0;i<book->entries;i++){
   1.366 +      if(c->lengthlist[i]>0){
   1.367 +        int this=0;
   1.368 +        for(j=0;j<dim;j++){
   1.369 +          int val=(e[j]-a[j]);
   1.370 +          this+=val*val;
   1.371 +        }
   1.372 +        if(best==-1 || this<best){
   1.373 +          memcpy(p,e,sizeof(p));
   1.374 +          best=this;
   1.375 +          index=i;
   1.376 +        }
   1.377 +      }
   1.378 +      /* assumes the value patterning created by the tools in vq/ */
   1.379 +      j=0;
   1.380 +      while(e[j]>=maxval)
   1.381 +        e[j++]=0;
   1.382 +      if(e[j]>=0)
   1.383 +        e[j]+=book->delta;
   1.384 +      e[j]= -e[j];
   1.385 +    }
   1.386 +  }
   1.387 +
   1.388 +  if(index>-1){
   1.389 +    for(i=0;i<dim;i++)
   1.390 +      *a++ -= p[i];
   1.391 +  }
   1.392 +
   1.393 +  return(index);
   1.394 +}
   1.395 +
   1.396 +static int _encodepart(oggpack_buffer *opb,int *vec, int n,
   1.397 +                       codebook *book,long *acc){
   1.398 +  int i,bits=0;
   1.399 +  int dim=book->dim;
   1.400 +  int step=n/dim;
   1.401 +
   1.402 +  for(i=0;i<step;i++){
   1.403 +    int entry=local_book_besterror(book,vec+i*dim);
   1.404 +
   1.405 +#ifdef TRAIN_RES
   1.406 +    if(entry>=0)
   1.407 +      acc[entry]++;
   1.408 +#endif
   1.409 +
   1.410 +    bits+=vorbis_book_encode(book,entry,opb);
   1.411 +
   1.412 +  }
   1.413 +
   1.414 +  return(bits);
   1.415 +}
   1.416 +
   1.417 +static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
   1.418 +                       int **in,int ch){
   1.419 +  long i,j,k;
   1.420 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.421 +  vorbis_info_residue0 *info=look->info;
   1.422 +
   1.423 +  /* move all this setup out later */
   1.424 +  int samples_per_partition=info->grouping;
   1.425 +  int possible_partitions=info->partitions;
   1.426 +  int n=info->end-info->begin;
   1.427 +
   1.428 +  int partvals=n/samples_per_partition;
   1.429 +  long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword));
   1.430 +  float scale=100./samples_per_partition;
   1.431 +
   1.432 +  /* we find the partition type for each partition of each
   1.433 +     channel.  We'll go back and do the interleaved encoding in a
   1.434 +     bit.  For now, clarity */
   1.435 +
   1.436 +  for(i=0;i<ch;i++){
   1.437 +    partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i]));
   1.438 +    memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i]));
   1.439 +  }
   1.440 +
   1.441 +  for(i=0;i<partvals;i++){
   1.442 +    int offset=i*samples_per_partition+info->begin;
   1.443 +    for(j=0;j<ch;j++){
   1.444 +      int max=0;
   1.445 +      int ent=0;
   1.446 +      for(k=0;k<samples_per_partition;k++){
   1.447 +        if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]);
   1.448 +        ent+=abs(in[j][offset+k]);
   1.449 +      }
   1.450 +      ent*=scale;
   1.451 +
   1.452 +      for(k=0;k<possible_partitions-1;k++)
   1.453 +        if(max<=info->classmetric1[k] &&
   1.454 +           (info->classmetric2[k]<0 || ent<info->classmetric2[k]))
   1.455 +          break;
   1.456 +
   1.457 +      partword[j][i]=k;
   1.458 +    }
   1.459 +  }
   1.460 +
   1.461 +#ifdef TRAIN_RESAUX
   1.462 +  {
   1.463 +    FILE *of;
   1.464 +    char buffer[80];
   1.465 +
   1.466 +    for(i=0;i<ch;i++){
   1.467 +      sprintf(buffer,"resaux_%d.vqd",look->train_seq);
   1.468 +      of=fopen(buffer,"a");
   1.469 +      for(j=0;j<partvals;j++)
   1.470 +        fprintf(of,"%ld, ",partword[i][j]);
   1.471 +      fprintf(of,"\n");
   1.472 +      fclose(of);
   1.473 +    }
   1.474 +  }
   1.475 +#endif
   1.476 +  look->frames++;
   1.477 +
   1.478 +  return(partword);
   1.479 +}
   1.480 +
   1.481 +/* designed for stereo or other modes where the partition size is an
   1.482 +   integer multiple of the number of channels encoded in the current
   1.483 +   submap */
   1.484 +static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in,
   1.485 +                      int ch){
   1.486 +  long i,j,k,l;
   1.487 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.488 +  vorbis_info_residue0 *info=look->info;
   1.489 +
   1.490 +  /* move all this setup out later */
   1.491 +  int samples_per_partition=info->grouping;
   1.492 +  int possible_partitions=info->partitions;
   1.493 +  int n=info->end-info->begin;
   1.494 +
   1.495 +  int partvals=n/samples_per_partition;
   1.496 +  long **partword=_vorbis_block_alloc(vb,sizeof(*partword));
   1.497 +
   1.498 +#if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
   1.499 +  FILE *of;
   1.500 +  char buffer[80];
   1.501 +#endif
   1.502 +
   1.503 +  partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0]));
   1.504 +  memset(partword[0],0,partvals*sizeof(*partword[0]));
   1.505 +
   1.506 +  for(i=0,l=info->begin/ch;i<partvals;i++){
   1.507 +    int magmax=0;
   1.508 +    int angmax=0;
   1.509 +    for(j=0;j<samples_per_partition;j+=ch){
   1.510 +      if(abs(in[0][l])>magmax)magmax=abs(in[0][l]);
   1.511 +      for(k=1;k<ch;k++)
   1.512 +        if(abs(in[k][l])>angmax)angmax=abs(in[k][l]);
   1.513 +      l++;
   1.514 +    }
   1.515 +
   1.516 +    for(j=0;j<possible_partitions-1;j++)
   1.517 +      if(magmax<=info->classmetric1[j] &&
   1.518 +         angmax<=info->classmetric2[j])
   1.519 +        break;
   1.520 +
   1.521 +    partword[0][i]=j;
   1.522 +
   1.523 +  }
   1.524 +
   1.525 +#ifdef TRAIN_RESAUX
   1.526 +  sprintf(buffer,"resaux_%d.vqd",look->train_seq);
   1.527 +  of=fopen(buffer,"a");
   1.528 +  for(i=0;i<partvals;i++)
   1.529 +    fprintf(of,"%ld, ",partword[0][i]);
   1.530 +  fprintf(of,"\n");
   1.531 +  fclose(of);
   1.532 +#endif
   1.533 +
   1.534 +  look->frames++;
   1.535 +
   1.536 +  return(partword);
   1.537 +}
   1.538 +
   1.539 +static int _01forward(oggpack_buffer *opb,
   1.540 +                      vorbis_block *vb,vorbis_look_residue *vl,
   1.541 +                      int **in,int ch,
   1.542 +                      long **partword,
   1.543 +                      int (*encode)(oggpack_buffer *,int *,int,
   1.544 +                                    codebook *,long *),
   1.545 +                      int submap){
   1.546 +  long i,j,k,s;
   1.547 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.548 +  vorbis_info_residue0 *info=look->info;
   1.549 +
   1.550 +#ifdef TRAIN_RES
   1.551 +  look->submap=submap;
   1.552 +#endif
   1.553 +
   1.554 +  /* move all this setup out later */
   1.555 +  int samples_per_partition=info->grouping;
   1.556 +  int possible_partitions=info->partitions;
   1.557 +  int partitions_per_word=look->phrasebook->dim;
   1.558 +  int n=info->end-info->begin;
   1.559 +
   1.560 +  int partvals=n/samples_per_partition;
   1.561 +  long resbits[128];
   1.562 +  long resvals[128];
   1.563 +
   1.564 +#ifdef TRAIN_RES
   1.565 +  for(i=0;i<ch;i++)
   1.566 +    for(j=info->begin;j<info->end;j++){
   1.567 +      if(in[i][j]>look->tmax)look->tmax=in[i][j];
   1.568 +      if(in[i][j]<look->tmin)look->tmin=in[i][j];
   1.569 +    }
   1.570 +#endif
   1.571 +
   1.572 +  memset(resbits,0,sizeof(resbits));
   1.573 +  memset(resvals,0,sizeof(resvals));
   1.574 +
   1.575 +  /* we code the partition words for each channel, then the residual
   1.576 +     words for a partition per channel until we've written all the
   1.577 +     residual words for that partition word.  Then write the next
   1.578 +     partition channel words... */
   1.579 +
   1.580 +  for(s=0;s<look->stages;s++){
   1.581 +
   1.582 +    for(i=0;i<partvals;){
   1.583 +
   1.584 +      /* first we encode a partition codeword for each channel */
   1.585 +      if(s==0){
   1.586 +        for(j=0;j<ch;j++){
   1.587 +          long val=partword[j][i];
   1.588 +          for(k=1;k<partitions_per_word;k++){
   1.589 +            val*=possible_partitions;
   1.590 +            if(i+k<partvals)
   1.591 +              val+=partword[j][i+k];
   1.592 +          }
   1.593 +
   1.594 +          /* training hack */
   1.595 +          if(val<look->phrasebook->entries)
   1.596 +            look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb);
   1.597 +#if 0 /*def TRAIN_RES*/
   1.598 +          else
   1.599 +            fprintf(stderr,"!");
   1.600 +#endif
   1.601 +
   1.602 +        }
   1.603 +      }
   1.604 +
   1.605 +      /* now we encode interleaved residual values for the partitions */
   1.606 +      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
   1.607 +        long offset=i*samples_per_partition+info->begin;
   1.608 +
   1.609 +        for(j=0;j<ch;j++){
   1.610 +          if(s==0)resvals[partword[j][i]]+=samples_per_partition;
   1.611 +          if(info->secondstages[partword[j][i]]&(1<<s)){
   1.612 +            codebook *statebook=look->partbooks[partword[j][i]][s];
   1.613 +            if(statebook){
   1.614 +              int ret;
   1.615 +              long *accumulator=NULL;
   1.616 +
   1.617 +#ifdef TRAIN_RES
   1.618 +              accumulator=look->training_data[s][partword[j][i]];
   1.619 +              {
   1.620 +                int l;
   1.621 +                int *samples=in[j]+offset;
   1.622 +                for(l=0;l<samples_per_partition;l++){
   1.623 +                  if(samples[l]<look->training_min[s][partword[j][i]])
   1.624 +                    look->training_min[s][partword[j][i]]=samples[l];
   1.625 +                  if(samples[l]>look->training_max[s][partword[j][i]])
   1.626 +                    look->training_max[s][partword[j][i]]=samples[l];
   1.627 +                }
   1.628 +              }
   1.629 +#endif
   1.630 +
   1.631 +              ret=encode(opb,in[j]+offset,samples_per_partition,
   1.632 +                         statebook,accumulator);
   1.633 +
   1.634 +              look->postbits+=ret;
   1.635 +              resbits[partword[j][i]]+=ret;
   1.636 +            }
   1.637 +          }
   1.638 +        }
   1.639 +      }
   1.640 +    }
   1.641 +  }
   1.642 +
   1.643 +  /*{
   1.644 +    long total=0;
   1.645 +    long totalbits=0;
   1.646 +    fprintf(stderr,"%d :: ",vb->mode);
   1.647 +    for(k=0;k<possible_partitions;k++){
   1.648 +    fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
   1.649 +    total+=resvals[k];
   1.650 +    totalbits+=resbits[k];
   1.651 +    }
   1.652 +
   1.653 +    fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
   1.654 +    }*/
   1.655 +
   1.656 +  return(0);
   1.657 +}
   1.658 +
   1.659 +/* a truncated packet here just means 'stop working'; it's not an error */
   1.660 +static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.661 +                      float **in,int ch,
   1.662 +                      long (*decodepart)(codebook *, float *,
   1.663 +                                         oggpack_buffer *,int)){
   1.664 +
   1.665 +  long i,j,k,l,s;
   1.666 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.667 +  vorbis_info_residue0 *info=look->info;
   1.668 +
   1.669 +  /* move all this setup out later */
   1.670 +  int samples_per_partition=info->grouping;
   1.671 +  int partitions_per_word=look->phrasebook->dim;
   1.672 +  int max=vb->pcmend>>1;
   1.673 +  int end=(info->end<max?info->end:max);
   1.674 +  int n=end-info->begin;
   1.675 +
   1.676 +  if(n>0){
   1.677 +    int partvals=n/samples_per_partition;
   1.678 +    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   1.679 +    int ***partword=alloca(ch*sizeof(*partword));
   1.680 +
   1.681 +    for(j=0;j<ch;j++)
   1.682 +      partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
   1.683 +
   1.684 +    for(s=0;s<look->stages;s++){
   1.685 +
   1.686 +      /* each loop decodes on partition codeword containing
   1.687 +         partitions_per_word partitions */
   1.688 +      for(i=0,l=0;i<partvals;l++){
   1.689 +        if(s==0){
   1.690 +          /* fetch the partition word for each channel */
   1.691 +          for(j=0;j<ch;j++){
   1.692 +            int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
   1.693 +
   1.694 +            if(temp==-1 || temp>=info->partvals)goto eopbreak;
   1.695 +            partword[j][l]=look->decodemap[temp];
   1.696 +            if(partword[j][l]==NULL)goto errout;
   1.697 +          }
   1.698 +        }
   1.699 +
   1.700 +        /* now we decode residual values for the partitions */
   1.701 +        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
   1.702 +          for(j=0;j<ch;j++){
   1.703 +            long offset=info->begin+i*samples_per_partition;
   1.704 +            if(info->secondstages[partword[j][l][k]]&(1<<s)){
   1.705 +              codebook *stagebook=look->partbooks[partword[j][l][k]][s];
   1.706 +              if(stagebook){
   1.707 +                if(decodepart(stagebook,in[j]+offset,&vb->opb,
   1.708 +                              samples_per_partition)==-1)goto eopbreak;
   1.709 +              }
   1.710 +            }
   1.711 +          }
   1.712 +      }
   1.713 +    }
   1.714 +  }
   1.715 + errout:
   1.716 + eopbreak:
   1.717 +  return(0);
   1.718 +}
   1.719 +
   1.720 +int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.721 +                 float **in,int *nonzero,int ch){
   1.722 +  int i,used=0;
   1.723 +  for(i=0;i<ch;i++)
   1.724 +    if(nonzero[i])
   1.725 +      in[used++]=in[i];
   1.726 +  if(used)
   1.727 +    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
   1.728 +  else
   1.729 +    return(0);
   1.730 +}
   1.731 +
   1.732 +int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
   1.733 +                 int **in,int *nonzero,int ch, long **partword, int submap){
   1.734 +  int i,used=0;
   1.735 +  for(i=0;i<ch;i++)
   1.736 +    if(nonzero[i])
   1.737 +      in[used++]=in[i];
   1.738 +
   1.739 +  if(used){
   1.740 +    return _01forward(opb,vb,vl,in,used,partword,_encodepart,submap);
   1.741 +  }else{
   1.742 +    return(0);
   1.743 +  }
   1.744 +}
   1.745 +
   1.746 +long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
   1.747 +                  int **in,int *nonzero,int ch){
   1.748 +  int i,used=0;
   1.749 +  for(i=0;i<ch;i++)
   1.750 +    if(nonzero[i])
   1.751 +      in[used++]=in[i];
   1.752 +  if(used)
   1.753 +    return(_01class(vb,vl,in,used));
   1.754 +  else
   1.755 +    return(0);
   1.756 +}
   1.757 +
   1.758 +int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.759 +                 float **in,int *nonzero,int ch){
   1.760 +  int i,used=0;
   1.761 +  for(i=0;i<ch;i++)
   1.762 +    if(nonzero[i])
   1.763 +      in[used++]=in[i];
   1.764 +  if(used)
   1.765 +    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
   1.766 +  else
   1.767 +    return(0);
   1.768 +}
   1.769 +
   1.770 +long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
   1.771 +                  int **in,int *nonzero,int ch){
   1.772 +  int i,used=0;
   1.773 +  for(i=0;i<ch;i++)
   1.774 +    if(nonzero[i])used++;
   1.775 +  if(used)
   1.776 +    return(_2class(vb,vl,in,ch));
   1.777 +  else
   1.778 +    return(0);
   1.779 +}
   1.780 +
   1.781 +/* res2 is slightly more different; all the channels are interleaved
   1.782 +   into a single vector and encoded. */
   1.783 +
   1.784 +int res2_forward(oggpack_buffer *opb,
   1.785 +                 vorbis_block *vb,vorbis_look_residue *vl,
   1.786 +                 int **in,int *nonzero,int ch, long **partword,int submap){
   1.787 +  long i,j,k,n=vb->pcmend/2,used=0;
   1.788 +
   1.789 +  /* don't duplicate the code; use a working vector hack for now and
   1.790 +     reshape ourselves into a single channel res1 */
   1.791 +  /* ugly; reallocs for each coupling pass :-( */
   1.792 +  int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work));
   1.793 +  for(i=0;i<ch;i++){
   1.794 +    int *pcm=in[i];
   1.795 +    if(nonzero[i])used++;
   1.796 +    for(j=0,k=i;j<n;j++,k+=ch)
   1.797 +      work[k]=pcm[j];
   1.798 +  }
   1.799 +
   1.800 +  if(used){
   1.801 +    return _01forward(opb,vb,vl,&work,1,partword,_encodepart,submap);
   1.802 +  }else{
   1.803 +    return(0);
   1.804 +  }
   1.805 +}
   1.806 +
   1.807 +/* duplicate code here as speed is somewhat more important */
   1.808 +int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
   1.809 +                 float **in,int *nonzero,int ch){
   1.810 +  long i,k,l,s;
   1.811 +  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
   1.812 +  vorbis_info_residue0 *info=look->info;
   1.813 +
   1.814 +  /* move all this setup out later */
   1.815 +  int samples_per_partition=info->grouping;
   1.816 +  int partitions_per_word=look->phrasebook->dim;
   1.817 +  int max=(vb->pcmend*ch)>>1;
   1.818 +  int end=(info->end<max?info->end:max);
   1.819 +  int n=end-info->begin;
   1.820 +
   1.821 +  if(n>0){
   1.822 +    int partvals=n/samples_per_partition;
   1.823 +    int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
   1.824 +    int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword));
   1.825 +
   1.826 +    for(i=0;i<ch;i++)if(nonzero[i])break;
   1.827 +    if(i==ch)return(0); /* no nonzero vectors */
   1.828 +
   1.829 +    for(s=0;s<look->stages;s++){
   1.830 +      for(i=0,l=0;i<partvals;l++){
   1.831 +
   1.832 +        if(s==0){
   1.833 +          /* fetch the partition word */
   1.834 +          int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
   1.835 +          if(temp==-1 || temp>=info->partvals)goto eopbreak;
   1.836 +          partword[l]=look->decodemap[temp];
   1.837 +          if(partword[l]==NULL)goto errout;
   1.838 +        }
   1.839 +
   1.840 +        /* now we decode residual values for the partitions */
   1.841 +        for(k=0;k<partitions_per_word && i<partvals;k++,i++)
   1.842 +          if(info->secondstages[partword[l][k]]&(1<<s)){
   1.843 +            codebook *stagebook=look->partbooks[partword[l][k]][s];
   1.844 +
   1.845 +            if(stagebook){
   1.846 +              if(vorbis_book_decodevv_add(stagebook,in,
   1.847 +                                          i*samples_per_partition+info->begin,ch,
   1.848 +                                          &vb->opb,samples_per_partition)==-1)
   1.849 +                goto eopbreak;
   1.850 +            }
   1.851 +          }
   1.852 +      }
   1.853 +    }
   1.854 +  }
   1.855 + errout:
   1.856 + eopbreak:
   1.857 +  return(0);
   1.858 +}
   1.859 +
   1.860 +
   1.861 +const vorbis_func_residue residue0_exportbundle={
   1.862 +  NULL,
   1.863 +  &res0_unpack,
   1.864 +  &res0_look,
   1.865 +  &res0_free_info,
   1.866 +  &res0_free_look,
   1.867 +  NULL,
   1.868 +  NULL,
   1.869 +  &res0_inverse
   1.870 +};
   1.871 +
   1.872 +const vorbis_func_residue residue1_exportbundle={
   1.873 +  &res0_pack,
   1.874 +  &res0_unpack,
   1.875 +  &res0_look,
   1.876 +  &res0_free_info,
   1.877 +  &res0_free_look,
   1.878 +  &res1_class,
   1.879 +  &res1_forward,
   1.880 +  &res1_inverse
   1.881 +};
   1.882 +
   1.883 +const vorbis_func_residue residue2_exportbundle={
   1.884 +  &res0_pack,
   1.885 +  &res0_unpack,
   1.886 +  &res0_look,
   1.887 +  &res0_free_info,
   1.888 +  &res0_free_look,
   1.889 +  &res2_class,
   1.890 +  &res2_forward,
   1.891 +  &res2_inverse
   1.892 +};