1 /********************************************************************
3 * THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
4 * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
5 * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
6 * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
8 * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
9 * by the Xiph.Org Foundation http://www.xiph.org/ *
11 ********************************************************************
13 function: metrics and quantization code for residue VQ codebooks
14 last mod: $Id: residuedata.c 16037 2009-05-26 21:10:58Z xiphmont $
16 ********************************************************************/
24 #include "../lib/scales.h"
28 char *vqext_booktype
="RESdata";
29 quant_meta q
={0,0,0,0}; /* set sequence data */
32 static float *quant_save
=NULL
;
34 float *vqext_weight(vqgen
*v
,float *p
){
38 /* quantize aligned on unit boundaries. Because our grid is likely
39 very coarse, play 'shuffle the blocks'; don't allow multiple
40 entries to fill the same spot as is nearly certain to happen. */
42 void vqext_quantize(vqgen
*v
,quant_meta
*q
){
47 float *test
=alloca(sizeof(float)*dim
);
51 /* allow movement only to unoccupied coordinates on the coarse grid */
54 float val
=_now(v
,j
)[k
];
55 float norm
=rint(fabs(val
)/scalequant
);
60 /* allow move only if unoccupied */
63 if(j
!=k
&& memcmp(test
,quant_save
+dim
*k
,dim
*sizeof(float))==0)
66 if(memcmp(test
,quant_save
+dim
*j
,dim
*sizeof(float)))
68 memcpy(quant_save
+dim
*j
,test
,sizeof(float)*dim
);
71 memcpy(_now(v
,j
),test
,sizeof(float)*dim
);
75 /* unlike the other trainers, we fill in our quantization
76 information (as we know granularity beforehand and don't need to
79 q
->min
=_float32_pack(0.f
);
80 q
->delta
=_float32_pack(scalequant
);
84 memcpy(_now(v
,0),quant_save
,sizeof(float)*dim
*n
);
85 fprintf(stderr
,"cells shifted this iteration: %d\n",moved
);
89 /* candidate,actual */
90 float vqext_metric(vqgen
*v
,float *e
, float *p
){
93 for(i
=0;i
<v
->elements
;i
++){
100 /* We don't interleave here; we assume that the interleave is provided
101 for us by residuesplit in vorbis/huff/ */
102 void vqext_addpoint_adj(vqgen
*v
,float *b
,int start
,int dim
,int cols
,int num
){
103 vqgen_addpoint(v
,b
+start
,NULL
);
106 /* need to reseed because of the coarse quantization we tend to use on
107 residuals (which causes lots & lots of dupes) */
108 void vqext_preprocess(vqgen
*v
){
110 float *test
=alloca(sizeof(float)*v
->elements
);
113 vqext_quantize(v
,&q
);
114 vqgen_unquantize(v
,&q
);
116 /* if there are any dupes, reseed */
117 for(k
=0;k
<v
->entries
;k
++){
119 if(memcmp(_now(v
,k
),_now(v
,l
),sizeof(float)*v
->elements
)==0)
126 fprintf(stderr
,"reseeding with quantization....\n");
128 /* seed the inputs to input points, but points on unit boundaries,
129 ignoring quantbits for now, making sure each seed is unique */
131 for(i
=0,j
=0;i
<v
->points
&& j
<v
->entries
;i
++){
132 for(k
=0;k
<v
->elements
;k
++){
133 float val
=_point(v
,i
)[k
];
134 test
[k
]=rint(val
/scalequant
)*scalequant
;
138 for(k
=0;k
<v
->elements
;k
++)
139 if(test
[k
]!=_now(v
,l
)[k
])
141 if(k
==v
->elements
)break;
144 memcpy(_now(v
,j
),test
,v
->elements
*sizeof(float));
150 fprintf(stderr
,"Not enough unique entries after prequantization\n");
154 vqext_quantize(v
,&q
);
155 quant_save
=_ogg_malloc(sizeof(float)*v
->elements
*v
->entries
);
156 memcpy(quant_save
,_now(v
,0),sizeof(float)*v
->elements
*v
->entries
);
157 vqgen_unquantize(v
,&q
);