Cast a factor to maintain precision on 16 bit systems.
authorRalph Giles <giles@mozilla.com>
Thu, 22 Mar 2012 21:13:33 +0000 (14:13 -0700)
committerJean-Marc Valin <jmvalin@jmvalin.ca>
Mon, 2 Apr 2012 15:21:44 +0000 (11:21 -0400)
The multiply would overflow with 16 bit ints. Thanks
to Riccardo Micci for pointing out the issue. Thanks
to Tim Terriberry for the valid range of the decay
argument.

Note that ft is unsigned, but always less than 32736,
so we could use a 16 bit signed type here if it allows
the compiler to produce faster code (with signed 16*16
and 16*32 multiplies). In the absense of actual cycle
counts from a real platform, I've left it as an unsigned
for the sake of readability.

For similar reasons we cast (16384-decay) to a signed
integer even though it is also always positive.

celt/laplace.c

index 5367313..30f2aab 100644 (file)
     direction). */
 #define LAPLACE_NMIN (16)
 
+/* When called, decay is positive and at most 11456. */
 static unsigned ec_laplace_get_freq1(unsigned fs0, int decay)
 {
    unsigned ft;
    ft = 32768 - LAPLACE_MINP*(2*LAPLACE_NMIN) - fs0;
-   return ft*(16384-decay)>>15;
+   return ft*(opus_int32)(16384-decay)>>15;
 }
 
 void ec_laplace_encode(ec_enc *enc, int *value, unsigned fs, int decay)