summaryrefslogtreecommitdiff
path: root/celt/bands.c
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-13 09:39:05 -0500
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-11-13 09:40:00 -0500
commit8ea01eed109b3621f3b9e0186ac017119509a5dc (patch)
tree2dae718940ee4bb4d84c030ffd1f5216d84643ab /celt/bands.c
parentdb5b19455f39c521998d521d9d91960ceeebacaa (diff)
downloadopus-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.c22
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);