Fixed a bunch of fixed-point overflows on insanely hot signals by changing

the time-domain representation from Q14 to Q12 (Q29 to Q27 using the
standard convention).
This commit is contained in:
Jean-Marc Valin 2008-08-28 23:34:24 -04:00
parent 8dff923a5d
commit 5c3bc67959
6 changed files with 12 additions and 14 deletions

View file

@ -6,7 +6,7 @@ AM_CONFIG_HEADER([config.h])
CELT_MAJOR_VERSION=0 CELT_MAJOR_VERSION=0
CELT_MINOR_VERSION=4 CELT_MINOR_VERSION=4
CELT_MICRO_VERSION=0 CELT_MICRO_VERSION=1
CELT_EXTRA_VERSION= CELT_EXTRA_VERSION=
CELT_VERSION=$CELT_MAJOR_VERSION.$CELT_MINOR_VERSION.$CELT_MICRO_VERSION$CELT_EXTRA_VERSION CELT_VERSION=$CELT_MAJOR_VERSION.$CELT_MINOR_VERSION.$CELT_MICRO_VERSION$CELT_EXTRA_VERSION

View file

@ -71,9 +71,7 @@ typedef celt_word32_t celt_mask_t;
#define Q15ONE 32767 #define Q15ONE 32767
#define Q30ONE 1073741823 #define Q30ONE 1073741823
#define SIG_SCALING 16384.f #define SIG_SHIFT 12
#define SIG_SCALING_1 (1.f/16384.f)
#define SIG_SHIFT 14
#define NORM_SCALING 16384 #define NORM_SCALING 16384
#define NORM_SCALING_1 (1.f/16384.f) #define NORM_SCALING_1 (1.f/16384.f)
@ -135,8 +133,6 @@ typedef float celt_mask_t;
#define Q15ONE 1.0f #define Q15ONE 1.0f
#define Q30ONE 1.0f #define Q30ONE 1.0f
#define SIG_SCALING 1.f
#define SIG_SCALING_1 1.f
#define NORM_SCALING 1.f #define NORM_SCALING 1.f
#define NORM_SCALING_1 1.f #define NORM_SCALING_1 1.f
#define ENER_SCALING 1.f #define ENER_SCALING 1.f

View file

@ -175,9 +175,9 @@ void denormalise_bands(const CELTMode *m, const celt_norm_t * restrict X, celt_s
for (i=0;i<m->nbEBands;i++) for (i=0;i<m->nbEBands;i++)
{ {
int j; int j;
celt_word32_t g = MULT16_32_Q13(sqrtC_1[C-1],bank[i*C+c]); celt_word32_t g = MULT16_32_Q15(sqrtC_1[C-1],bank[i*C+c]);
j=eBands[i]; do { j=eBands[i]; do {
freq[j*C+c] = MULT16_32_Q15(X[j*C+c], g); freq[j*C+c] = SHL32(MULT16_32_Q15(X[j*C+c], g),2);
} while (++j<eBands[i+1]); } while (++j<eBands[i+1]);
} }
} }

View file

@ -182,11 +182,11 @@ static int transient_analysis(celt_word32_t *in, int len, int C, int *transient_
SAVE_STACK; SAVE_STACK;
ALLOC(begin, len, celt_word32_t); ALLOC(begin, len, celt_word32_t);
for (i=0;i<len;i++) for (i=0;i<len;i++)
begin[i] = EXTEND32(ABS16(SHR32(in[C*i],SIG_SHIFT))); begin[i] = ABS32(SHR32(in[C*i],SIG_SHIFT));
for (c=1;c<C;c++) for (c=1;c<C;c++)
{ {
for (i=0;i<len;i++) for (i=0;i<len;i++)
begin[i] = MAX32(begin[i], EXTEND32(ABS16(SHR32(in[C*i+c],SIG_SHIFT)))); begin[i] = MAX32(begin[i], ABS32(SHR32(in[C*i+c],SIG_SHIFT)));
} }
for (i=1;i<len;i++) for (i=1;i<len;i++)
begin[i] = MAX32(begin[i-1],begin[i]); begin[i] = MAX32(begin[i-1],begin[i]);
@ -412,7 +412,7 @@ int celt_encode_float(CELTEncoder * restrict st, celt_sig_t * restrict pcm, unsi
{ {
/* Apply pre-emphasis */ /* Apply pre-emphasis */
celt_sig_t tmp = SCALEIN(SHL32(EXTEND32(*pcmp), SIG_SHIFT)); celt_sig_t tmp = SCALEIN(SHL32(EXTEND32(*pcmp), SIG_SHIFT));
*inp = SUB32(tmp, SHR32(MULT16_16(preemph,st->preemph_memE[c]),1)); *inp = SUB32(tmp, SHR32(MULT16_16(preemph,st->preemph_memE[c]),3));
st->preemph_memE[c] = SCALEIN(*pcmp); st->preemph_memE[c] = SCALEIN(*pcmp);
inp += C; inp += C;
pcmp += C; pcmp += C;

View file

@ -246,7 +246,7 @@ static inline celt_word32_t celt_exp2(celt_word16_t x)
celt_word16_t frac; celt_word16_t frac;
integer = SHR16(x,11); integer = SHR16(x,11);
if (integer>14) if (integer>14)
return 0x7fffffff; return 0x7f000000;
else if (integer < -15) else if (integer < -15)
return 0; return 0;
frac = SHL16(x-SHL16(integer,11),3); frac = SHL16(x-SHL16(integer,11),3);

View file

@ -52,17 +52,19 @@ const celt_word16_t eMeans[24] = {45.f, -8.f, -12.f, -2.5f, 1.f, 0.f, 0.f, 0.f,
static inline celt_ener_t dB2Amp(celt_ener_t dB) static inline celt_ener_t dB2Amp(celt_ener_t dB)
{ {
celt_ener_t amp; celt_ener_t amp;
if (dB>24659)
dB=24659;
amp = PSHR32(celt_exp2(MULT16_16_Q14(21771,dB)),2)-QCONST16(.3f, 14); amp = PSHR32(celt_exp2(MULT16_16_Q14(21771,dB)),2)-QCONST16(.3f, 14);
if (amp < 0) if (amp < 0)
amp = 0; amp = 0;
return amp; return PSHR32(amp,2);
} }
#define DBofTWO 24661 #define DBofTWO 24661
static inline celt_word16_t amp2dB(celt_ener_t amp) static inline celt_word16_t amp2dB(celt_ener_t amp)
{ {
/* equivalent to return 6.0207*log2(.3+amp) */ /* equivalent to return 6.0207*log2(.3+amp) */
return ROUND16(MULT16_16(24661,celt_log2(ADD32(QCONST32(.3f,14),amp))),12); return ROUND16(MULT16_16(24661,celt_log2(ADD32(QCONST32(.3f,14),SHL32(amp,2)))),12);
/* return DB_SCALING*20*log10(.3+ENER_SCALING_1*amp); */ /* return DB_SCALING*20*log10(.3+ENER_SCALING_1*amp); */
} }
#else #else