From b60340f7e311a6126920afed74661c60d87f9d9d Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <Jean-Marc.Valin@csiro.au> Date: Tue, 26 Feb 2008 15:41:51 +1100 Subject: [PATCH] fixed-point: band energy now a 32-bit value. It might have (barely) fix into 16-bit, but at this point, it's not worth the trouble and loss of accuracy. --- libcelt/arch.h | 24 ++++++------------------ libcelt/bands.c | 8 ++++---- libcelt/quant_bands.c | 14 +++++++------- libcelt/vq.c | 8 +++++++- 4 files changed, 24 insertions(+), 30 deletions(-) diff --git a/libcelt/arch.h b/libcelt/arch.h index 49915e557..afb9fd659 100644 --- a/libcelt/arch.h +++ b/libcelt/arch.h @@ -53,25 +53,16 @@ typedef celt_int32_t celt_word32_t; typedef celt_word32_t celt_sig_t; typedef celt_word16_t celt_norm_t; -typedef float celt_ener_t; +typedef celt_word32_t celt_ener_t; #define Q15ONE 32767 -#define LPC_SCALING 8192 #define SIG_SCALING 16384.f #define SIG_SCALING_1 0.000061035 #define NORM_SCALING 16384.f #define NORM_SCALING_1 0.000061035 - -#define LSP_SCALING 8192. -#define GAMMA_SCALING 32768. -#define GAIN_SCALING 64 -#define GAIN_SCALING_1 0.015625 - -#define LPC_SHIFT 13 -#define LSP_SHIFT 13 -#define SIG_SHIFT 14 -#define GAIN_SHIFT 6 +#define ENER_SCALING 16384.f +#define ENER_SCALING_1 0.000061035 #define VERY_SMALL 0 #define VERY_LARGE32 ((celt_word32_t)2147483647) @@ -106,16 +97,13 @@ typedef float celt_norm_t; typedef float celt_ener_t; #define Q15ONE 1.0f -#define LPC_SCALING 1.f + #define SIG_SCALING 1.f #define SIG_SCALING_1 1.f #define NORM_SCALING 1.f #define NORM_SCALING_1 1.f - -#define LSP_SCALING 1.f -#define GAMMA_SCALING 1.f -#define GAIN_SCALING 1.f -#define GAIN_SCALING_1 1.f +#define ENER_SCALING 1.f +#define ENER_SCALING_1 1.f #define VERY_SMALL 1e-15f diff --git a/libcelt/bands.c b/libcelt/bands.c index f6f519fa7..b92606ade 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -84,7 +84,7 @@ void compute_band_energies(const CELTMode *m, celt_sig_t *X, celt_ener_t *bank) float sum = 1e-10; for (j=B*eBands[i];j<B*eBands[i+1];j++) sum += SIG_SCALING_1*SIG_SCALING_1*X[j*C+c]*X[j*C+c]; - bank[i*C+c] = sqrt(sum); + bank[i*C+c] = ENER_SCALING*sqrt(sum); /*printf ("%f ", bank[i*C+c]);*/ } } @@ -103,7 +103,7 @@ void normalise_bands(const CELTMode *m, celt_sig_t *freq, celt_norm_t *X, celt_e for (i=0;i<m->nbEBands;i++) { int j; - float g = 1.f/(1e-10+bank[i*C+c]*sqrt(C)); + float g = 1.f/(1e-10+ENER_SCALING_1*bank[i*C+c]*sqrt(C)); for (j=B*eBands[i];j<B*eBands[i+1];j++) X[j*C+c] = NORM_SCALING*SIG_SCALING_1*freq[j*C+c]*g; } @@ -133,7 +133,7 @@ void denormalise_bands(const CELTMode *m, celt_norm_t *X, celt_sig_t *freq, celt for (i=0;i<m->nbEBands;i++) { int j; - float g = sqrt(C)*bank[i*C+c]; + float g = ENER_SCALING_1*sqrt(C)*bank[i*C+c]; for (j=B*eBands[i];j<B*eBands[i+1];j++) freq[j*C+c] = NORM_SCALING_1*SIG_SCALING*X[j*C+c] * g; } @@ -156,7 +156,7 @@ void compute_pitch_gain(const CELTMode *m, celt_norm_t *X, celt_norm_t *P, float { int j; for (j=B*eBands[i];j<B*eBands[i+1];j++) - w[j] = bank[i]; + w[j] = bank[i]*ENER_SCALING_1; } diff --git a/libcelt/quant_bands.c b/libcelt/quant_bands.c index bd70a0424..2daaa4cd5 100644 --- a/libcelt/quant_bands.c +++ b/libcelt/quant_bands.c @@ -64,7 +64,7 @@ static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, float *old float x; float f; float mean = (1-coef)*eMeans[i]; - x = 20*log10(.3+eBands[i]); + x = 20*log10(.3+ENER_SCALING_1*eBands[i]); res = 6.; f = (x-mean-coef*oldEBands[i]-prev)/res; qi = (int)floor(.5+f); @@ -105,7 +105,7 @@ static void quant_energy_mono(const CELTMode *m, celt_ener_t *eBands, float *old } for (i=0;i<m->nbEBands;i++) { - eBands[i] = pow(10, .05*oldEBands[i])-.3; + eBands[i] = ENER_SCALING*(pow(10, .05*oldEBands[i])-.3); if (eBands[i] < 0) eBands[i] = 0; } @@ -154,7 +154,7 @@ static void unquant_energy_mono(const CELTMode *m, celt_ener_t *eBands, float *o for (i=0;i<m->nbEBands;i++) { /*printf ("%f ", error[i] - offset);*/ - eBands[i] = pow(10, .05*oldEBands[i])-.3; + eBands[i] = ENER_SCALING*(pow(10, .05*oldEBands[i])-.3); if (eBands[i] < 0) eBands[i] = 0; } @@ -200,8 +200,8 @@ void quant_energy(const CELTMode *m, celt_ener_t *eBands, float *oldEBands, int { //left = eBands[C*i]; //right = eBands[C*i+1]; - mid[i] = sqrt(eBands[C*i]*eBands[C*i] + eBands[C*i+1]*eBands[C*i+1]); - side[i] = 20*log10((eBands[2*i]+.3)/(eBands[2*i+1]+.3)); + mid[i] = ENER_SCALING_1*sqrt(eBands[C*i]*eBands[C*i] + eBands[C*i+1]*eBands[C*i+1]); + side[i] = 20*log10((ENER_SCALING_1*eBands[2*i]+.3)/(ENER_SCALING_1*eBands[2*i+1]+.3)); //printf ("%f %f ", mid[i], side[i]); } //printf ("\n"); @@ -212,8 +212,8 @@ void quant_energy(const CELTMode *m, celt_ener_t *eBands, float *oldEBands, int //quant_energy_side(m, side, oldEBands+NB, enc); for (i=0;i<NB;i++) { - eBands[C*i] = mid[i]*sqrt(side[i]/(1.f+side[i])); - eBands[C*i+1] = mid[i]*sqrt(1.f/(1.f+side[i])); + eBands[C*i] = ENER_SCALING*mid[i]*sqrt(side[i]/(1.f+side[i])); + eBands[C*i+1] = ENER_SCALING*mid[i]*sqrt(1.f/(1.f+side[i])); //printf ("%f %f ", mid[i], side[i]); } diff --git a/libcelt/vq.c b/libcelt/vq.c index 91c107e22..452326ec6 100644 --- a/libcelt/vq.c +++ b/libcelt/vq.c @@ -38,6 +38,7 @@ #include "cwrs.h" #include "vq.h" #include "arch.h" +#include "os_support.h" /* Enable this or define your own implementation if you want to speed up the VQ search (used in inner loop only) */ @@ -132,7 +133,9 @@ void alg_quant(celt_norm_t *X, float *W, int N, int K, celt_norm_t *P, float alp Rpp += p[j]*p[j]; Rxp += x[j]*p[j]; } - + if (Rpp>1) + celt_fatal("Rpp > 1"); + /* We only need to initialise the zero because the first iteration only uses that */ for (i=0;i<N;i++) y[0][i] = 0; @@ -221,6 +224,9 @@ void alg_quant(celt_norm_t *X, float *W, int N, int K, celt_norm_t *P, float alp } } + + if (!(nbest[0]->score > -1e10f)) + celt_fatal("Could not find any match in VQ codebook. Something got corrupted somewhere."); /* Only now that we've made the final choice, update ny/iny and others */ for (k=0;k<Lupdate;k++) { -- GitLab