#include #include #include "qbase.h" /*---------------------------------------------------------------------------*\ quantise Quantises vec by choosing the nearest vector in codebook cb, and returns the vector index. The squared error of the quantised vector is added to se. \*---------------------------------------------------------------------------*/ long CQbase::quantise(const float *cb, float vec[], float w[], int k, int m, float *se) /* float cb[][K]; current VQ codebook */ /* float vec[]; vector to quantise */ /* float w[]; weighting vector */ /* int k; dimension of vectors */ /* int m; size of codebook */ /* float *se; accumulated squared error */ { float e; /* current error */ long besti; /* best index so far */ float beste; /* best error so far */ long j; int i; float diff; besti = 0; beste = 1E32; for(j=0; jWo/PI)*4000.0/50.0)/log10f(2); x[1] = 10.0*log10f(1e-4 + e); compute_weights2(x, xq, w); for (i=0; iWo_min; float Wo_max = c2const->Wo_max; for (i=0; iWo = powf(2.0, xq[0])*(PI*50.0)/4000.0; /* bit errors can make us go out of range leading to all sorts of probs like seg faults */ if (model->Wo > Wo_max) model->Wo = Wo_max; if (model->Wo < Wo_min) model->Wo = Wo_min; model->L = PI/model->Wo; /* if we quantise Wo re-compute L */ *e = exp10f(xq[1]/10.0); } void CQbase::compute_weights2(const float *x, const float *xp, float *w) { w[0] = 30; w[1] = 1; if (x[1]<0) { w[0] *= .6; w[1] *= .3; } if (x[1]<-10) { w[0] *= .3; w[1] *= .3; } /* Higher weight if pitch is stable */ if (fabsf(x[0]-xp[0])<.2) { w[0] *= 2; w[1] *= 1.5; } else if (fabsf(x[0]-xp[0])>.5) /* Lower if not stable */ { w[0] *= .5; } /* Lower weight for low energy */ if (x[1] < xp[1]-10) { w[1] *= .5; } if (x[1] < xp[1]-20) { w[1] *= .5; } //w[0] = 30; //w[1] = 1; /* Square the weights because it's applied on the squared error */ w[0] *= w[0]; w[1] *= w[1]; } int CQbase::find_nearest_weighted(const float *codebook, int nb_entries, float *x, const float *w, int ndim) { int i, j; float min_dist = 1e15; int nearest = 0; for (i=0; iWo_min; float Wo_max = c2const->Wo_max; float norm; norm = (log10f(Wo) - log10f(Wo_min))/(log10f(Wo_max) - log10f(Wo_min)); index = floorf(Wo_levels * norm + 0.5); if (index < 0 ) index = 0; if (index > (Wo_levels-1)) index = Wo_levels-1; return index; } /*---------------------------------------------------------------------------*\ FUNCTION....: decode_log_Wo() AUTHOR......: David Rowe DATE CREATED: 22/8/2010 Decodes Wo using a WO_LEVELS quantiser in the log domain. \*---------------------------------------------------------------------------*/ float CQbase::decode_log_Wo(C2CONST *c2const, int index, int bits) { float Wo_min = c2const->Wo_min; float Wo_max = c2const->Wo_max; float step; float Wo; int Wo_levels = 1<