ref: b624cdd2ce3f18172c1ffaab1d5fa2d4d4a5fff4
parent: b0c93c66eac4de48022313a02964a3f662c4863f
author: Jean-Marc Valin <[email protected]>
date: Wed Mar 5 08:40:20 EST 2008
fixed-point: masking curve computation now converted. ***Fixed a bug in the handling of the left side slope of the spreading function (right-side coef was used)
--- a/libcelt/arch.h
+++ b/libcelt/arch.h
@@ -55,7 +55,7 @@
typedef celt_word16_t celt_norm_t;
typedef celt_word32_t celt_ener_t;
typedef celt_word16_t celt_pgain_t;
-typedef float celt_mask_t;
+typedef celt_word32_t celt_mask_t;
#define Q15ONE 32767
#define Q30ONE 1073741823
--- a/libcelt/pitch.c
+++ b/libcelt/pitch.c
@@ -112,7 +112,7 @@
float n, tmp;
/*n = 1.f/(1e1+sqrt(sqrt((X[2*i-1]*X[2*i-1] + X[2*i ]*X[2*i ])*(Y[2*i-1]*Y[2*i-1] + Y[2*i ]*Y[2*i ]))));*/
/*n = 1;*/
- n = 1.f/sqrt(1+curve[i]);
+ n = SIG_SCALING_1/sqrt(1+curve[i]);
/*printf ("%f ", n);*/
/*n = 1.f/(1+curve[i]);*/
tmp = X[2*i];
--- a/libcelt/psy.c
+++ b/libcelt/psy.c
@@ -63,9 +63,9 @@
/* Back to FFT bin units */
deriv *= Fs*(1/(2.f*len));
/* decay corresponding to -10dB/Bark */
- decay->decayR[i] = pow(.1f, deriv);
+ decay->decayR[i] = Q15ONE*pow(.1f, deriv);
/* decay corresponding to -25dB/Bark */
- decay->decayL[i] = pow(0.0031623f, deriv);
+ decay->decayL[i] = Q15ONE*pow(0.0031623f, deriv);
/*printf ("%f %f\n", decayL[i], decayR[i]);*/
}
}
@@ -76,16 +76,18 @@
celt_free(decay->decayL);
}
-static void spreading_func(struct PsyDecay *d, float *psd, celt_mask_t *mask, int len)
+static void spreading_func(struct PsyDecay *d, celt_word32_t *psd, celt_mask_t *mask, int len)
{
int i;
- float mem;
+ celt_word32_t mem;
/*for (i=0;i<len;i++) printf ("%f ", psd[i]);*/
/* Compute right slope (-10 dB/Bark) */
mem=psd[0];
for (i=0;i<len;i++)
{
- mask[i] = (1-d->decayR[i])*psd[i] + d->decayR[i]*mem;
+ mask[i] = MULT16_32_Q15(Q15ONE-d->decayR[i],psd[i]) + MULT16_32_Q15(d->decayR[i],mem);
+ if (mask[i]<1)
+ mask[i]=1;
mem = mask[i];
}
/* Compute left slope (-25 dB/Bark) */
@@ -92,7 +94,9 @@
mem=mask[len-1];
for (i=len-1;i>=0;i--)
{
- mask[i] = (1-d->decayR[i])*mask[i] + d->decayL[i]*mem;
+ mask[i] = MULT16_32_Q15(Q15ONE-d->decayL[i],mask[i]) + MULT16_32_Q15(d->decayL[i],mem);
+ if (mask[i]<1)
+ mask[i]=1;
mem = mask[i];
}
/*for (i=0;i<len;i++) printf ("%f ", mask[i]); printf ("\n");*/
@@ -125,14 +129,15 @@
void compute_masking(struct PsyDecay *decay, celt_word32_t *X, celt_mask_t *mask, int len)
{
int i;
- VARDECL(float *psd);
+ VARDECL(celt_word32_t *psd);
int N;
SAVE_STACK;
N=len/2;
- ALLOC(psd, N, float);
- psd[0] = X[0]*1.f*X[0];
+ ALLOC(psd, N, celt_word32_t);
+ psd[0] = MULT16_16(ROUND(X[0],SIG_SHIFT), ROUND(X[0],SIG_SHIFT));
for (i=1;i<N;i++)
- psd[i] = X[i*2]*1.f*X[i*2] + X[i*2+1]*1.f*X[i*2+1];
+ psd[i] = ADD32(MULT16_16(ROUND(X[i*2],SIG_SHIFT), ROUND(X[i*2],SIG_SHIFT)),
+ MULT16_16(ROUND(X[i*2+1],SIG_SHIFT), ROUND(X[i*2+1],SIG_SHIFT)));
/* TODO: Do tone masking */
/* Noise masking */
spreading_func(decay, psd, mask, N);
@@ -139,6 +144,7 @@
RESTORE_STACK;
}
+#if 0 /* Not needed for now, but will be useful in the future */
void compute_mdct_masking(struct PsyDecay *decay, celt_word32_t *X, celt_mask_t *mask, int len)
{
int i;
@@ -157,3 +163,4 @@
spreading_func(decay, psd, mask, len);
RESTORE_STACK;
}
+#endif
--- a/libcelt/psy.h
+++ b/libcelt/psy.h
@@ -34,8 +34,8 @@
#include "arch.h"
struct PsyDecay {
- float *decayL;
- float *decayR;
+ celt_word16_t *decayL;
+ celt_word16_t *decayR;
};
/** Pre-compute the decay of the psycho-acoustic spreading function */