Update tizen 2.0 beta source
[external/libvorbis.git] / vq / lspdata.c
1 /********************************************************************
2  *                                                                  *
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.       *
7  *                                                                  *
8  * THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001             *
9  * by the Xiph.Org Foundation http://www.xiph.org/                  *
10  *                                                                  *
11  ********************************************************************
12
13  function: metrics and quantization code for LSP VQ codebooks
14  last mod: $Id: lspdata.c 16037 2009-05-26 21:10:58Z xiphmont $
15
16  ********************************************************************/
17
18 #include <stdlib.h>
19 #include <math.h>
20 #include <stdio.h>
21 #include "vqgen.h"
22 #include "vqext.h"
23 #include "codebook.h"
24
25 char *vqext_booktype="LSPdata";  
26 quant_meta q={0,0,0,1};          /* set sequence data */
27 int vqext_aux=1;
28
29 float global_maxdel=M_PI;
30 float global_mindel=M_PI;
31 #if 0
32 void vqext_quantize(vqgen *v,quant_meta *q){
33   float delta,mindel;
34   float maxquant=((1<<q->quant)-1);
35   int j,k;
36
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 */
40
41   delta=(global_maxdel-global_mindel)/((1<<q->quant)-1.5f);
42   
43   q->min=_float32_pack(global_mindel);
44   q->delta=_float32_pack(delta);
45
46   mindel=_float32_unpack(q->min);
47   delta=_float32_unpack(q->delta);
48
49   for(j=0;j<v->entries;j++){
50     float last=0;
51     for(k=0;k<v->elements;k++){
52       float val=_now(v,j)[k];
53       float now=rint((val-last-mindel)/delta);
54       
55       _now(v,j)[k]=now;
56       if(now<0){
57         /* be paranoid; this should be impossible */
58         fprintf(stderr,"fault; quantized value<0\n");
59         exit(1);
60       }
61
62       if(now>maxquant){
63         /* be paranoid; this should be impossible */
64         fprintf(stderr,"fault; quantized value>max\n");
65         exit(1);
66       }
67       last=(now*delta)+mindel+last;
68     }
69   }
70
71 }
72 #else
73 void vqext_quantize(vqgen *v,quant_meta *q){
74   vqgen_quantize(v,q);
75 }
76 #endif
77
78 float *weight=NULL;
79 #if 0
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
84    features. */
85
86 #define FUDGE (global_maxdel-weight[i])
87
88 float *vqext_weight(vqgen *v,float *p){
89   int i;
90   int el=v->elements;
91   float lastp=0.f;
92   for(i=0;i<el;i++){
93     float predist=(p[i]-lastp);
94     float postdist=(p[i+1]-p[i]);
95     weight[i]=(predist<postdist?predist:postdist);
96     lastp=p[i];
97   }
98   return p;
99 }
100 #else
101 #define FUDGE 1.f
102 float *vqext_weight(vqgen *v,float *p){
103   return p;
104 }
105 #endif
106
107                             /* candidate,actual */
108 float vqext_metric(vqgen *v,float *e, float *p){
109   int i;
110   int el=v->elements;
111   float acc=0.f;
112   for(i=0;i<el;i++){
113     float val=(p[i]-e[i])*FUDGE;
114     acc+=val*val;
115   }
116   return sqrt(acc/v->elements);
117 }
118
119 /* Data files are line-vectors, now just deltas.  The codebook entries
120    want to be monotonically increasing, so we adjust */
121
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 */
125   float base=0;
126   int i;
127
128   for(i=0;i<dim;i++)
129     base=a[i]=b[i+start]+base;
130
131   if(start+dim+1>cols) /* +aux */
132     a[i]=M_PI;
133   else
134     a[i]=b[i+start]+base;
135   
136   vqgen_addpoint(v,a,a+dim);
137 }
138
139 /* we just need to calc the global_maxdel from the training set */
140 void vqext_preprocess(vqgen *v){
141   long j,k;
142
143   global_maxdel=0.f;
144   global_mindel=M_PI;
145   for(j=0;j<v->points;j++){
146     float last=0.;
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;
151       last=p;
152     }
153   }
154
155   weight=_ogg_malloc(sizeof(float)*v->elements);
156 }
157