res0.c 22 KB
Newer Older
Monty's avatar
   
Monty committed
1
2
/********************************************************************
 *                                                                  *
Monty's avatar
   
Monty committed
3
 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE.   *
Monty's avatar
   
Monty committed
4
5
6
 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
Monty's avatar
   
Monty committed
7
 *                                                                  *
Monty's avatar
   
Monty committed
8
9
 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
 * by the XIPHOPHORUS Company http://www.xiph.org/                  *
Monty's avatar
   
Monty committed
10
 *                                                                  *
Monty's avatar
   
Monty committed
11
12
 ********************************************************************

Monty's avatar
   
Monty committed
13
 function: residue backend 0, 1 and 2 implementation
Monty's avatar
   
Monty committed
14
 last mod: $Id: res0.c,v 1.36 2001/09/01 06:14:50 xiphmont Exp $
Monty's avatar
   
Monty committed
15
16
17

 ********************************************************************/

Monty's avatar
   
Monty committed
18
19
20
21
22
/* Slow, slow, slow, simpleminded and did I mention it was slow?  The
   encode/decode loops are coded for clarity and performance is not
   yet even a nagging little idea lurking in the shadows.  Oh and BTW,
   it's slow. */

Monty's avatar
   
Monty committed
23
24
#include <stdlib.h>
#include <string.h>
Monty's avatar
   
Monty committed
25
#include <math.h>
Monty's avatar
   
Monty committed
26
#include <stdio.h>
Monty's avatar
   
Monty committed
27
#include <ogg/ogg.h>
Monty's avatar
   
Monty committed
28
#include "vorbis/codec.h"
Monty's avatar
   
Monty committed
29
#include "codec_internal.h"
Monty's avatar
   
Monty committed
30
#include "registry.h"
Monty's avatar
   
Monty committed
31
#include "codebook.h"
Monty's avatar
   
Monty committed
32
#include "misc.h"
Monty's avatar
   
Monty committed
33
#include "os.h"
Monty's avatar
   
Monty committed
34

Monty's avatar
   
Monty committed
35
36
typedef struct {
  vorbis_info_residue0 *info;
Monty's avatar
   
Monty committed
37
  int         map;
Monty's avatar
   
Monty committed
38
39
  
  int         parts;
Monty's avatar
   
Monty committed
40
41
  int         stages;
  codebook   *fullbooks;
Monty's avatar
   
Monty committed
42
43
44
45
46
  codebook   *phrasebook;
  codebook ***partbooks;

  int         partvals;
  int       **decodemap;
Monty's avatar
   
Monty committed
47

Monty's avatar
   
Monty committed
48
  long      postbits;
Monty's avatar
   
Monty committed
49
  long      phrasebits;
Monty's avatar
   
Monty committed
50
  long      frames;
Monty's avatar
   
Monty committed
51

Monty's avatar
   
Monty committed
52
} vorbis_look_residue0;
Monty's avatar
   
Monty committed
53

Monty's avatar
   
Monty committed
54
55
56
57
58
59
60
vorbis_info_residue *res0_copy_info(vorbis_info_residue *vr){
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
  vorbis_info_residue0 *ret=_ogg_malloc(sizeof(vorbis_info_residue0));
  memcpy(ret,info,sizeof(vorbis_info_residue0));
  return(ret);
}

Monty's avatar
   
Monty committed
61
void res0_free_info(vorbis_info_residue *i){
Monty's avatar
   
Monty committed
62
63
  if(i){
    memset(i,0,sizeof(vorbis_info_residue0));
Monty's avatar
   
Monty committed
64
    _ogg_free(i);
Monty's avatar
   
Monty committed
65
  }
Monty's avatar
   
Monty committed
66
67
}

Monty's avatar
   
Monty committed
68
void res0_free_look(vorbis_look_residue *i){
Monty's avatar
   
Monty committed
69
  int j;
Monty's avatar
   
Monty committed
70
  if(i){
Monty's avatar
   
Monty committed
71

Monty's avatar
   
Monty committed
72
    vorbis_look_residue0 *look=(vorbis_look_residue0 *)i;
Monty's avatar
   
Monty committed
73

Monty's avatar
   
Monty committed
74
    fprintf(stderr,"residue bit usage %f:%f (%f total)\n",
Monty's avatar
   
Monty committed
75
76
	    (float)look->phrasebits/look->frames,
	    (float)look->postbits/look->frames,
Monty's avatar
   
Monty committed
77
	    (float)(look->postbits+look->phrasebits)/look->frames);
Monty's avatar
   
Monty committed
78
79
80
81

    /*vorbis_info_residue0 *info=look->info;

    fprintf(stderr,
Monty's avatar
   
Monty committed
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
	    "%ld frames encoded in %ld phrasebits and %ld residue bits "
	    "(%g/frame) \n",look->frames,look->phrasebits,
	    look->resbitsflat,
	    (look->phrasebits+look->resbitsflat)/(float)look->frames);
    
    for(j=0;j<look->parts;j++){
      long acc=0;
      fprintf(stderr,"\t[%d] == ",j);
      for(k=0;k<look->stages;k++)
	if((info->secondstages[j]>>k)&1){
	  fprintf(stderr,"%ld,",look->resbits[j][k]);
	  acc+=look->resbits[j][k];
	}

      fprintf(stderr,":: (%ld vals) %1.2fbits/sample\n",look->resvals[j],
	      acc?(float)acc/(look->resvals[j]*info->grouping):0);
    }
    fprintf(stderr,"\n");*/
Monty's avatar
   
Monty committed
100

Monty's avatar
   
Monty committed
101
    for(j=0;j<look->parts;j++)
Monty's avatar
   
Monty committed
102
103
      if(look->partbooks[j])_ogg_free(look->partbooks[j]);
    _ogg_free(look->partbooks);
Monty's avatar
   
Monty committed
104
    for(j=0;j<look->partvals;j++)
Monty's avatar
   
Monty committed
105
106
      _ogg_free(look->decodemap[j]);
    _ogg_free(look->decodemap);
Monty's avatar
   
Monty committed
107
    memset(i,0,sizeof(vorbis_look_residue0));
Monty's avatar
   
Monty committed
108
    _ogg_free(i);
Monty's avatar
   
Monty committed
109
  }
Monty's avatar
   
Monty committed
110
111
}

Monty's avatar
   
Monty committed
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
static int ilog(unsigned int v){
  int ret=0;
  while(v){
    ret++;
    v>>=1;
  }
  return(ret);
}

static int icount(unsigned int v){
  int ret=0;
  while(v){
    ret+=v&1;
    v>>=1;
  }
  return(ret);
}


Monty's avatar
   
Monty committed
131
void res0_pack(vorbis_info_residue *vr,oggpack_buffer *opb){
Monty's avatar
   
Monty committed
132
133
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
  int j,acc=0;
Monty's avatar
   
Monty committed
134
135
  oggpack_write(opb,info->begin,24);
  oggpack_write(opb,info->end,24);
Monty's avatar
   
Monty committed
136

Monty's avatar
   
Monty committed
137
  oggpack_write(opb,info->grouping-1,24);  /* residue vectors to group and 
Monty's avatar
   
Monty committed
138
					     code with a partitioned book */
Monty's avatar
   
Monty committed
139
140
  oggpack_write(opb,info->partitions-1,6); /* possible partition choices */
  oggpack_write(opb,info->groupbook,8);  /* group huffman book */
Monty's avatar
   
Monty committed
141
142
143
144

  /* secondstages is a bitmask; as encoding progresses pass by pass, a
     bitmask of one indicates this partition class has bits to write
     this pass */
Monty's avatar
   
Monty committed
145
  for(j=0;j<info->partitions;j++){
Monty's avatar
   
Monty committed
146
147
148
149
150
151
152
153
    if(ilog(info->secondstages[j])>3){
      /* yes, this is a minor hack due to not thinking ahead */
      oggpack_write(opb,info->secondstages[j],3); 
      oggpack_write(opb,1,1);
      oggpack_write(opb,info->secondstages[j]>>3,5); 
    }else
      oggpack_write(opb,info->secondstages[j],4); /* trailing zero */
    acc+=icount(info->secondstages[j]);
Monty's avatar
   
Monty committed
154
155
  }
  for(j=0;j<acc;j++)
Monty's avatar
   
Monty committed
156
    oggpack_write(opb,info->booklist[j],8);
Monty's avatar
   
Monty committed
157

Monty's avatar
   
Monty committed
158
159
160
}

/* vorbis_info is for range checking */
Monty's avatar
   
Monty committed
161
vorbis_info_residue *res0_unpack(vorbis_info *vi,oggpack_buffer *opb){
Monty's avatar
   
Monty committed
162
  int j,acc=0;
Monty's avatar
   
Monty committed
163
164
  vorbis_info_residue0 *info=_ogg_calloc(1,sizeof(vorbis_info_residue0));
  codec_setup_info     *ci=vi->codec_setup;
Monty's avatar
   
Monty committed
165

Monty's avatar
   
Monty committed
166
167
168
169
170
  info->begin=oggpack_read(opb,24);
  info->end=oggpack_read(opb,24);
  info->grouping=oggpack_read(opb,24)+1;
  info->partitions=oggpack_read(opb,6)+1;
  info->groupbook=oggpack_read(opb,8);
Monty's avatar
   
Monty committed
171

Monty's avatar
   
Monty committed
172
  for(j=0;j<info->partitions;j++){
Monty's avatar
   
Monty committed
173
    int cascade=oggpack_read(opb,3);
Monty's avatar
   
Monty committed
174
175
    if(oggpack_read(opb,1))
      cascade|=(oggpack_read(opb,5)<<3);
Monty's avatar
   
Monty committed
176
177
    info->secondstages[j]=cascade;

Monty's avatar
   
Monty committed
178
    acc+=icount(cascade);
Monty's avatar
   
Monty committed
179
  }
Monty's avatar
   
Monty committed
180
  for(j=0;j<acc;j++)
Monty's avatar
   
Monty committed
181
    info->booklist[j]=oggpack_read(opb,8);
Monty's avatar
   
Monty committed
182

Monty's avatar
   
Monty committed
183
  if(info->groupbook>=ci->books)goto errout;
Monty's avatar
   
Monty committed
184
  for(j=0;j<acc;j++)
Monty's avatar
   
Monty committed
185
    if(info->booklist[j]>=ci->books)goto errout;
Monty's avatar
   
Monty committed
186

Monty's avatar
   
Monty committed
187
  return(info);
Monty's avatar
   
Monty committed
188
 errout:
Monty's avatar
   
Monty committed
189
  res0_free_info(info);
Monty's avatar
   
Monty committed
190
  return(NULL);
Monty's avatar
   
Monty committed
191
192
}

Monty's avatar
   
Monty committed
193
vorbis_look_residue *res0_look (vorbis_dsp_state *vd,vorbis_info_mode *vm,
Monty's avatar
   
Monty committed
194
			  vorbis_info_residue *vr){
Monty's avatar
   
Monty committed
195
  vorbis_info_residue0 *info=(vorbis_info_residue0 *)vr;
Monty's avatar
   
Monty committed
196
197
198
  vorbis_look_residue0 *look=_ogg_calloc(1,sizeof(vorbis_look_residue0));
  backend_lookup_state *be=vd->backend_state;

Monty's avatar
   
Monty committed
199
200
  int j,k,acc=0;
  int dim;
Monty's avatar
   
Monty committed
201
  int maxstage=0;
Monty's avatar
   
Monty committed
202
  look->info=info;
Monty's avatar
   
Monty committed
203
  look->map=vm->mapping;
Monty's avatar
   
Monty committed
204
205

  look->parts=info->partitions;
Monty's avatar
   
Monty committed
206
  look->fullbooks=be->fullbooks;
Monty's avatar
   
Monty committed
207
  look->phrasebook=be->fullbooks+info->groupbook;
Monty's avatar
   
Monty committed
208
209
  dim=look->phrasebook->dim;

Monty's avatar
   
Monty committed
210
  look->partbooks=_ogg_calloc(look->parts,sizeof(codebook **));
Monty's avatar
   
Monty committed
211
212

  for(j=0;j<look->parts;j++){
Monty's avatar
   
Monty committed
213
    int stages=ilog(info->secondstages[j]);
Monty's avatar
   
Monty committed
214
    if(stages){
Monty's avatar
   
Monty committed
215
216
217
218
219
      if(stages>maxstage)maxstage=stages;
      look->partbooks[j]=_ogg_calloc(stages,sizeof(codebook *));
      for(k=0;k<stages;k++)
	if(info->secondstages[j]&(1<<k))
	  look->partbooks[j][k]=be->fullbooks+info->booklist[acc++];
Monty's avatar
   
Monty committed
220
221
222
    }
  }

Monty's avatar
   
Monty committed
223
  look->partvals=rint(pow(look->parts,dim));
Monty's avatar
   
Monty committed
224
  look->stages=maxstage;
Monty's avatar
   
Monty committed
225
  look->decodemap=_ogg_malloc(look->partvals*sizeof(int *));
Monty's avatar
   
Monty committed
226
227
228
  for(j=0;j<look->partvals;j++){
    long val=j;
    long mult=look->partvals/look->parts;
Monty's avatar
   
Monty committed
229
    look->decodemap[j]=_ogg_malloc(dim*sizeof(int));
Monty's avatar
   
Monty committed
230
231
232
233
234
235
    for(k=0;k<dim;k++){
      long deco=val/mult;
      val-=deco*mult;
      mult/=look->parts;
      look->decodemap[j][k]=deco;
    }
Monty's avatar
   
Monty committed
236
237
238
  }

  return(look);
Monty's avatar
   
Monty committed
239
}
Monty's avatar
   
Monty committed
240

Monty's avatar
   
Monty committed
241
242
243

/* does not guard against invalid settings; eg, a subn of 16 and a
   subgroup request of 32.  Max subn of 128 */
Monty's avatar
   
Monty committed
244
245
static int _interleaved_testhack(float *vec,int n,vorbis_look_residue0 *look,
				 int auxparts,int auxpartnum){
Monty's avatar
   
Monty committed
246
  vorbis_info_residue0 *info=look->info;
Monty's avatar
   
Monty committed
247
  int i,j=0;
Monty's avatar
   
Monty committed
248
  float max,localmax=0.f;
Monty's avatar
   
Monty committed
249
250
  float temp[128];
  float entropy[8];
Monty's avatar
   
Monty committed
251
252

  /* setup */
Monty's avatar
   
Monty committed
253
  for(i=0;i<n;i++)temp[i]=fabs(vec[i]);
Monty's avatar
   
Monty committed
254
255

  /* handle case subgrp==1 outside */
Monty's avatar
   
Monty committed
256
  for(i=0;i<n;i++)
Monty's avatar
   
Monty committed
257
258
    if(temp[i]>localmax)localmax=temp[i];
  max=localmax;
Monty's avatar
   
Monty committed
259
260

  for(i=0;i<n;i++)temp[i]=rint(temp[i]);
Monty's avatar
   
Monty committed
261
  
Monty's avatar
   
Monty committed
262
263
264
  while(1){
    entropy[j]=localmax;
    n>>=1;
Monty's avatar
   
Monty committed
265
    if(!n)break;
Monty's avatar
   
Monty committed
266
267
268
269
270
    j++;

    for(i=0;i<n;i++){
      temp[i]+=temp[i+n];
    }
Monty's avatar
   
Monty committed
271
    localmax=0.f;
Monty's avatar
   
Monty committed
272
273
274
275
276
    for(i=0;i<n;i++)
      if(temp[i]>localmax)localmax=temp[i];
  }

  for(i=0;i<auxparts-1;i++)
Monty's avatar
   
Monty committed
277
278
    if(auxpartnum<info->blimit[i] &&
       entropy[info->subgrp[i]]<=info->entmax[i] &&
Monty's avatar
   
Monty committed
279
       max<=info->ampmax[i])
Monty's avatar
   
Monty committed
280
      break;
Monty's avatar
   
Monty committed
281

Monty's avatar
   
Monty committed
282
  return(i);
Monty's avatar
   
Monty committed
283
284
}

Monty's avatar
   
Monty committed
285
286
287
static int _testhack(float *vec,int n,vorbis_look_residue0 *look,
		     int auxparts,int auxpartnum){
  vorbis_info_residue0 *info=look->info;
Monty's avatar
   
Monty committed
288
289
  int i;
  float max=0.f;
Monty's avatar
   
Monty committed
290
  float temp[128];
Monty's avatar
   
Monty committed
291
  float entropy=0.f;
Monty's avatar
   
Monty committed
292
293
294
295
296

  /* setup */
  for(i=0;i<n;i++)temp[i]=fabs(vec[i]);

  for(i=0;i<n;i++)
Monty's avatar
   
Monty committed
297
    if(temp[i]>max)max=temp[i];
Monty's avatar
   
Monty committed
298
299

  for(i=0;i<n;i++)temp[i]=rint(temp[i]);
Monty's avatar
   
Monty committed
300
301
302

  for(i=0;i<n;i++)
    entropy+=temp[i];
Monty's avatar
   
Monty committed
303
304
305

  for(i=0;i<auxparts-1;i++)
    if(auxpartnum<info->blimit[i] &&
Monty's avatar
   
Monty committed
306
       entropy<=info->entmax[i] &&
Monty's avatar
   
Monty committed
307
308
309
310
311
312
313
       max<=info->ampmax[i])
      break;

  return(i);
}

static int _interleaved_encodepart(oggpack_buffer *opb,float *vec, int n,
Monty's avatar
   
Monty committed
314
315
316
317
				   codebook *book,vorbis_look_residue0 *look){
  int i,bits=0;
  int dim=book->dim;
  int step=n/dim;
Monty's avatar
   
Monty committed
318
#ifdef TRAIN_RESENT      
Monty's avatar
   
Monty committed
319
320
321
322
  char buf[80];
  FILE *f;
  sprintf(buf,"res0_b%d.vqd",book-look->fullbooks);
  f=fopen(buf,"a");
Monty's avatar
   
Monty committed
323
#endif
Monty's avatar
   
Monty committed
324
325
326
327
328
329
330
331
332

  for(i=0;i<step;i++){
    int entry=vorbis_book_besterror(book,vec+i,step,0);

#ifdef TRAIN_RESENT      
    fprintf(f,"%d\n",entry);
#endif

    bits+=vorbis_book_encode(book,entry,opb);
Monty's avatar
   
Monty committed
333
  }
Monty's avatar
   
Monty committed
334
335
336
337

#ifdef TRAIN_RESENT      
  fclose(f);
#endif
Monty's avatar
   
Monty committed
338
339
340
  return(bits);
}
 
Monty's avatar
   
Monty committed
341
static int _encodepart(oggpack_buffer *opb,float *vec, int n,
Monty's avatar
   
Monty committed
342
343
344
345
		       codebook *book,vorbis_look_residue0 *look){
  int i,bits=0;
  int dim=book->dim;
  int step=n/dim;
Monty's avatar
   
Monty committed
346
#ifdef TRAIN_RESENT      
Monty's avatar
   
Monty committed
347
348
349
350
  char buf[80];
  FILE *f;
  sprintf(buf,"res0_b%d.vqd",book-look->fullbooks);
  f=fopen(buf,"a");
Monty's avatar
   
Monty committed
351
#endif
Monty's avatar
   
Monty committed
352

Monty's avatar
   
Monty committed
353
354
  for(i=0;i<step;i++){
    int entry=vorbis_book_besterror(book,vec+i*dim,1,0);
Monty's avatar
   
Monty committed
355

Monty's avatar
   
Monty committed
356
357
358
359
360
#ifdef TRAIN_RESENT      
    fprintf(f,"%d\n",entry);
#endif

    bits+=vorbis_book_encode(book,entry,opb);
Monty's avatar
   
Monty committed
361
  }
Monty's avatar
   
Monty committed
362
363
364
365
366

#ifdef TRAIN_RESENT      
  fclose(f);
#endif
  return(bits);
Monty's avatar
   
Monty committed
367
368
}

Monty's avatar
   
Monty committed
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
static long **_01class(vorbis_block *vb,vorbis_look_residue *vl,
		       float **in,int ch,
		       int (*classify)(float *,int,vorbis_look_residue0 *,
				       int,int)){
  long i,j;
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int possible_partitions=info->partitions;
  int n=info->end-info->begin;

  int partvals=n/samples_per_partition;
  long **partword=_vorbis_block_alloc(vb,ch*sizeof(long *));

  /* we find the partition type for each partition of each
     channel.  We'll go back and do the interleaved encoding in a
     bit.  For now, clarity */
 
  for(i=0;i<ch;i++){
    partword[i]=_vorbis_block_alloc(vb,n/samples_per_partition*sizeof(long));
    memset(partword[i],0,n/samples_per_partition*sizeof(long));
  }

  for(i=0;i<partvals;i++){
    for(j=0;j<ch;j++)
      /* do the partition decision based on the 'entropy'
         int the block */
      partword[j][i]=
	classify(in[j]+i*samples_per_partition+info->begin,
		 samples_per_partition,look,possible_partitions,i);
  
  }

#ifdef TRAIN_RES
  {
    FILE *of;
    char buffer[80];
  
    for(i=0;i<ch;i++){
      sprintf(buffer,"resaux_%d.vqd",vb->mode);
      of=fopen(buffer,"a");
      for(j=0;j<partvals;j++)
	fprintf(of,"%ld, ",partword[i][j]);
      fprintf(of,"\n");
      fclose(of);
    }
  }
#endif
  look->frames++;

  return(partword);
}

static long **_2class(vorbis_block *vb,vorbis_look_residue *vl,
		       float **in,int ch,
		       int (*classify)(float *,int,vorbis_look_residue0 *,
				       int,int)){
  long i,j,k,l;
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int possible_partitions=info->partitions;
  int n=info->end-info->begin;

  int partvals=n/samples_per_partition;
  long **partword=_vorbis_block_alloc(vb,sizeof(long *));
  float *work=alloca(sizeof(float)*samples_per_partition);
  
  partword[0]=_vorbis_block_alloc(vb,n*ch/samples_per_partition*sizeof(long));
  memset(partword[0],0,n*ch/samples_per_partition*sizeof(long));

  for(i=0,j=0,k=0,l=info->begin;i<partvals;i++){
    for(k=0;k<samples_per_partition;k++){
      work[k]=in[j][l];
      j++;
      if(j>=ch){
	j=0;
	l++;
      }
    }
    partword[0][i]=
      classify(work,samples_per_partition,look,possible_partitions,i);
  }  

#ifdef TRAIN_RES
  {
    FILE *of;
    char buffer[80];
  
    sprintf(buffer,"resaux_%d.vqd",vb->mode);
    of=fopen(buffer,"a");
    for(i=0;i<partvals;i++)
      fprintf(of,"%ld, ",partword[0][i]);
    fprintf(of,"\n");
    fclose(of);
  }
#endif
  look->frames++;

  return(partword);
}

Monty's avatar
   
Monty committed
475
476
static int _01forward(vorbis_block *vb,vorbis_look_residue *vl,
		      float **in,int ch,
Monty's avatar
   
Monty committed
477
		      int pass,long **partword,
Monty's avatar
   
Monty committed
478
479
		      int (*encode)(oggpack_buffer *,float *,int,
				    codebook *,vorbis_look_residue0 *)){
Monty's avatar
   
Monty committed
480
  long i,j,k,s;
Monty's avatar
   
Monty committed
481
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
Monty's avatar
   
Monty committed
482
  vorbis_info_residue0 *info=look->info;
Monty's avatar
   
Monty committed
483
484
485
486
487
488
489
490

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int possible_partitions=info->partitions;
  int partitions_per_word=look->phrasebook->dim;
  int n=info->end-info->begin;

  int partvals=n/samples_per_partition;
Monty's avatar
   
Monty committed
491
492
  long resbits[128];
  long resvals[128];
Monty's avatar
   
Monty committed
493

Monty's avatar
   
Monty committed
494
495
496
497
498
499
#ifdef TRAIN_RES
  FILE *of;
  char buffer[80];
  int m;
  
  for(i=0;i<ch;i++){
Monty's avatar
   
Monty committed
500
    sprintf(buffer,"residue_%d#%d.vqd",vb->mode,pass);
Monty's avatar
   
Monty committed
501
502
503
504
505
506
507
508
    of=fopen(buffer,"a");
    for(m=0;m<info->end;m++)
      fprintf(of,"%.2f, ",in[i][m]);
    fprintf(of,"\n");
    fclose(of);
  }
#endif      

Monty's avatar
   
Monty committed
509
510
  memset(resbits,0,sizeof(resbits));
  memset(resvals,0,sizeof(resvals));
Monty's avatar
   
Monty committed
511
512
513
  
  /* we code the partition words for each channel, then the residual
     words for a partition per channel until we've written all the
Monty's avatar
   
Monty committed
514
     residual words for that partition word.  Then write the next
Monty's avatar
   
Monty committed
515
     partition channel words... */
Monty's avatar
   
Monty committed
516

Monty's avatar
   
Monty committed
517
518
  for(s=(pass==0?0:info->passlimit[pass-1]);s<info->passlimit[pass];s++){
    for(i=0;i<partvals;){
Monty's avatar
   
Monty committed
519
      
Monty's avatar
   
Monty committed
520
521
522
      /* first we encode a partition codeword for each channel */
      if(s==0){
	for(j=0;j<ch;j++){
Monty's avatar
   
Monty committed
523
	  long val=partword[j][i];
Monty's avatar
   
Monty committed
524
	  long ret;
Monty's avatar
   
Monty committed
525
526
527
528
529
530
531
532
533
	  for(k=1;k<partitions_per_word;k++){
	    val*=possible_partitions;
	    if(i+k<partvals)
	      val+=partword[j][i+k];
	  }	

	  /* training hack */
	  if(val<look->phrasebook->entries)
	    ret=vorbis_book_encode(look->phrasebook,val,&vb->opb);
Monty's avatar
   
Monty committed
534
535
	  else
	    fprintf(stderr,"!");
Monty's avatar
   
Monty committed
536
537
538
	  
	  look->phrasebits+=ret;
	
Monty's avatar
   
Monty committed
539
	}
Monty's avatar
   
Monty committed
540
      }
Monty's avatar
   
Monty committed
541
      
Monty's avatar
   
Monty committed
542
      /* now we encode interleaved residual values for the partitions */
Monty's avatar
   
Monty committed
543
544
      for(k=0;k<partitions_per_word && i<partvals;k++,i++){
	long offset=i*samples_per_partition+info->begin;
Monty's avatar
   
Monty committed
545
546
	
	for(j=0;j<ch;j++){
Monty's avatar
   
Monty committed
547
548
549
	  if(s==0)resvals[partword[j][i]]+=samples_per_partition;
	  if(info->secondstages[partword[j][i]]&(1<<s)){
	    codebook *statebook=look->partbooks[partword[j][i]][s];
Monty's avatar
   
Monty committed
550
	    if(statebook){
Monty's avatar
   
Monty committed
551
	      int ret=encode(&vb->opb,in[j]+offset,samples_per_partition,
Monty's avatar
   
Monty committed
552
			     statebook,look);
Monty's avatar
   
Monty committed
553
554
	      look->postbits+=ret;
	      resbits[partword[j][i]]+=ret;
Monty's avatar
   
Monty committed
555
556
557
558
559
	    }
	  }
	}
      }
    }
Monty's avatar
   
Monty committed
560
  }
Monty's avatar
   
Monty committed
561

Monty's avatar
   
Monty committed
562
  /*{
Monty's avatar
   
Monty committed
563
564
565
566
567
568
569
    long total=0;
    long totalbits=0;
    fprintf(stderr,"%d :: ",vb->mode);
    for(k=0;k<possible_partitions;k++){
      fprintf(stderr,"%ld/%1.2g, ",resvals[k],(float)resbits[k]/resvals[k]);
      total+=resvals[k];
      totalbits+=resbits[k];
Monty's avatar
   
Monty committed
570
      }
Monty's avatar
   
Monty committed
571
    
Monty's avatar
   
Monty committed
572
    fprintf(stderr,":: %ld:%1.2g\n",total,(double)totalbits/total);
Monty's avatar
   
Monty committed
573
    }*/
Monty's avatar
   
Monty committed
574
  return(0);
Monty's avatar
   
Monty committed
575
}
Monty's avatar
   
Monty committed
576

Monty's avatar
   
Monty committed
577
/* a truncated packet here just means 'stop working'; it's not an error */
Monty's avatar
   
Monty committed
578
579
static int _01inverse(vorbis_block *vb,vorbis_look_residue *vl,
		      float **in,int ch,
Monty's avatar
   
Monty committed
580
		      long (*decodepart)(codebook *, float *, 
Monty's avatar
   
Monty committed
581
					 oggpack_buffer *,int)){
Monty's avatar
   
Monty committed
582

Monty's avatar
   
Monty committed
583
  long i,j,k,l,s;
Monty's avatar
   
Monty committed
584
585
586
587
588
589
590
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int partitions_per_word=look->phrasebook->dim;
  int n=info->end-info->begin;
Monty's avatar
   
Monty committed
591
  
Monty's avatar
   
Monty committed
592
593
  int partvals=n/samples_per_partition;
  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
Monty's avatar
   
Monty committed
594
  int ***partword=alloca(ch*sizeof(int **));
Monty's avatar
   
Monty committed
595

Monty's avatar
   
Monty committed
596
  for(j=0;j<ch;j++)
Monty's avatar
   
Monty committed
597
598
599
600
    partword[j]=_vorbis_block_alloc(vb,partwords*sizeof(int *));

  for(s=0;s<look->stages;s++){

Monty's avatar
   
Monty committed
601
602
603
    /* each loop decodes on partition codeword containing 
       partitions_pre_word partitions */
    for(i=0,l=0;i<partvals;l++){
Monty's avatar
   
Monty committed
604
605
606
607
608
609
610
611
      if(s==0){
	/* fetch the partition word for each channel */
	for(j=0;j<ch;j++){
	  int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
	  if(temp==-1)goto eopbreak;
	  partword[j][l]=look->decodemap[temp];
	  if(partword[j][l]==NULL)goto errout;
	}
Monty's avatar
   
Monty committed
612
      }
Monty's avatar
   
Monty committed
613
614
      
      /* now we decode residual values for the partitions */
Monty's avatar
   
Monty committed
615
      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
Monty's avatar
   
Monty committed
616
	for(j=0;j<ch;j++){
Monty's avatar
   
Monty committed
617
	  long offset=info->begin+i*samples_per_partition;
Monty's avatar
   
Monty committed
618
619
620
	  if(info->secondstages[partword[j][l][k]]&(1<<s)){
	    codebook *stagebook=look->partbooks[partword[j][l][k]][s];
	    if(stagebook){
Monty's avatar
   
Monty committed
621
	      if(decodepart(stagebook,in[j]+offset,&vb->opb,
Monty's avatar
   
Monty committed
622
			    samples_per_partition)==-1)goto eopbreak;
Monty's avatar
   
Monty committed
623
624
625
626
	    }
	  }
	}
    } 
Monty's avatar
   
Monty committed
627
  }
Monty's avatar
   
Monty committed
628
  
Monty's avatar
   
Monty committed
629
 errout:
Monty's avatar
   
Monty committed
630
 eopbreak:
Monty's avatar
   
Monty committed
631
  return(0);
Monty's avatar
   
Monty committed
632
633
}

Monty's avatar
   
Monty committed
634
635
/* residue 0 and 1 are just slight variants of one another. 0 is
   interleaved, 1 is not */
Monty's avatar
   
Monty committed
636
637
long **res0_class(vorbis_block *vb,vorbis_look_residue *vl,
		  float **in,int *nonzero,int ch){
Monty's avatar
   
Monty committed
638
639
640
641
642
643
  /* we encode only the nonzero parts of a bundle */
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
Monty's avatar
   
Monty committed
644
645
    /*return(_01class(vb,vl,in,used,_interleaved_testhack));*/
    return(_01class(vb,vl,in,used,_testhack));
Monty's avatar
   
Monty committed
646
647
  else
    return(0);
Monty's avatar
   
Monty committed
648
649
}

Monty's avatar
   
Monty committed
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
int res0_forward(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,float **out,int *nonzero,int ch,
		 int pass, long **partword){
  /* we encode only the nonzero parts of a bundle */
  int i,j,used=0,n=vb->pcmend/2;
  for(i=0;i<ch;i++)
    if(nonzero[i]){
      for(j=0;j<n;j++)
	out[i][j]+=in[i][j];
      in[used++]=in[i];
    }
  if(used){
    int ret=_01forward(vb,vl,in,used,pass,partword,
		      _interleaved_encodepart);
    used=0;
    for(i=0;i<ch;i++)
      if(nonzero[i]){
	for(j=0;j<n;j++)
	  out[i][j]-=in[used][j];
	used++;
      }
    return(ret);
  }else
    return(0);
}

Monty's avatar
   
Monty committed
676
677
678
679
680
681
682
683
684
685
int res0_inverse(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    return(_01inverse(vb,vl,in,used,vorbis_book_decodevs_add));
  else
    return(0);
Monty's avatar
   
Monty committed
686
687
688
}

int res1_forward(vorbis_block *vb,vorbis_look_residue *vl,
Monty's avatar
   
Monty committed
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
		 float **in,float **out,int *nonzero,int ch,
		 int pass, long **partword){
  int i,j,used=0,n=vb->pcmend/2;
  for(i=0;i<ch;i++)
    if(nonzero[i]){
      for(j=0;j<n;j++)
	out[i][j]+=in[i][j];
      in[used++]=in[i];
    }

  if(used){
    int ret=_01forward(vb,vl,in,used,pass,partword,_encodepart);
    used=0;
    for(i=0;i<ch;i++)
      if(nonzero[i]){
	for(j=0;j<n;j++)
	  out[i][j]-=in[used][j];
	used++;
      }
    return(ret);
  }else
    return(0);
}

long **res1_class(vorbis_block *vb,vorbis_look_residue *vl,
		  float **in,int *nonzero,int ch){
Monty's avatar
   
Monty committed
715
716
717
718
719
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
Monty's avatar
   
Monty committed
720
    return(_01class(vb,vl,in,used,_testhack));
Monty's avatar
   
Monty committed
721
722
  else
    return(0);
Monty's avatar
   
Monty committed
723
724
}

Monty's avatar
   
Monty committed
725
726
727
728
729
730
731
732
733
734
int res1_inverse(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    return(_01inverse(vb,vl,in,used,vorbis_book_decodev_add));
  else
    return(0);
Monty's avatar
   
Monty committed
735
736
}

Monty's avatar
   
Monty committed
737
738
739
740
741
742
743
744
745
746
747
748
long **res2_class(vorbis_block *vb,vorbis_look_residue *vl,
		  float **in,int *nonzero,int ch){
  int i,used=0;
  for(i=0;i<ch;i++)
    if(nonzero[i])
      in[used++]=in[i];
  if(used)
    return(_2class(vb,vl,in,used,_testhack));
  else
    return(0);
}

Monty's avatar
   
Monty committed
749
750
/* res2 is slightly more different; all the channels are interleaved
   into a single vector and encoded. */
Monty's avatar
   
Monty committed
751

Monty's avatar
   
Monty committed
752
int res2_forward(vorbis_block *vb,vorbis_look_residue *vl,
Monty's avatar
   
Monty committed
753
754
		 float **in,float **out,int *nonzero,int ch,
		 int pass,long **partword){
Monty's avatar
   
Monty committed
755
  long i,j,k,n=vb->pcmend/2,used=0;
Monty's avatar
   
Monty committed
756
757
758

  /* don't duplicate the code; use a working vector hack for now and
     reshape ourselves into a single channel res1 */
Monty's avatar
   
Monty committed
759
  /* ugly; reallocs for each coupling pass :-( */
Monty's avatar
   
Monty committed
760
761
  float *work=_vorbis_block_alloc(vb,ch*n*sizeof(float));
  for(i=0;i<ch;i++){
Monty's avatar
   
Monty committed
762
    float *pcm=in[i];
Monty's avatar
   
Monty committed
763
    if(nonzero[i])used++;
Monty's avatar
   
Monty committed
764
765
766
    for(j=0,k=i;j<n;j++,k+=ch)
      work[k]=pcm[j];
  }
Monty's avatar
   
Monty committed
767
  
Monty's avatar
   
Monty committed
768
769
770
771
772
773
774
775
776
777
778
779
  if(used){
    int ret=_01forward(vb,vl,&work,1,pass,partword,_encodepart);
    /* update the sofar vector */
    for(i=0;i<ch;i++){
      float *pcm=in[i];
      float *sofar=out[i];
      for(j=0,k=i;j<n;j++,k+=ch)
	sofar[j]+=pcm[j]-work[k];
    }

    return(ret);
  }else
Monty's avatar
   
Monty committed
780
    return(0);
Monty's avatar
   
Monty committed
781
782
783
}

/* duplicate code here as speed is somewhat more important */
Monty's avatar
   
Monty committed
784
785
int res2_inverse(vorbis_block *vb,vorbis_look_residue *vl,
		 float **in,int *nonzero,int ch){
Monty's avatar
   
Monty committed
786
787
788
789
790
791
792
793
794
795
796
797
798
  long i,k,l,s;
  vorbis_look_residue0 *look=(vorbis_look_residue0 *)vl;
  vorbis_info_residue0 *info=look->info;

  /* move all this setup out later */
  int samples_per_partition=info->grouping;
  int partitions_per_word=look->phrasebook->dim;
  int n=info->end-info->begin;

  int partvals=n/samples_per_partition;
  int partwords=(partvals+partitions_per_word-1)/partitions_per_word;
  int **partword=_vorbis_block_alloc(vb,partwords*sizeof(int *));

Monty's avatar
   
Monty committed
799
800
801
  for(i=0;i<ch;i++)if(nonzero[i])break;
  if(i==ch)return(0); /* no nonzero vectors */

Monty's avatar
   
Monty committed
802
  for(s=0;s<look->stages;s++){
Monty's avatar
   
Monty committed
803
    for(i=0,l=0;i<partvals;l++){
Monty's avatar
   
Monty committed
804
805
806
807
808
809
810
811
812
813

      if(s==0){
	/* fetch the partition word */
	int temp=vorbis_book_decode(look->phrasebook,&vb->opb);
	if(temp==-1)goto eopbreak;
	partword[l]=look->decodemap[temp];
	if(partword[l]==NULL)goto errout;
      }

      /* now we decode residual values for the partitions */
Monty's avatar
   
Monty committed
814
      for(k=0;k<partitions_per_word && i<partvals;k++,i++)
Monty's avatar
   
Monty committed
815
816
	if(info->secondstages[partword[l][k]]&(1<<s)){
	  codebook *stagebook=look->partbooks[partword[l][k]][s];
Monty's avatar
   
Monty committed
817
	  
Monty's avatar
   
Monty committed
818
	  if(stagebook){
Monty's avatar
   
Monty committed
819
820
	    if(vorbis_book_decodevv_add(stagebook,in,
					i*samples_per_partition+info->begin,ch,
Monty's avatar
   
Monty committed
821
822
823
824
825
826
827
828
829
830
					&vb->opb,samples_per_partition)==-1)
	      goto eopbreak;
	  }
	}
    } 
  }
  
 errout:
 eopbreak:
  return(0);
Monty's avatar
   
Monty committed
831
832
}

Monty's avatar
   
Monty committed
833

Monty's avatar
   
Monty committed
834
vorbis_func_residue residue0_exportbundle={
Monty's avatar
   
Monty committed
835
836
837
  &res0_pack,
  &res0_unpack,
  &res0_look,
Monty's avatar
   
Monty committed
838
  &res0_copy_info,
Monty's avatar
   
Monty committed
839
840
  &res0_free_info,
  &res0_free_look,
Monty's avatar
   
Monty committed
841
  &res0_class,
Monty's avatar
   
Monty committed
842
843
  &res0_forward,
  &res0_inverse
Monty's avatar
   
Monty committed
844
};
Monty's avatar
   
Monty committed
845
846
847
848
849
850
851
852

vorbis_func_residue residue1_exportbundle={
  &res0_pack,
  &res0_unpack,
  &res0_look,
  &res0_copy_info,
  &res0_free_info,
  &res0_free_look,
Monty's avatar
   
Monty committed
853
  &res1_class,
Monty's avatar
   
Monty committed
854
855
856
  &res1_forward,
  &res1_inverse
};
Monty's avatar
   
Monty committed
857
858
859
860
861
862
863
864

vorbis_func_residue residue2_exportbundle={
  &res0_pack,
  &res0_unpack,
  &res0_look,
  &res0_copy_info,
  &res0_free_info,
  &res0_free_look,
Monty's avatar
   
Monty committed
865
  &res2_class,
Monty's avatar
   
Monty committed
866
867
868
  &res2_forward,
  &res2_inverse
};