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 iascsort(const void *a,const void *b){
65 double av=sortvals[*((long *)a) * els];
66 double bv=sortvals[*((long *)b) * els];
71 extern double _dist_sq(vqgen *v,double *a, double *b);
73 /* goes through the split, but just counts it and returns a metric*/
74 void vqsp_count(vqgen *v,long *entryindex,long entries,
75 long *pointindex,long points,
76 long *entryA,long *entryB,
77 double *n, double c, double slack,
78 long *entriesA,long *entriesB,long *entriesC){
82 memset(entryA,0,sizeof(long)*entries);
83 memset(entryB,0,sizeof(long)*entries);
85 for(i=0;i<points;i++){
86 double *ppt=_point(v,pointindex[i]);
88 double firstmetric=_dist_sq(v,_now(v,entryindex[0]),ppt);
91 for(j=1;j<entries;j++){
92 double thismetric=_dist_sq(v,_now(v,entryindex[j]),ppt);
93 if(thismetric<firstmetric){
94 firstmetric=thismetric;
99 /* count point split */
100 for(k=0;k<v->elements;k++)
101 position+=ppt[k]*n[k];
103 entryA[firstentry]++;
105 entryB[firstentry]++;
109 /* look to see if entries are in the slack zone */
110 /* The entry splitting isn't total, so that storage has to be
111 allocated for recursion. Reuse the entryA/entryB vectors */
112 for(j=0;j<entries;j++){
113 long total=entryA[j]+entryB[j];
114 if((double)entryA[j]/total<slack){
116 }else if((double)entryB[j]/total<slack){
119 if(entryA[j] && entryB[j])C++;
120 if(entryA[j])entryA[A++]=entryindex[j];
121 if(entryB[j])entryB[B++]=entryindex[j];
128 void pq_in_out(vqgen *v,double *n,double *c,double *p,double *q){
131 for(k=0;k<v->elements;k++){
132 double center=(p[k]+q[k])/2.;
133 n[k]=(center-q[k])*2.;
138 void pq_center_out(vqgen *v,double *n,double *c,double *center,double *q){
141 for(k=0;k<v->elements;k++){
142 n[k]=(center[k]-q[k])*2.;
147 static void spinnit(void){
149 static long lasttime=0;
151 struct timeval thistime;
153 gettimeofday(&thistime,NULL);
154 test=thistime.tv_sec*10+thistime.tv_usec/100000;
161 fprintf(stderr,"|\b");
164 fprintf(stderr,"/\b");
167 fprintf(stderr,"-\b");
170 fprintf(stderr,"\\\b");
177 int lp_split(vqgen *v,vqbook *b,
178 long *entryindex,long entries,
179 long *pointindex,long points,
180 long depth,double slack){
182 /* The encoder, regardless of book, will be using a straight
183 euclidian distance-to-point metric to determine closest point.
184 Thus we split the cells using the same (we've already trained the
185 codebook set spacing and distribution using special metrics and
186 even a midpoint division won't disturb the basic properties) */
193 long *entryA=calloc(entries,sizeof(long));
194 long *entryB=calloc(entries,sizeof(long));
201 p=alloca(sizeof(double)*v->elements);
202 q=alloca(sizeof(double)*v->elements);
203 n=alloca(sizeof(double)*v->elements);
204 memset(p,0,sizeof(double)*v->elements);
206 /* We need to find the dividing hyperplane. find the median of each
207 axis as the centerpoint and the normal facing farthest point */
209 /* more than one way to do this part. For small sets, we can brute
213 /* try every pair possibility */
218 for(i=0;i<entries-1;i++){
219 for(j=i+1;j<entries;j++){
221 pq_in_out(v,n,&c,_now(v,entryindex[i]),_now(v,entryindex[j]));
222 vqsp_count(v,entryindex,entries,
226 &entriesA,&entriesB,&entriesC);
227 this=(entriesA-entriesC)*(entriesB-entriesC);
236 pq_in_out(v,n,&c,_now(v,entryindex[besti]),_now(v,entryindex[bestj]));
241 /* try COG/normal and furthest pairs */
243 for(k=0;k<v->elements;k++){
246 /* just sort the index array */
247 sortvals=v->entrylist+k;
249 qsort(entryindex,entries,sizeof(long),iascsort);
251 p[k]=v->entrylist[(entryindex[entries/2])*v->elements+k];
253 p[k]=(v->entrylist[(entryindex[entries/2])*v->elements+k]+
254 v->entrylist[(entryindex[entries/2-1])*v->elements+k])/2.;
260 /* try every normal, but just for distance */
261 for(j=0;j<entries;j++){
262 double *ppj=_now(v,entryindex[j]);
263 double this=_dist_sq(v,p,ppj);
270 pq_center_out(v,n,&c,p,_point(v,pointindex[bestj]));
275 /* find cells enclosing points */
276 /* count A/B points */
278 vqsp_count(v,entryindex,entries,
282 &entriesA,&entriesB,&entriesC);
284 /* the point index is split evenly, so we do an Order n
285 rearrangement into A first/B last and just pass it on */
292 for(k=0;k<v->elements;k++)
293 position+=_point(v,pointindex[Aptr])[k]*n[k];
294 if(position<=0.)break; /* not in A */
299 for(k=0;k<v->elements;k++)
300 position+=_point(v,pointindex[Bptr])[k]*n[k];
301 if(position>0.)break; /* not in B */
305 long temp=pointindex[Aptr];
306 pointindex[Aptr]=pointindex[Bptr];
307 pointindex[Bptr]=temp;
313 fprintf(stderr,"split: total=%ld depth=%ld set A=%ld:%ld:%ld=B\n",
314 entries,depth,entriesA-entriesC,entriesC,entriesB-entriesC);
316 long thisaux=b->aux++;
317 if(b->aux>=b->alloc){
319 b->ptr0=realloc(b->ptr0,sizeof(long)*b->alloc);
320 b->ptr1=realloc(b->ptr1,sizeof(long)*b->alloc);
321 b->n=realloc(b->n,sizeof(double)*b->elements*b->alloc);
322 b->c=realloc(b->c,sizeof(double)*b->alloc);
325 memcpy(b->n+b->elements*thisaux,n,sizeof(double)*v->elements);
330 b->ptr0[thisaux]=entryA[0];
332 b->ptr0[thisaux]= -b->aux;
333 ret=lp_split(v,b,entryA,entriesA,pointindex,pointsA,depth+1,slack);
337 b->ptr1[thisaux]=entryB[0];
339 b->ptr1[thisaux]= -b->aux;
340 ret+=lp_split(v,b,entryB,entriesB,pointindex+pointsA,points-pointsA,
349 void vqsp_book(vqgen *v, vqbook *b){
350 long *entryindex=malloc(sizeof(double)*v->entries);
351 long *pointindex=malloc(sizeof(double)*v->points);
354 memset(b,0,sizeof(vqbook));
355 for(i=0;i<v->entries;i++)entryindex[i]=i;
356 for(i=0;i<v->points;i++)pointindex[i]=i;
358 b->elements=v->elements;
359 b->entries=v->entries;
361 b->ptr0=malloc(sizeof(long)*b->alloc);
362 b->ptr1=malloc(sizeof(long)*b->alloc);
363 b->n=malloc(sizeof(double)*b->elements*b->alloc);
364 b->c=malloc(sizeof(double)*b->alloc);
366 b->valuelist=v->entrylist;
367 b->codelist=malloc(sizeof(long)*b->entries);
368 b->lengthlist=calloc(b->entries,sizeof(long));
370 /* first, generate the encoding decision heirarchy */
371 fprintf(stderr,"Total leaves: %d\n",
372 lp_split(v,b,entryindex,v->entries, pointindex,v->points,0,0));
374 /* run all training points through the decision tree to get a final
377 long *probability=calloc(b->entries,sizeof(long));
378 long *membership=malloc(b->entries*sizeof(long));
381 for(i=0;i<v->points;i++){
382 int ret=vqenc_entry(b,v->pointlist+i*v->elements);
385 for(i=0;i<v->entries;i++)membership[i]=i;
387 /* find codeword lengths */
388 /* much more elegant means exist. Brute force n^2, minimum thought */
389 for(i=v->entries;i>1;i--){
390 int first=-1,second=-1;
391 long least=v->points+1;
393 /* find the two nodes to join */
394 for(j=0;j<v->entries;j++)
395 if(probability[j]<least){
396 least=probability[j];
400 for(j=0;j<v->entries;j++)
401 if(probability[j]<least && membership[j]!=first){
402 least=probability[j];
403 second=membership[j];
405 if(first==-1 || second==-1){
406 fprintf(stderr,"huffman fault; no free branch\n");
411 least=probability[first]+probability[second];
412 for(j=0;j<v->entries;j++)
413 if(membership[j]==first || membership[j]==second){
415 probability[j]=least;
419 for(i=0;i<v->entries-1;i++)
420 if(membership[i]!=membership[i+1]){
421 fprintf(stderr,"huffman fault; failed to build single tree\n");
425 /* unneccessary metric */
426 memset(probability,0,sizeof(long)*v->entries);
427 for(i=0;i<v->points;i++){
428 int ret=vqenc_entry(b,v->pointlist+i*v->elements);
432 /* print the results */
433 for(i=0;i<v->entries;i++)
434 fprintf(stderr,"%d: count=%ld codelength=%d\n",i,probability[i],b->lengthlist[i]);
440 /* rearrange, sort by codelength */
443 /* generate the codewords (short to long) */
450 int vqenc_entry(vqbook *b,double *val){
453 double c= -b->c[ptr];
454 double *nptr=b->n+b->elements*ptr;
455 for(k=0;k<b->elements;k++)