1 /********************************************************************
3 * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
5 * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
6 * PLEASE READ THESE TERMS DISTRIBUTING. *
8 * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-1999 *
9 * by 1999 Monty <monty@xiph.org> and The XIPHOPHORUS Company *
10 * http://www.xiph.org/ *
12 ********************************************************************
14 function: build a VQ codebook
15 author: Monty <xiphmont@mit.edu>
16 modifications by: Monty
17 last modification date: Dec 10 1999
19 ********************************************************************/
21 /* This code is *not* part of libvorbis. It is used to generate
22 trained codebooks offline and then spit the results into a
23 pregenerated codebook that is compiled into libvorbis. It is an
24 expensive (but good) algorithm. Run it on big iron. */
26 /* There are so many optimizations to explore in *both* stages that
27 considering the undertaking is almost withering. For now, we brute
37 /* Codebook generation happens in two steps:
39 1) Train the codebook with data collected from the encoder: We use
40 one of a few error metrics (which represent the distance between a
41 given data point and a candidate point in the training set) to
42 divide the training set up into cells representing roughly equal
43 probability of occurring.
45 2) Generate the codebook and auxiliary data from the trained data set
48 /* Building a codebook from trained set **********************************
50 The codebook in raw form is technically finished once it's trained.
51 However, we want to finalize the representative codebook values for
52 each entry and generate auxiliary information to optimize encoding.
53 We generate the auxiliary coding tree using collected data,
54 probably the same data as in the original training */
56 /* At each recursion, the data set is split in half. Cells with data
57 points on side A go into set A, same with set B. The sets may
58 overlap. If the cell overlaps the deviding line only very slightly
59 (provided parameter), we may choose to ignore the overlap in order
60 to pare the tree down */
64 int dascsort(const void *a,const void *b){
65 double av=sortvals[*((long *)a) * els];
66 double bv=sortvals[*((long *)b) * els];
72 int iascsort(const void *a,const void *b){
73 long av=isortvals[*((long *)a)];
74 long bv=isortvals[*((long *)b)];
78 extern double _dist_sq(vqgen *v,double *a, double *b);
80 /* goes through the split, but just counts it and returns a metric*/
81 void vqsp_count(vqgen *v,long *entryindex,long entries,
82 long *pointindex,long points,
83 long *entryA,long *entryB,
84 double *n, double c, double slack,
85 long *entriesA,long *entriesB,long *entriesC){
89 memset(entryA,0,sizeof(long)*entries);
90 memset(entryB,0,sizeof(long)*entries);
92 for(i=0;i<points;i++){
93 double *ppt=_point(v,pointindex[i]);
95 double firstmetric=_dist_sq(v,_now(v,entryindex[0]),ppt);
98 for(j=1;j<entries;j++){
99 double thismetric=_dist_sq(v,_now(v,entryindex[j]),ppt);
100 if(thismetric<firstmetric){
101 firstmetric=thismetric;
106 /* count point split */
107 for(k=0;k<v->elements;k++)
108 position+=ppt[k]*n[k];
110 entryA[firstentry]++;
112 entryB[firstentry]++;
116 /* look to see if entries are in the slack zone */
117 /* The entry splitting isn't total, so that storage has to be
118 allocated for recursion. Reuse the entryA/entryB vectors */
119 for(j=0;j<entries;j++){
120 long total=entryA[j]+entryB[j];
121 if((double)entryA[j]/total<slack){
123 }else if((double)entryB[j]/total<slack){
126 if(entryA[j] && entryB[j])C++;
127 if(entryA[j])entryA[A++]=entryindex[j];
128 if(entryB[j])entryB[B++]=entryindex[j];
135 void pq_in_out(vqgen *v,double *n,double *c,double *p,double *q){
138 for(k=0;k<v->elements;k++){
139 double center=(p[k]+q[k])/2.;
140 n[k]=(center-q[k])*2.;
145 void pq_center_out(vqgen *v,double *n,double *c,double *center,double *q){
148 for(k=0;k<v->elements;k++){
149 n[k]=(center[k]-q[k])*2.;
154 static void spinnit(void){
156 static long lasttime=0;
158 struct timeval thistime;
160 gettimeofday(&thistime,NULL);
161 test=thistime.tv_sec*10+thistime.tv_usec/100000;
168 fprintf(stderr,"|\b");
171 fprintf(stderr,"/\b");
174 fprintf(stderr,"-\b");
177 fprintf(stderr,"\\\b");
184 int lp_split(vqgen *v,vqbook *b,
185 long *entryindex,long entries,
186 long *pointindex,long points,
187 long depth,double slack){
189 /* The encoder, regardless of book, will be using a straight
190 euclidian distance-to-point metric to determine closest point.
191 Thus we split the cells using the same (we've already trained the
192 codebook set spacing and distribution using special metrics and
193 even a midpoint division won't disturb the basic properties) */
200 long *entryA=calloc(entries,sizeof(long));
201 long *entryB=calloc(entries,sizeof(long));
208 p=alloca(sizeof(double)*v->elements);
209 q=alloca(sizeof(double)*v->elements);
210 n=alloca(sizeof(double)*v->elements);
211 memset(p,0,sizeof(double)*v->elements);
213 /* We need to find the dividing hyperplane. find the median of each
214 axis as the centerpoint and the normal facing farthest point */
216 /* more than one way to do this part. For small sets, we can brute
220 /* try every pair possibility */
225 for(i=0;i<entries-1;i++){
226 for(j=i+1;j<entries;j++){
228 pq_in_out(v,n,&c,_now(v,entryindex[i]),_now(v,entryindex[j]));
229 vqsp_count(v,entryindex,entries,
233 &entriesA,&entriesB,&entriesC);
234 this=(entriesA-entriesC)*(entriesB-entriesC);
243 pq_in_out(v,n,&c,_now(v,entryindex[besti]),_now(v,entryindex[bestj]));
248 /* try COG/normal and furthest pairs */
250 for(k=0;k<v->elements;k++){
253 /* just sort the index array */
254 sortvals=v->entrylist+k;
256 qsort(entryindex,entries,sizeof(long),dascsort);
258 p[k]=v->entrylist[(entryindex[entries/2])*v->elements+k];
260 p[k]=(v->entrylist[(entryindex[entries/2])*v->elements+k]+
261 v->entrylist[(entryindex[entries/2-1])*v->elements+k])/2.;
267 /* try every normal, but just for distance */
268 for(j=0;j<entries;j++){
269 double *ppj=_now(v,entryindex[j]);
270 double this=_dist_sq(v,p,ppj);
277 pq_center_out(v,n,&c,p,_point(v,pointindex[bestj]));
282 /* find cells enclosing points */
283 /* count A/B points */
285 vqsp_count(v,entryindex,entries,
289 &entriesA,&entriesB,&entriesC);
291 /* the point index is split evenly, so we do an Order n
292 rearrangement into A first/B last and just pass it on */
299 for(k=0;k<v->elements;k++)
300 position+=_point(v,pointindex[Aptr])[k]*n[k];
301 if(position<=0.)break; /* not in A */
306 for(k=0;k<v->elements;k++)
307 position+=_point(v,pointindex[Bptr])[k]*n[k];
308 if(position>0.)break; /* not in B */
312 long temp=pointindex[Aptr];
313 pointindex[Aptr]=pointindex[Bptr];
314 pointindex[Bptr]=temp;
320 fprintf(stderr,"split: total=%ld depth=%ld set A=%ld:%ld:%ld=B\n",
321 entries,depth,entriesA-entriesC,entriesC,entriesB-entriesC);
323 long thisaux=b->aux++;
324 if(b->aux>=b->alloc){
326 b->ptr0=realloc(b->ptr0,sizeof(long)*b->alloc);
327 b->ptr1=realloc(b->ptr1,sizeof(long)*b->alloc);
328 b->n=realloc(b->n,sizeof(double)*b->dim*b->alloc);
329 b->c=realloc(b->c,sizeof(double)*b->alloc);
332 memcpy(b->n+b->dim*thisaux,n,sizeof(double)*v->elements);
337 b->ptr0[thisaux]=entryA[0];
339 b->ptr0[thisaux]= -b->aux;
340 ret=lp_split(v,b,entryA,entriesA,pointindex,pointsA,depth+1,slack);
344 b->ptr1[thisaux]=entryB[0];
346 b->ptr1[thisaux]= -b->aux;
347 ret+=lp_split(v,b,entryB,entriesB,pointindex+pointsA,points-pointsA,
356 void vqsp_book(vqgen *v, vqbook *b){
357 long *entryindex=malloc(sizeof(double)*v->entries);
358 long *pointindex=malloc(sizeof(double)*v->points);
361 memset(b,0,sizeof(vqbook));
362 for(i=0;i<v->entries;i++)entryindex[i]=i;
363 for(i=0;i<v->points;i++)pointindex[i]=i;
366 b->entries=v->entries;
369 b->ptr0=malloc(sizeof(long)*b->alloc);
370 b->ptr1=malloc(sizeof(long)*b->alloc);
371 b->n=malloc(sizeof(double)*b->dim*b->alloc);
372 b->c=malloc(sizeof(double)*b->alloc);
373 b->lengthlist=calloc(b->entries,sizeof(long));
375 /* first, generate the encoding decision heirarchy */
376 fprintf(stderr,"Total leaves: %d\n",
377 lp_split(v,b,entryindex,v->entries, pointindex,v->points,0,0));
382 /* run all training points through the decision tree to get a final
385 long *probability=calloc(b->entries,sizeof(long));
386 long *membership=malloc(b->entries*sizeof(long));
388 for(i=0;i<v->points;i++){
389 int ret=vqenc_entry(b,v->pointlist+i*v->elements);
392 for(i=0;i<v->entries;i++)membership[i]=i;
394 /* find codeword lengths */
395 /* much more elegant means exist. Brute force n^2, minimum thought */
396 for(i=v->entries;i>1;i--){
397 int first=-1,second=-1;
398 long least=v->points+1;
400 /* find the two nodes to join */
401 for(j=0;j<v->entries;j++)
402 if(probability[j]<least){
403 least=probability[j];
407 for(j=0;j<v->entries;j++)
408 if(probability[j]<least && membership[j]!=first){
409 least=probability[j];
410 second=membership[j];
412 if(first==-1 || second==-1){
413 fprintf(stderr,"huffman fault; no free branch\n");
418 least=probability[first]+probability[second];
419 for(j=0;j<v->entries;j++)
420 if(membership[j]==first || membership[j]==second){
422 probability[j]=least;
426 for(i=0;i<v->entries-1;i++)
427 if(membership[i]!=membership[i+1]){
428 fprintf(stderr,"huffman fault; failed to build single tree\n");
432 /* unneccessary metric */
433 memset(probability,0,sizeof(long)*v->entries);
434 for(i=0;i<v->points;i++){
435 int ret=vqenc_entry(b,v->pointlist+i*v->elements);
439 /* print the results */
440 for(i=0;i<v->entries;i++)
441 fprintf(stderr,"%ld: count=%ld codelength=%ld\n",i,probability[i],b->lengthlist[i]);
447 /* Sort the entries by codeword length, short to long (eases
448 assignment and packing to do it now) */
450 long *wordlen=b->lengthlist;
451 long *index=malloc(b->entries*sizeof(long));
452 long *revindex=malloc(b->entries*sizeof(long));
454 for(i=0;i<b->entries;i++)index[i]=i;
455 isortvals=b->lengthlist;
456 qsort(index,b->entries,sizeof(long),iascsort);
458 /* rearrange storage; ptr0/1 first as it needs a reverse index */
459 /* n and c stay unchanged */
460 for(i=0;i<b->entries;i++)revindex[index[i]]=i;
461 for(i=0;i<b->aux;i++){
462 if(b->ptr0[i]>=0)b->ptr0[i]=revindex[i];
463 if(b->ptr1[i]>=0)b->ptr1[i]=revindex[i];
467 /* map lengthlist and vallist with index */
468 b->lengthlist=calloc(b->entries,sizeof(long));
469 b->valuelist=malloc(sizeof(double)*b->entries*b->dim);
470 for(i=0;i<b->entries;i++){
472 for(k=0;k<b->dim;k++)
473 b->valuelist[i*b->dim+k]=v->entrylist[e*b->dim+k];
474 b->lengthlist[i]=wordlen[e];
480 /* generate the codewords (short to long) */
484 b->codelist=malloc(sizeof(long)*b->entries);
485 for(i=0;i<b->entries;i++){
486 if(length != b->lengthlist[i]){
487 current<<=(b->lengthlist[i]-length);
488 length=b->lengthlist[i];
490 b->codelist[i]=current;
491 fprintf(stderr,"codeword %ld: %ld (length %d)\n",
492 i, current, b->lengthlist[i]);
497 /* sanity check the codewords */
498 for(i=0;i<b->entries;i++){
499 for(j=i+1;j<b->entries;j++){
500 if(b->codelist[i]==b->codelist[j]){
501 fprintf(stderr,"Error; codewords for %ld and %ld both equal %lx\n",
502 i, j, b->codelist[i]);
510 int vqenc_entry(vqbook *b,double *val){
513 double c= -b->c[ptr];
514 double *nptr=b->n+b->dim*ptr;
515 for(k=0;k<b->dim;k++)