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 +};