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 LSP VQ codebooks
14 last mod: $Id: lspdata.c 16037 2009-05-26 21:10:58Z xiphmont $
16 ********************************************************************/
25 char *vqext_booktype
="LSPdata";
26 quant_meta q
={0,0,0,1}; /* set sequence data */
29 float global_maxdel
=M_PI
;
30 float global_mindel
=M_PI
;
32 void vqext_quantize(vqgen
*v
,quant_meta
*q
){
34 float maxquant
=((1<<q
->quant
)-1);
37 /* first find the basic delta amount from the maximum span to be
38 encoded. Loosen the delta slightly to allow for additional error
39 during sequence quantization */
41 delta
=(global_maxdel
-global_mindel
)/((1<<q
->quant
)-1.5f
);
43 q
->min
=_float32_pack(global_mindel
);
44 q
->delta
=_float32_pack(delta
);
46 mindel
=_float32_unpack(q
->min
);
47 delta
=_float32_unpack(q
->delta
);
49 for(j
=0;j
<v
->entries
;j
++){
51 for(k
=0;k
<v
->elements
;k
++){
52 float val
=_now(v
,j
)[k
];
53 float now
=rint((val
-last
-mindel
)/delta
);
57 /* be paranoid; this should be impossible */
58 fprintf(stderr
,"fault; quantized value<0\n");
63 /* be paranoid; this should be impossible */
64 fprintf(stderr
,"fault; quantized value>max\n");
67 last
=(now
*delta
)+mindel
+last
;
73 void vqext_quantize(vqgen
*v
,quant_meta
*q
){
80 /* LSP training metric. We weight error proportional to distance
81 *between* LSP vector values. The idea of this metric is not to set
82 final cells, but get the midpoint spacing into a form conducive to
83 what we want, which is weighting toward preserving narrower
86 #define FUDGE (global_maxdel-weight[i])
88 float *vqext_weight(vqgen
*v
,float *p
){
93 float predist
=(p
[i
]-lastp
);
94 float postdist
=(p
[i
+1]-p
[i
]);
95 weight
[i
]=(predist
<postdist
?predist
:postdist
);
102 float *vqext_weight(vqgen
*v
,float *p
){
107 /* candidate,actual */
108 float vqext_metric(vqgen
*v
,float *e
, float *p
){
113 float val
=(p
[i
]-e
[i
])*FUDGE
;
116 return sqrt(acc
/v
->elements
);
119 /* Data files are line-vectors, now just deltas. The codebook entries
120 want to be monotonically increasing, so we adjust */
122 /* assume vqext_aux==1 */
123 void vqext_addpoint_adj(vqgen
*v
,float *b
,int start
,int dim
,int cols
,int num
){
124 float *a
=alloca(sizeof(float)*(dim
+1)); /* +aux */
129 base
=a
[i
]=b
[i
+start
]+base
;
131 if(start
+dim
+1>cols
) /* +aux */
134 a
[i
]=b
[i
+start
]+base
;
136 vqgen_addpoint(v
,a
,a
+dim
);
139 /* we just need to calc the global_maxdel from the training set */
140 void vqext_preprocess(vqgen
*v
){
145 for(j
=0;j
<v
->points
;j
++){
147 for(k
=0;k
<v
->elements
+v
->aux
;k
++){
148 float p
=_point(v
,j
)[k
];
149 if(p
-last
>global_maxdel
)global_maxdel
=p
-last
;
150 if(p
-last
<global_mindel
)global_mindel
=p
-last
;
155 weight
=_ogg_malloc(sizeof(float)*v
->elements
);