123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- /********************************************************************
- * *
- * THIS FILE IS PART OF THE Ogg Vorbis SOFTWARE CODEC SOURCE CODE. *
- * USE, DISTRIBUTION AND REPRODUCTION OF THIS SOURCE IS GOVERNED BY *
- * THE GNU PUBLIC LICENSE 2, WHICH IS INCLUDED WITH THIS SOURCE. *
- * PLEASE READ THESE TERMS DISTRIBUTING. *
- * *
- * THE OggSQUISH SOURCE CODE IS (C) COPYRIGHT 1994-2000 *
- * by Monty <monty@xiph.org> and The XIPHOPHORUS Company *
- * http://www.xiph.org/ *
- * *
- ********************************************************************
- function: metrics and quantization code for LSP VQ codebooks
- last mod: $Id: lspdata.c,v 1.11.4.5 2000/05/06 05:41:14 xiphmont Exp $
- ********************************************************************/
- #include <stdlib.h>
- #include <math.h>
- #include <stdio.h>
- #include "vqgen.h"
- #include "vqext.h"
- #include "../lib/sharedbook.h"
- char *vqext_booktype="LSPdata";
- quant_meta q={0,0,0,1}; /* set sequence data */
- int vqext_aux=1;
- double global_maxdel=M_PI;
- double global_mindel=M_PI;
- #if 0
- void vqext_quantize(vqgen *v,quant_meta *q){
- double delta,mindel;
- double 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.5);
-
- 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++){
- double last=0;
- for(k=0;k<v->elements;k++){
- double val=_now(v,j)[k];
- double 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
- double *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])
- double *vqext_weight(vqgen *v,double *p){
- int i;
- int el=v->elements;
- double lastp=0.;
- for(i=0;i<el;i++){
- double predist=(p[i]-lastp);
- double postdist=(p[i+1]-p[i]);
- weight[i]=(predist<postdist?predist:postdist);
- lastp=p[i];
- }
- return p;
- }
- #else
- #define FUDGE 1.
- double *vqext_weight(vqgen *v,double *p){
- return p;
- }
- #endif
- /* candidate,actual */
- double vqext_metric(vqgen *v,double *e, double *p){
- int i;
- int el=v->elements;
- double acc=0.;
- for(i=0;i<el;i++){
- double val=(p[i]-e[i])*FUDGE;
- acc+=val*val;
- }
- return sqrt(acc/v->elements);
- }
- /* Data files are line-vectors, starting with zero. If we want to
- train on a subvector starting in the middle, we need to adjust the
- data as if it was starting at zero. we also need to add the 'aux'
- value, which is an extra point at the end so we have leading and
- trailing space */
- /* assume vqext_aux==1 */
- void vqext_addpoint_adj(vqgen *v,double *b,int start,int dim,int cols,int num){
- double *a=alloca(sizeof(double)*(dim+1)); /* +aux */
- double base=0;
- int i;
- if(start>0)base=b[start-1];
- for(i=0;i<dim;i++)a[i]=b[i+start]-base;
- if(start+dim+1>cols) /* +aux */
- a[i]=a[i-1];
- 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.;
- global_mindel=M_PI;
- for(j=0;j<v->points;j++){
- double last=0.;
- for(k=0;k<v->elements+v->aux;k++){
- double 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=malloc(sizeof(double)*v->elements);
- }
|