1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
|
/********************************************************************
* *
* THIS FILE IS PART OF THE OggVorbis SOFTWARE CODEC SOURCE CODE. *
* USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS *
* GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
* IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING. *
* *
* THE OggVorbis SOURCE CODE IS (C) COPYRIGHT 1994-2001 *
* by the Xiph.Org Foundation http://www.xiph.org/ *
* *
********************************************************************
function: metrics and quantization code for LSP VQ codebooks
last mod: $Id: lspdata.c,v 1.4 2008-02-02 15:54:08 richardash1981 Exp $
********************************************************************/
#include <stdlib.h>
#include <math.h>
#include <stdio.h>
#include "vqgen.h"
#include "vqext.h"
#include "codebook.h"
char *vqext_booktype="LSPdata";
quant_meta q={0,0,0,1}; /* set sequence data */
int vqext_aux=1;
float global_maxdel=M_PI;
float global_mindel=M_PI;
#if 0
void vqext_quantize(vqgen *v,quant_meta *q){
float delta,mindel;
float maxquant=((1<<q->quant)-1);
int j,k;
/* first find the basic delta amount from the maximum span to be
encoded. Loosen the delta slightly to allow for additional error
during sequence quantization */
delta=(global_maxdel-global_mindel)/((1<<q->quant)-1.5f);
q->min=_float32_pack(global_mindel);
q->delta=_float32_pack(delta);
mindel=_float32_unpack(q->min);
delta=_float32_unpack(q->delta);
for(j=0;j<v->entries;j++){
float last=0;
for(k=0;k<v->elements;k++){
float val=_now(v,j)[k];
float now=rint((val-last-mindel)/delta);
_now(v,j)[k]=now;
if(now<0){
/* be paranoid; this should be impossible */
fprintf(stderr,"fault; quantized value<0\n");
exit(1);
}
if(now>maxquant){
/* be paranoid; this should be impossible */
fprintf(stderr,"fault; quantized value>max\n");
exit(1);
}
last=(now*delta)+mindel+last;
}
}
}
#else
void vqext_quantize(vqgen *v,quant_meta *q){
vqgen_quantize(v,q);
}
#endif
float *weight=NULL;
#if 0
/* LSP training metric. We weight error proportional to distance
*between* LSP vector values. The idea of this metric is not to set
final cells, but get the midpoint spacing into a form conducive to
what we want, which is weighting toward preserving narrower
features. */
#define FUDGE (global_maxdel-weight[i])
float *vqext_weight(vqgen *v,float *p){
int i;
int el=v->elements;
float lastp=0.f;
for(i=0;i<el;i++){
float predist=(p[i]-lastp);
float postdist=(p[i+1]-p[i]);
weight[i]=(predist<postdist?predist:postdist);
lastp=p[i];
}
return p;
}
#else
#define FUDGE 1.f
float *vqext_weight(vqgen *v,float *p){
return p;
}
#endif
/* candidate,actual */
float vqext_metric(vqgen *v,float *e, float *p){
int i;
int el=v->elements;
float acc=0.f;
for(i=0;i<el;i++){
float val=(p[i]-e[i])*FUDGE;
acc+=val*val;
}
return sqrt(acc/v->elements);
}
/* Data files are line-vectors, now just deltas. The codebook entries
want to be monotonically increasing, so we adjust */
/* assume vqext_aux==1 */
void vqext_addpoint_adj(vqgen *v,float *b,int start,int dim,int cols,int num){
float *a=alloca(sizeof(float)*(dim+1)); /* +aux */
float base=0;
int i;
for(i=0;i<dim;i++)
base=a[i]=b[i+start]+base;
if(start+dim+1>cols) /* +aux */
a[i]=M_PI;
else
a[i]=b[i+start]+base;
vqgen_addpoint(v,a,a+dim);
}
/* we just need to calc the global_maxdel from the training set */
void vqext_preprocess(vqgen *v){
long j,k;
global_maxdel=0.f;
global_mindel=M_PI;
for(j=0;j<v->points;j++){
float last=0.;
for(k=0;k<v->elements+v->aux;k++){
float p=_point(v,j)[k];
if(p-last>global_maxdel)global_maxdel=p-last;
if(p-last<global_mindel)global_mindel=p-last;
last=p;
}
}
weight=_ogg_malloc(sizeof(float)*v->elements);
}
|