diff options
author | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-11-13 09:39:05 -0500 |
---|---|---|
committer | Jean-Marc Valin <jmvalin@jmvalin.ca> | 2013-11-13 09:40:00 -0500 |
commit | 8ea01eed109b3621f3b9e0186ac017119509a5dc (patch) | |
tree | 2dae718940ee4bb4d84c030ffd1f5216d84643ab /celt/bands.c | |
parent | db5b19455f39c521998d521d9d91960ceeebacaa (diff) | |
download | opus-8ea01eed109b3621f3b9e0186ac017119509a5dc.tar.gz |
Making the CELT fixed-point decoder a bit more robust to extreme signals
denormalise_bands() can now produce signals close to the max MDCT amplitude.
Diffstat (limited to 'celt/bands.c')
-rw-r--r-- | celt/bands.c | 22 |
1 files changed, 19 insertions, 3 deletions
diff --git a/celt/bands.c b/celt/bands.c index f22951b5..cce56e2f 100644 --- a/celt/bands.c +++ b/celt/bands.c @@ -214,7 +214,9 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, j=M*eBands[i]; band_end = M*eBands[i+1]; lg = ADD16(bandLogE[i+c*m->nbEBands], SHL16((opus_val16)eMeans[i],6)); -#ifdef FIXED_POINT +#ifndef FIXED_POINT + g = celt_exp2(lg); +#else /* Handle the integer part of the log energy */ shift = 16-(lg>>DB_SHIFT); if (shift>31) @@ -225,9 +227,23 @@ void denormalise_bands(const CELTMode *m, const celt_norm * OPUS_RESTRICT X, /* Handle the fractional part. */ g = celt_exp2_frac(lg&((1<<DB_SHIFT)-1)); } -#else - g = celt_exp2(lg); + /* Handle extreme gains with negative shift. */ + if (shift<0) + { + /* For shift < -2 we'd be likely to overflow, so we're capping + the gain here. This shouldn't happen unless the bitstream is + already corrupted. */ + if (shift < -2) + { + g = 32767; + shift = -2; + } + do { + *f++ = SHL32(MULT16_16(*x++, g), -shift); + } while (++j<band_end); + } else #endif + /* Be careful of the fixed-point "else" just above when changing this code */ do { *f++ = SHR32(MULT16_16(*x++, g), shift); } while (++j<band_end); |