annotate src/libvorbis-1.3.3/lib/res0.c @ 83:ae30d91d2ffe

Replace these with versions built using an older toolset (so as to avoid ABI compatibilities when linking on Ubuntu 14.04 for packaging purposes)
author Chris Cannam
date Fri, 07 Feb 2020 11:51:13 +0000
parents 05aa0afa9217
children
rev   line source
Chris@1 1 /********************************************************************
Chris@1 2 * *
Chris@1 3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
Chris@1 4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
Chris@1 5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
Chris@1 6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
Chris@1 7 * *
Chris@1 8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2010 *
Chris@1 9 * by the Xiph.Org Foundation http://www.xiph.org/ *
Chris@1 10 * *
Chris@1 11 ********************************************************************
Chris@1 12
Chris@1 13 function: residue backend 0, 1 and 2 implementation
Chris@1 14 last mod: $Id: res0.c 17556 2010-10-21 18:25:19Z tterribe $
Chris@1 15
Chris@1 16 ********************************************************************/
Chris@1 17
Chris@1 18 /* Slow, slow, slow, simpleminded and did I mention it was slow? The
Chris@1 19 encode/decode loops are coded for clarity and performance is not
Chris@1 20 yet even a nagging little idea lurking in the shadows. Oh and BTW,
Chris@1 21 it's slow. */
Chris@1 22
Chris@1 23 #include <stdlib.h>
Chris@1 24 #include <string.h>
Chris@1 25 #include <math.h>
Chris@1 26 #include <ogg/ogg.h>
Chris@1 27 #include "vorbis/codec.h"
Chris@1 28 #include "codec_internal.h"
Chris@1 29 #include "registry.h"
Chris@1 30 #include "codebook.h"
Chris@1 31 #include "misc.h"
Chris@1 32 #include "os.h"
Chris@1 33
Chris@1 34 //#define TRAIN_RES 1
Chris@1 35 //#define TRAIN_RESAUX 1
Chris@1 36
Chris@1 37 #if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
Chris@1 38 #include <stdio.h>
Chris@1 39 #endif
Chris@1 40
Chris@1 41 typedef struct {
Chris@1 42 vorbis_info_residue0 *info;
Chris@1 43
Chris@1 44 int parts;
Chris@1 45 int stages;
Chris@1 46 codebook *fullbooks;
Chris@1 47 codebook *phrasebook;
Chris@1 48 codebook ***partbooks;
Chris@1 49
Chris@1 50 int partvals;
Chris@1 51 int **decodemap;
Chris@1 52
Chris@1 53 long postbits;
Chris@1 54 long phrasebits;
Chris@1 55 long frames;
Chris@1 56
Chris@1 57 #if defined(TRAIN_RES) || defined(TRAIN_RESAUX)
Chris@1 58 int train_seq;
Chris@1 59 long *training_data[8][64];
Chris@1 60 float training_max[8][64];
Chris@1 61 float training_min[8][64];
Chris@1 62 float tmin;
Chris@1 63 float tmax;
Chris@1 64 int submap;
Chris@1 65 #endif
Chris@1 66
Chris@1 67 } vorbis_look_residue0;
Chris@1 68
Chris@1 69 void res0_free_info(vorbis_info_residue *i){
Chris@1 70 vorbis_info_residue0 *info=(vorbis_info_residue0 *)i;
Chris@1 71 if(info){
Chris@1 72 memset(info,0,sizeof(*info));
Chris@1 73 _ogg_free(info);
Chris@1 74 }
Chris@1 75 }
Chris@1 76
Chris@1 77 void res0_free_look(vorbis_look_residue *i){
Chris@1 78 int j;
Chris@1 79 if(i){
Chris@1 80
Chris@1 81 vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
Chris@1 82
Chris@1 83 #ifdef TRAIN_RES
Chris@1 84 {
Chris@1 85 int j,k,l;
Chris@1 86 for(j=0;j<look->parts;j++){
Chris@1 87 /*fprintf(stderr,"partition %d: ",j);*/
Chris@1 88 for(k=0;k<8;k++)
Chris@1 89 if(look->training_data[k][j]){
Chris@1 90 char buffer[80];
Chris@1 91 FILE *of;
Chris@1 92 codebook *statebook=look->partbooks[j][k];
Chris@1 93
Chris@1 94 /* long and short into the same bucket by current convention */
Chris@1 95 sprintf(buffer,"res_sub%d_part%d_pass%d.vqd",look->submap,j,k);
Chris@1 96 of=fopen(buffer,"a");
Chris@1 97
Chris@1 98 for(l=0;l<statebook->entries;l++)
Chris@1 99 fprintf(of,"%d:%ld\n",l,look->training_data[k][j][l]);
Chris@1 100
Chris@1 101 fclose(of);
Chris@1 102
Chris@1 103 /*fprintf(stderr,"%d(%.2f|%.2f) ",k,
Chris@1 104 look->training_min[k][j],look->training_max[k][j]);*/
Chris@1 105
Chris@1 106 _ogg_free(look->training_data[k][j]);
Chris@1 107 look->training_data[k][j]=NULL;
Chris@1 108 }
Chris@1 109 /*fprintf(stderr,"\n");*/
Chris@1 110 }
Chris@1 111 }
Chris@1 112 fprintf(stderr,"min/max residue: %g::%g\n",look->tmin,look->tmax);
Chris@1 113
Chris@1 114 /*fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
Chris@1 115 (float)look->phrasebits/look->frames,
Chris@1 116 (float)look->postbits/look->frames,
Chris@1 117 (float)(look->postbits+look->phrasebits)/look->frames);*/
Chris@1 118 #endif
Chris@1 119
Chris@1 120
Chris@1 121 /*vorbis_info_residue0 *info=look->info;
Chris@1 122
Chris@1 123 fprintf(stderr,
Chris@1 124 "%ld frames encoded in %ld phrasebits and %ld residue bits "
Chris@1 125 "(%g/frame) \n",look->frames,look->phrasebits,
Chris@1 126 look->resbitsflat,
Chris@1 127 (look->phrasebits+look->resbitsflat)/(float)look->frames);
Chris@1 128
Chris@1 129 for(j=0;j<look->parts;j++){
Chris@1 130 long acc=0;
Chris@1 131 fprintf(stderr,"\t[%d] == ",j);
Chris@1 132 for(k=0;k<look->stages;k++)
Chris@1 133 if((info->secondstages[j]>>k)&1){
Chris@1 134 fprintf(stderr,"%ld,",look->resbits[j][k]);
Chris@1 135 acc+=look->resbits[j][k];
Chris@1 136 }
Chris@1 137
Chris@1 138 fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
Chris@1 139 acc?(float)acc/(look->resvals[j]*info->grouping):0);
Chris@1 140 }
Chris@1 141 fprintf(stderr,"\n");*/
Chris@1 142
Chris@1 143 for(j=0;j<look->parts;j++)
Chris@1 144 if(look->partbooks[j])_ogg_free(look->partbooks[j]);
Chris@1 145 _ogg_free(look->partbooks);
Chris@1 146 for(j=0;j<look->partvals;j++)
Chris@1 147 _ogg_free(look->decodemap[j]);
Chris@1 148 _ogg_free(look->decodemap);
Chris@1 149
Chris@1 150 memset(look,0,sizeof(*look));
Chris@1 151 _ogg_free(look);
Chris@1 152 }
Chris@1 153 }
Chris@1 154
Chris@1 155 static int ilog(unsigned int v){
Chris@1 156 int ret=0;
Chris@1 157 while(v){
Chris@1 158 ret++;
Chris@1 159 v>>=1;
Chris@1 160 }
Chris@1 161 return(ret);
Chris@1 162 }
Chris@1 163
Chris@1 164 static int icount(unsigned int v){
Chris@1 165 int ret=0;
Chris@1 166 while(v){
Chris@1 167 ret+=v&1;
Chris@1 168 v>>=1;
Chris@1 169 }
Chris@1 170 return(ret);
Chris@1 171 }
Chris@1 172
Chris@1 173
Chris@1 174 void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
Chris@1 175 vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
Chris@1 176 int j,acc=0;
Chris@1 177 oggpack_write(opb,info->begin,24);
Chris@1 178 oggpack_write(opb,info->end,24);
Chris@1 179
Chris@1 180 oggpack_write(opb,info->grouping-1,24); /* residue vectors to group and
Chris@1 181 code with a partitioned book */
Chris@1 182 oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
Chris@1 183 oggpack_write(opb,info->groupbook,8); /* group huffman book */
Chris@1 184
Chris@1 185 /* secondstages is a bitmask; as encoding progresses pass by pass, a
Chris@1 186 bitmask of one indicates this partition class has bits to write
Chris@1 187 this pass */
Chris@1 188 for(j=0;j<info->partitions;j++){
Chris@1 189 if(ilog(info->secondstages[j])>3){
Chris@1 190 /* yes, this is a minor hack due to not thinking ahead */
Chris@1 191 oggpack_write(opb,info->secondstages[j],3);
Chris@1 192 oggpack_write(opb,1,1);
Chris@1 193 oggpack_write(opb,info->secondstages[j]>>3,5);
Chris@1 194 }else
Chris@1 195 oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
Chris@1 196 acc+=icount(info->secondstages[j]);
Chris@1 197 }
Chris@1 198 for(j=0;j<acc;j++)
Chris@1 199 oggpack_write(opb,info->booklist[j],8);
Chris@1 200
Chris@1 201 }
Chris@1 202
Chris@1 203 /* vorbis_info is for range checking */
Chris@1 204 vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
Chris@1 205 int j,acc=0;
Chris@1 206 vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(*info));
Chris@1 207 codec_setup_info *ci=vi->codec_setup;
Chris@1 208
Chris@1 209 info->begin=oggpack_read(opb,24);
Chris@1 210 info->end=oggpack_read(opb,24);
Chris@1 211 info->grouping=oggpack_read(opb,24)+1;
Chris@1 212 info->partitions=oggpack_read(opb,6)+1;
Chris@1 213 info->groupbook=oggpack_read(opb,8);
Chris@1 214
Chris@1 215 /* check for premature EOP */
Chris@1 216 if(info->groupbook<0)goto errout;
Chris@1 217
Chris@1 218 for(j=0;j<info->partitions;j++){
Chris@1 219 int cascade=oggpack_read(opb,3);
Chris@1 220 int cflag=oggpack_read(opb,1);
Chris@1 221 if(cflag<0) goto errout;
Chris@1 222 if(cflag){
Chris@1 223 int c=oggpack_read(opb,5);
Chris@1 224 if(c<0) goto errout;
Chris@1 225 cascade|=(c<<3);
Chris@1 226 }
Chris@1 227 info->secondstages[j]=cascade;
Chris@1 228
Chris@1 229 acc+=icount(cascade);
Chris@1 230 }
Chris@1 231 for(j=0;j<acc;j++){
Chris@1 232 int book=oggpack_read(opb,8);
Chris@1 233 if(book<0) goto errout;
Chris@1 234 info->booklist[j]=book;
Chris@1 235 }
Chris@1 236
Chris@1 237 if(info->groupbook>=ci->books)goto errout;
Chris@1 238 for(j=0;j<acc;j++){
Chris@1 239 if(info->booklist[j]>=ci->books)goto errout;
Chris@1 240 if(ci->book_param[info->booklist[j]]->maptype==0)goto errout;
Chris@1 241 }
Chris@1 242
Chris@1 243 /* verify the phrasebook is not specifying an impossible or
Chris@1 244 inconsistent partitioning scheme. */
Chris@1 245 /* modify the phrasebook ranging check from r16327; an early beta
Chris@1 246 encoder had a bug where it used an oversized phrasebook by
Chris@1 247 accident. These files should continue to be playable, but don't
Chris@1 248 allow an exploit */
Chris@1 249 {
Chris@1 250 int entries = ci->book_param[info->groupbook]->entries;
Chris@1 251 int dim = ci->book_param[info->groupbook]->dim;
Chris@1 252 int partvals = 1;
Chris@1 253 if (dim<1) goto errout;
Chris@1 254 while(dim>0){
Chris@1 255 partvals *= info->partitions;
Chris@1 256 if(partvals > entries) goto errout;
Chris@1 257 dim--;
Chris@1 258 }
Chris@1 259 info->partvals = partvals;
Chris@1 260 }
Chris@1 261
Chris@1 262 return(info);
Chris@1 263 errout:
Chris@1 264 res0_free_info(info);
Chris@1 265 return(NULL);
Chris@1 266 }
Chris@1 267
Chris@1 268 vorbis_look_residue *res0_look(vorbis_dsp_state *vd,
Chris@1 269 vorbis_info_residue *vr){
Chris@1 270 vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
Chris@1 271 vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(*look));
Chris@1 272 codec_setup_info *ci=vd->vi->codec_setup;
Chris@1 273
Chris@1 274 int j,k,acc=0;
Chris@1 275 int dim;
Chris@1 276 int maxstage=0;
Chris@1 277 look->info=info;
Chris@1 278
Chris@1 279 look->parts=info->partitions;
Chris@1 280 look->fullbooks=ci->fullbooks;
Chris@1 281 look->phrasebook=ci->fullbooks+info->groupbook;
Chris@1 282 dim=look->phrasebook->dim;
Chris@1 283
Chris@1 284 look->partbooks=_ogg_calloc(look->parts,sizeof(*look->partbooks));
Chris@1 285
Chris@1 286 for(j=0;j<look->parts;j++){
Chris@1 287 int stages=ilog(info->secondstages[j]);
Chris@1 288 if(stages){
Chris@1 289 if(stages>maxstage)maxstage=stages;
Chris@1 290 look->partbooks[j]=_ogg_calloc(stages,sizeof(*look->partbooks[j]));
Chris@1 291 for(k=0;k<stages;k++)
Chris@1 292 if(info->secondstages[j]&(1<<k)){
Chris@1 293 look->partbooks[j][k]=ci->fullbooks+info->booklist[acc++];
Chris@1 294 #ifdef TRAIN_RES
Chris@1 295 look->training_data[k][j]=_ogg_calloc(look->partbooks[j][k]->entries,
Chris@1 296 sizeof(***look->training_data));
Chris@1 297 #endif
Chris@1 298 }
Chris@1 299 }
Chris@1 300 }
Chris@1 301
Chris@1 302 look->partvals=1;
Chris@1 303 for(j=0;j<dim;j++)
Chris@1 304 look->partvals*=look->parts;
Chris@1 305
Chris@1 306 look->stages=maxstage;
Chris@1 307 look->decodemap=_ogg_malloc(look->partvals*sizeof(*look->decodemap));
Chris@1 308 for(j=0;j<look->partvals;j++){
Chris@1 309 long val=j;
Chris@1 310 long mult=look->partvals/look->parts;
Chris@1 311 look->decodemap[j]=_ogg_malloc(dim*sizeof(*look->decodemap[j]));
Chris@1 312 for(k=0;k<dim;k++){
Chris@1 313 long deco=val/mult;
Chris@1 314 val-=deco*mult;
Chris@1 315 mult/=look->parts;
Chris@1 316 look->decodemap[j][k]=deco;
Chris@1 317 }
Chris@1 318 }
Chris@1 319 #if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
Chris@1 320 {
Chris@1 321 static int train_seq=0;
Chris@1 322 look->train_seq=train_seq++;
Chris@1 323 }
Chris@1 324 #endif
Chris@1 325 return(look);
Chris@1 326 }
Chris@1 327
Chris@1 328 /* break an abstraction and copy some code for performance purposes */
Chris@1 329 static int local_book_besterror(codebook *book,int *a){
Chris@1 330 int dim=book->dim;
Chris@1 331 int i,j,o;
Chris@1 332 int minval=book->minval;
Chris@1 333 int del=book->delta;
Chris@1 334 int qv=book->quantvals;
Chris@1 335 int ze=(qv>>1);
Chris@1 336 int index=0;
Chris@1 337 /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
Chris@1 338 int p[8]={0,0,0,0,0,0,0,0};
Chris@1 339
Chris@1 340 if(del!=1){
Chris@1 341 for(i=0,o=dim;i<dim;i++){
Chris@1 342 int v = (a[--o]-minval+(del>>1))/del;
Chris@1 343 int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
Chris@1 344 index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
Chris@1 345 p[o]=v*del+minval;
Chris@1 346 }
Chris@1 347 }else{
Chris@1 348 for(i=0,o=dim;i<dim;i++){
Chris@1 349 int v = a[--o]-minval;
Chris@1 350 int m = (v<ze ? ((ze-v)<<1)-1 : ((v-ze)<<1));
Chris@1 351 index = index*qv+ (m<0?0:(m>=qv?qv-1:m));
Chris@1 352 p[o]=v*del+minval;
Chris@1 353 }
Chris@1 354 }
Chris@1 355
Chris@1 356 if(book->c->lengthlist[index]<=0){
Chris@1 357 const static_codebook *c=book->c;
Chris@1 358 int best=-1;
Chris@1 359 /* assumes integer/centered encoder codebook maptype 1 no more than dim 8 */
Chris@1 360 int e[8]={0,0,0,0,0,0,0,0};
Chris@1 361 int maxval = book->minval + book->delta*(book->quantvals-1);
Chris@1 362 for(i=0;i<book->entries;i++){
Chris@1 363 if(c->lengthlist[i]>0){
Chris@1 364 int this=0;
Chris@1 365 for(j=0;j<dim;j++){
Chris@1 366 int val=(e[j]-a[j]);
Chris@1 367 this+=val*val;
Chris@1 368 }
Chris@1 369 if(best==-1 || this<best){
Chris@1 370 memcpy(p,e,sizeof(p));
Chris@1 371 best=this;
Chris@1 372 index=i;
Chris@1 373 }
Chris@1 374 }
Chris@1 375 /* assumes the value patterning created by the tools in vq/ */
Chris@1 376 j=0;
Chris@1 377 while(e[j]>=maxval)
Chris@1 378 e[j++]=0;
Chris@1 379 if(e[j]>=0)
Chris@1 380 e[j]+=book->delta;
Chris@1 381 e[j]= -e[j];
Chris@1 382 }
Chris@1 383 }
Chris@1 384
Chris@1 385 if(index>-1){
Chris@1 386 for(i=0;i<dim;i++)
Chris@1 387 *a++ -= p[i];
Chris@1 388 }
Chris@1 389
Chris@1 390 return(index);
Chris@1 391 }
Chris@1 392
Chris@1 393 static int _encodepart(oggpack_buffer *opb,int *vec, int n,
Chris@1 394 codebook *book,long *acc){
Chris@1 395 int i,bits=0;
Chris@1 396 int dim=book->dim;
Chris@1 397 int step=n/dim;
Chris@1 398
Chris@1 399 for(i=0;i<step;i++){
Chris@1 400 int entry=local_book_besterror(book,vec+i*dim);
Chris@1 401
Chris@1 402 #ifdef TRAIN_RES
Chris@1 403 if(entry>=0)
Chris@1 404 acc[entry]++;
Chris@1 405 #endif
Chris@1 406
Chris@1 407 bits+=vorbis_book_encode(book,entry,opb);
Chris@1 408
Chris@1 409 }
Chris@1 410
Chris@1 411 return(bits);
Chris@1 412 }
Chris@1 413
Chris@1 414 static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 415 int **in,int ch){
Chris@1 416 long i,j,k;
Chris@1 417 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
Chris@1 418 vorbis_info_residue0 *info=look->info;
Chris@1 419
Chris@1 420 /* move all this setup out later */
Chris@1 421 int samples_per_partition=info->grouping;
Chris@1 422 int possible_partitions=info->partitions;
Chris@1 423 int n=info->end-info->begin;
Chris@1 424
Chris@1 425 int partvals=n/samples_per_partition;
Chris@1 426 long **partword=_vorbis_block_alloc(vb,ch*sizeof(*partword));
Chris@1 427 float scale=100./samples_per_partition;
Chris@1 428
Chris@1 429 /* we find the partition type for each partition of each
Chris@1 430 channel. We'll go back and do the interleaved encoding in a
Chris@1 431 bit. For now, clarity */
Chris@1 432
Chris@1 433 for(i=0;i<ch;i++){
Chris@1 434 partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(*partword[i]));
Chris@1 435 memset(partword[i],0,n/samples_per_partition*sizeof(*partword[i]));
Chris@1 436 }
Chris@1 437
Chris@1 438 for(i=0;i<partvals;i++){
Chris@1 439 int offset=i*samples_per_partition+info->begin;
Chris@1 440 for(j=0;j<ch;j++){
Chris@1 441 int max=0;
Chris@1 442 int ent=0;
Chris@1 443 for(k=0;k<samples_per_partition;k++){
Chris@1 444 if(abs(in[j][offset+k])>max)max=abs(in[j][offset+k]);
Chris@1 445 ent+=abs(in[j][offset+k]);
Chris@1 446 }
Chris@1 447 ent*=scale;
Chris@1 448
Chris@1 449 for(k=0;k<possible_partitions-1;k++)
Chris@1 450 if(max<=info->classmetric1[k] &&
Chris@1 451 (info->classmetric2[k]<0 || ent<info->classmetric2[k]))
Chris@1 452 break;
Chris@1 453
Chris@1 454 partword[j][i]=k;
Chris@1 455 }
Chris@1 456 }
Chris@1 457
Chris@1 458 #ifdef TRAIN_RESAUX
Chris@1 459 {
Chris@1 460 FILE *of;
Chris@1 461 char buffer[80];
Chris@1 462
Chris@1 463 for(i=0;i<ch;i++){
Chris@1 464 sprintf(buffer,"resaux_%d.vqd",look->train_seq);
Chris@1 465 of=fopen(buffer,"a");
Chris@1 466 for(j=0;j<partvals;j++)
Chris@1 467 fprintf(of,"%ld, ",partword[i][j]);
Chris@1 468 fprintf(of,"\n");
Chris@1 469 fclose(of);
Chris@1 470 }
Chris@1 471 }
Chris@1 472 #endif
Chris@1 473 look->frames++;
Chris@1 474
Chris@1 475 return(partword);
Chris@1 476 }
Chris@1 477
Chris@1 478 /* designed for stereo or other modes where the partition size is an
Chris@1 479 integer multiple of the number of channels encoded in the current
Chris@1 480 submap */
Chris@1 481 static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,int **in,
Chris@1 482 int ch){
Chris@1 483 long i,j,k,l;
Chris@1 484 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
Chris@1 485 vorbis_info_residue0 *info=look->info;
Chris@1 486
Chris@1 487 /* move all this setup out later */
Chris@1 488 int samples_per_partition=info->grouping;
Chris@1 489 int possible_partitions=info->partitions;
Chris@1 490 int n=info->end-info->begin;
Chris@1 491
Chris@1 492 int partvals=n/samples_per_partition;
Chris@1 493 long **partword=_vorbis_block_alloc(vb,sizeof(*partword));
Chris@1 494
Chris@1 495 #if defined(TRAIN_RES) || defined (TRAIN_RESAUX)
Chris@1 496 FILE *of;
Chris@1 497 char buffer[80];
Chris@1 498 #endif
Chris@1 499
Chris@1 500 partword[0]=_vorbis_block_alloc(vb,partvals*sizeof(*partword[0]));
Chris@1 501 memset(partword[0],0,partvals*sizeof(*partword[0]));
Chris@1 502
Chris@1 503 for(i=0,l=info->begin/ch;i<partvals;i++){
Chris@1 504 int magmax=0;
Chris@1 505 int angmax=0;
Chris@1 506 for(j=0;j<samples_per_partition;j+=ch){
Chris@1 507 if(abs(in[0][l])>magmax)magmax=abs(in[0][l]);
Chris@1 508 for(k=1;k<ch;k++)
Chris@1 509 if(abs(in[k][l])>angmax)angmax=abs(in[k][l]);
Chris@1 510 l++;
Chris@1 511 }
Chris@1 512
Chris@1 513 for(j=0;j<possible_partitions-1;j++)
Chris@1 514 if(magmax<=info->classmetric1[j] &&
Chris@1 515 angmax<=info->classmetric2[j])
Chris@1 516 break;
Chris@1 517
Chris@1 518 partword[0][i]=j;
Chris@1 519
Chris@1 520 }
Chris@1 521
Chris@1 522 #ifdef TRAIN_RESAUX
Chris@1 523 sprintf(buffer,"resaux_%d.vqd",look->train_seq);
Chris@1 524 of=fopen(buffer,"a");
Chris@1 525 for(i=0;i<partvals;i++)
Chris@1 526 fprintf(of,"%ld, ",partword[0][i]);
Chris@1 527 fprintf(of,"\n");
Chris@1 528 fclose(of);
Chris@1 529 #endif
Chris@1 530
Chris@1 531 look->frames++;
Chris@1 532
Chris@1 533 return(partword);
Chris@1 534 }
Chris@1 535
Chris@1 536 static int _01forward(oggpack_buffer *opb,
Chris@1 537 vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 538 int **in,int ch,
Chris@1 539 long **partword,
Chris@1 540 int (*encode)(oggpack_buffer *,int *,int,
Chris@1 541 codebook *,long *),
Chris@1 542 int submap){
Chris@1 543 long i,j,k,s;
Chris@1 544 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
Chris@1 545 vorbis_info_residue0 *info=look->info;
Chris@1 546
Chris@1 547 #ifdef TRAIN_RES
Chris@1 548 look->submap=submap;
Chris@1 549 #endif
Chris@1 550
Chris@1 551 /* move all this setup out later */
Chris@1 552 int samples_per_partition=info->grouping;
Chris@1 553 int possible_partitions=info->partitions;
Chris@1 554 int partitions_per_word=look->phrasebook->dim;
Chris@1 555 int n=info->end-info->begin;
Chris@1 556
Chris@1 557 int partvals=n/samples_per_partition;
Chris@1 558 long resbits[128];
Chris@1 559 long resvals[128];
Chris@1 560
Chris@1 561 #ifdef TRAIN_RES
Chris@1 562 for(i=0;i<ch;i++)
Chris@1 563 for(j=info->begin;j<info->end;j++){
Chris@1 564 if(in[i][j]>look->tmax)look->tmax=in[i][j];
Chris@1 565 if(in[i][j]<look->tmin)look->tmin=in[i][j];
Chris@1 566 }
Chris@1 567 #endif
Chris@1 568
Chris@1 569 memset(resbits,0,sizeof(resbits));
Chris@1 570 memset(resvals,0,sizeof(resvals));
Chris@1 571
Chris@1 572 /* we code the partition words for each channel, then the residual
Chris@1 573 words for a partition per channel until we've written all the
Chris@1 574 residual words for that partition word. Then write the next
Chris@1 575 partition channel words... */
Chris@1 576
Chris@1 577 for(s=0;s<look->stages;s++){
Chris@1 578
Chris@1 579 for(i=0;i<partvals;){
Chris@1 580
Chris@1 581 /* first we encode a partition codeword for each channel */
Chris@1 582 if(s==0){
Chris@1 583 for(j=0;j<ch;j++){
Chris@1 584 long val=partword[j][i];
Chris@1 585 for(k=1;k<partitions_per_word;k++){
Chris@1 586 val*=possible_partitions;
Chris@1 587 if(i+k<partvals)
Chris@1 588 val+=partword[j][i+k];
Chris@1 589 }
Chris@1 590
Chris@1 591 /* training hack */
Chris@1 592 if(val<look->phrasebook->entries)
Chris@1 593 look->phrasebits+=vorbis_book_encode(look->phrasebook,val,opb);
Chris@1 594 #if 0 /*def TRAIN_RES*/
Chris@1 595 else
Chris@1 596 fprintf(stderr,"!");
Chris@1 597 #endif
Chris@1 598
Chris@1 599 }
Chris@1 600 }
Chris@1 601
Chris@1 602 /* now we encode interleaved residual values for the partitions */
Chris@1 603 for(k=0;k<partitions_per_word && i<partvals;k++,i++){
Chris@1 604 long offset=i*samples_per_partition+info->begin;
Chris@1 605
Chris@1 606 for(j=0;j<ch;j++){
Chris@1 607 if(s==0)resvals[partword[j][i]]+=samples_per_partition;
Chris@1 608 if(info->secondstages[partword[j][i]]&(1<<s)){
Chris@1 609 codebook *statebook=look->partbooks[partword[j][i]][s];
Chris@1 610 if(statebook){
Chris@1 611 int ret;
Chris@1 612 long *accumulator=NULL;
Chris@1 613
Chris@1 614 #ifdef TRAIN_RES
Chris@1 615 accumulator=look->training_data[s][partword[j][i]];
Chris@1 616 {
Chris@1 617 int l;
Chris@1 618 int *samples=in[j]+offset;
Chris@1 619 for(l=0;l<samples_per_partition;l++){
Chris@1 620 if(samples[l]<look->training_min[s][partword[j][i]])
Chris@1 621 look->training_min[s][partword[j][i]]=samples[l];
Chris@1 622 if(samples[l]>look->training_max[s][partword[j][i]])
Chris@1 623 look->training_max[s][partword[j][i]]=samples[l];
Chris@1 624 }
Chris@1 625 }
Chris@1 626 #endif
Chris@1 627
Chris@1 628 ret=encode(opb,in[j]+offset,samples_per_partition,
Chris@1 629 statebook,accumulator);
Chris@1 630
Chris@1 631 look->postbits+=ret;
Chris@1 632 resbits[partword[j][i]]+=ret;
Chris@1 633 }
Chris@1 634 }
Chris@1 635 }
Chris@1 636 }
Chris@1 637 }
Chris@1 638 }
Chris@1 639
Chris@1 640 /*{
Chris@1 641 long total=0;
Chris@1 642 long totalbits=0;
Chris@1 643 fprintf(stderr,"%d :: ",vb->mode);
Chris@1 644 for(k=0;k<possible_partitions;k++){
Chris@1 645 fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
Chris@1 646 total+=resvals[k];
Chris@1 647 totalbits+=resbits[k];
Chris@1 648 }
Chris@1 649
Chris@1 650 fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
Chris@1 651 }*/
Chris@1 652
Chris@1 653 return(0);
Chris@1 654 }
Chris@1 655
Chris@1 656 /* a truncated packet here just means 'stop working'; it's not an error */
Chris@1 657 static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 658 float **in,int ch,
Chris@1 659 long (*decodepart)(codebook *, float *,
Chris@1 660 oggpack_buffer *,int)){
Chris@1 661
Chris@1 662 long i,j,k,l,s;
Chris@1 663 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
Chris@1 664 vorbis_info_residue0 *info=look->info;
Chris@1 665
Chris@1 666 /* move all this setup out later */
Chris@1 667 int samples_per_partition=info->grouping;
Chris@1 668 int partitions_per_word=look->phrasebook->dim;
Chris@1 669 int max=vb->pcmend>>1;
Chris@1 670 int end=(info->end<max?info->end:max);
Chris@1 671 int n=end-info->begin;
Chris@1 672
Chris@1 673 if(n>0){
Chris@1 674 int partvals=n/samples_per_partition;
Chris@1 675 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
Chris@1 676 int ***partword=alloca(ch*sizeof(*partword));
Chris@1 677
Chris@1 678 for(j=0;j<ch;j++)
Chris@1 679 partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(*partword[j]));
Chris@1 680
Chris@1 681 for(s=0;s<look->stages;s++){
Chris@1 682
Chris@1 683 /* each loop decodes on partition codeword containing
Chris@1 684 partitions_per_word partitions */
Chris@1 685 for(i=0,l=0;i<partvals;l++){
Chris@1 686 if(s==0){
Chris@1 687 /* fetch the partition word for each channel */
Chris@1 688 for(j=0;j<ch;j++){
Chris@1 689 int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
Chris@1 690
Chris@1 691 if(temp==-1 || temp>=info->partvals)goto eopbreak;
Chris@1 692 partword[j][l]=look->decodemap[temp];
Chris@1 693 if(partword[j][l]==NULL)goto errout;
Chris@1 694 }
Chris@1 695 }
Chris@1 696
Chris@1 697 /* now we decode residual values for the partitions */
Chris@1 698 for(k=0;k<partitions_per_word && i<partvals;k++,i++)
Chris@1 699 for(j=0;j<ch;j++){
Chris@1 700 long offset=info->begin+i*samples_per_partition;
Chris@1 701 if(info->secondstages[partword[j][l][k]]&(1<<s)){
Chris@1 702 codebook *stagebook=look->partbooks[partword[j][l][k]][s];
Chris@1 703 if(stagebook){
Chris@1 704 if(decodepart(stagebook,in[j]+offset,&vb->opb,
Chris@1 705 samples_per_partition)==-1)goto eopbreak;
Chris@1 706 }
Chris@1 707 }
Chris@1 708 }
Chris@1 709 }
Chris@1 710 }
Chris@1 711 }
Chris@1 712 errout:
Chris@1 713 eopbreak:
Chris@1 714 return(0);
Chris@1 715 }
Chris@1 716
Chris@1 717 int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 718 float **in,int *nonzero,int ch){
Chris@1 719 int i,used=0;
Chris@1 720 for(i=0;i<ch;i++)
Chris@1 721 if(nonzero[i])
Chris@1 722 in[used++]=in[i];
Chris@1 723 if(used)
Chris@1 724 return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
Chris@1 725 else
Chris@1 726 return(0);
Chris@1 727 }
Chris@1 728
Chris@1 729 int res1_forward(oggpack_buffer *opb,vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 730 int **in,int *nonzero,int ch, long **partword, int submap){
Chris@1 731 int i,used=0;
Chris@1 732 for(i=0;i<ch;i++)
Chris@1 733 if(nonzero[i])
Chris@1 734 in[used++]=in[i];
Chris@1 735
Chris@1 736 if(used){
Chris@1 737 return _01forward(opb,vb,vl,in,used,partword,_encodepart,submap);
Chris@1 738 }else{
Chris@1 739 return(0);
Chris@1 740 }
Chris@1 741 }
Chris@1 742
Chris@1 743 long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 744 int **in,int *nonzero,int ch){
Chris@1 745 int i,used=0;
Chris@1 746 for(i=0;i<ch;i++)
Chris@1 747 if(nonzero[i])
Chris@1 748 in[used++]=in[i];
Chris@1 749 if(used)
Chris@1 750 return(_01class(vb,vl,in,used));
Chris@1 751 else
Chris@1 752 return(0);
Chris@1 753 }
Chris@1 754
Chris@1 755 int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 756 float **in,int *nonzero,int ch){
Chris@1 757 int i,used=0;
Chris@1 758 for(i=0;i<ch;i++)
Chris@1 759 if(nonzero[i])
Chris@1 760 in[used++]=in[i];
Chris@1 761 if(used)
Chris@1 762 return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
Chris@1 763 else
Chris@1 764 return(0);
Chris@1 765 }
Chris@1 766
Chris@1 767 long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 768 int **in,int *nonzero,int ch){
Chris@1 769 int i,used=0;
Chris@1 770 for(i=0;i<ch;i++)
Chris@1 771 if(nonzero[i])used++;
Chris@1 772 if(used)
Chris@1 773 return(_2class(vb,vl,in,ch));
Chris@1 774 else
Chris@1 775 return(0);
Chris@1 776 }
Chris@1 777
Chris@1 778 /* res2 is slightly more different; all the channels are interleaved
Chris@1 779 into a single vector and encoded. */
Chris@1 780
Chris@1 781 int res2_forward(oggpack_buffer *opb,
Chris@1 782 vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 783 int **in,int *nonzero,int ch, long **partword,int submap){
Chris@1 784 long i,j,k,n=vb->pcmend/2,used=0;
Chris@1 785
Chris@1 786 /* don't duplicate the code; use a working vector hack for now and
Chris@1 787 reshape ourselves into a single channel res1 */
Chris@1 788 /* ugly; reallocs for each coupling pass :-( */
Chris@1 789 int *work=_vorbis_block_alloc(vb,ch*n*sizeof(*work));
Chris@1 790 for(i=0;i<ch;i++){
Chris@1 791 int *pcm=in[i];
Chris@1 792 if(nonzero[i])used++;
Chris@1 793 for(j=0,k=i;j<n;j++,k+=ch)
Chris@1 794 work[k]=pcm[j];
Chris@1 795 }
Chris@1 796
Chris@1 797 if(used){
Chris@1 798 return _01forward(opb,vb,vl,&work,1,partword,_encodepart,submap);
Chris@1 799 }else{
Chris@1 800 return(0);
Chris@1 801 }
Chris@1 802 }
Chris@1 803
Chris@1 804 /* duplicate code here as speed is somewhat more important */
Chris@1 805 int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
Chris@1 806 float **in,int *nonzero,int ch){
Chris@1 807 long i,k,l,s;
Chris@1 808 vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
Chris@1 809 vorbis_info_residue0 *info=look->info;
Chris@1 810
Chris@1 811 /* move all this setup out later */
Chris@1 812 int samples_per_partition=info->grouping;
Chris@1 813 int partitions_per_word=look->phrasebook->dim;
Chris@1 814 int max=(vb->pcmend*ch)>>1;
Chris@1 815 int end=(info->end<max?info->end:max);
Chris@1 816 int n=end-info->begin;
Chris@1 817
Chris@1 818 if(n>0){
Chris@1 819 int partvals=n/samples_per_partition;
Chris@1 820 int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
Chris@1 821 int **partword=_vorbis_block_alloc(vb,partwords*sizeof(*partword));
Chris@1 822
Chris@1 823 for(i=0;i<ch;i++)if(nonzero[i])break;
Chris@1 824 if(i==ch)return(0); /* no nonzero vectors */
Chris@1 825
Chris@1 826 for(s=0;s<look->stages;s++){
Chris@1 827 for(i=0,l=0;i<partvals;l++){
Chris@1 828
Chris@1 829 if(s==0){
Chris@1 830 /* fetch the partition word */
Chris@1 831 int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
Chris@1 832 if(temp==-1 || temp>=info->partvals)goto eopbreak;
Chris@1 833 partword[l]=look->decodemap[temp];
Chris@1 834 if(partword[l]==NULL)goto errout;
Chris@1 835 }
Chris@1 836
Chris@1 837 /* now we decode residual values for the partitions */
Chris@1 838 for(k=0;k<partitions_per_word && i<partvals;k++,i++)
Chris@1 839 if(info->secondstages[partword[l][k]]&(1<<s)){
Chris@1 840 codebook *stagebook=look->partbooks[partword[l][k]][s];
Chris@1 841
Chris@1 842 if(stagebook){
Chris@1 843 if(vorbis_book_decodevv_add(stagebook,in,
Chris@1 844 i*samples_per_partition+info->begin,ch,
Chris@1 845 &vb->opb,samples_per_partition)==-1)
Chris@1 846 goto eopbreak;
Chris@1 847 }
Chris@1 848 }
Chris@1 849 }
Chris@1 850 }
Chris@1 851 }
Chris@1 852 errout:
Chris@1 853 eopbreak:
Chris@1 854 return(0);
Chris@1 855 }
Chris@1 856
Chris@1 857
Chris@1 858 const vorbis_func_residue residue0_exportbundle={
Chris@1 859 NULL,
Chris@1 860 &res0_unpack,
Chris@1 861 &res0_look,
Chris@1 862 &res0_free_info,
Chris@1 863 &res0_free_look,
Chris@1 864 NULL,
Chris@1 865 NULL,
Chris@1 866 &res0_inverse
Chris@1 867 };
Chris@1 868
Chris@1 869 const vorbis_func_residue residue1_exportbundle={
Chris@1 870 &res0_pack,
Chris@1 871 &res0_unpack,
Chris@1 872 &res0_look,
Chris@1 873 &res0_free_info,
Chris@1 874 &res0_free_look,
Chris@1 875 &res1_class,
Chris@1 876 &res1_forward,
Chris@1 877 &res1_inverse
Chris@1 878 };
Chris@1 879
Chris@1 880 const vorbis_func_residue residue2_exportbundle={
Chris@1 881 &res0_pack,
Chris@1 882 &res0_unpack,
Chris@1 883 &res0_look,
Chris@1 884 &res0_free_info,
Chris@1 885 &res0_free_look,
Chris@1 886 &res2_class,
Chris@1 887 &res2_forward,
Chris@1 888 &res2_inverse
Chris@1 889 };