Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/libvorbis-1.2.0/vq/lspdata.c @ 28

Last change on this file since 28 was 16, checked in by landauf, 17 years ago

added libvorbis

File size: 4.1 KB
Line 
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 13293 2007-07-24 00:09:47Z 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
25char *vqext_booktype="LSPdata"; 
26quant_meta q={0,0,0,1};          /* set sequence data */
27int vqext_aux=1;
28
29float global_maxdel=M_PI;
30float global_mindel=M_PI;
31#if 0
32void 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
73void vqext_quantize(vqgen *v,quant_meta *q){
74  vqgen_quantize(v,q);
75}
76#endif
77
78float *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
88float *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
102float *vqext_weight(vqgen *v,float *p){
103  return p;
104}
105#endif
106
107                            /* candidate,actual */
108float 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 */
123void 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 */
140void 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
Note: See TracBrowser for help on using the repository browser.