shithub: opus

Download patch

ref: 5c3bc67959790ea0339894c21ee25e81669f81a8
parent: 8dff923a5de52a4f38ee6db0f0cc1463ec25e775
author: Jean-Marc Valin <[email protected]>
date: Thu Aug 28 19:34:24 EDT 2008

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).

--- a/configure.ac
+++ b/configure.ac
@@ -6,7 +6,7 @@
 
 CELT_MAJOR_VERSION=0
 CELT_MINOR_VERSION=4
-CELT_MICRO_VERSION=0
+CELT_MICRO_VERSION=1
 CELT_EXTRA_VERSION=
 CELT_VERSION=$CELT_MAJOR_VERSION.$CELT_MINOR_VERSION.$CELT_MICRO_VERSION$CELT_EXTRA_VERSION
 
--- a/libcelt/arch.h
+++ b/libcelt/arch.h
@@ -71,9 +71,7 @@
 #define Q15ONE 32767
 #define Q30ONE 1073741823
 
-#define SIG_SCALING 16384.f
-#define SIG_SCALING_1 (1.f/16384.f)
-#define SIG_SHIFT 14
+#define SIG_SHIFT 12
 
 #define NORM_SCALING 16384
 #define NORM_SCALING_1 (1.f/16384.f)
@@ -135,8 +133,6 @@
 #define Q15ONE 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 1.f
 #define ENER_SCALING 1.f
--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -175,9 +175,9 @@
       for (i=0;i<m->nbEBands;i++)
       {
          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 {
-            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]);
       }
    }
--- a/libcelt/celt.c
+++ b/libcelt/celt.c
@@ -182,11 +182,11 @@
    SAVE_STACK;
    ALLOC(begin, len, celt_word32_t);
    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 (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++)
       begin[i] = MAX32(begin[i-1],begin[i]);
@@ -412,7 +412,7 @@
       {
          /* Apply pre-emphasis */
          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);
          inp += C;
          pcmp += C;
--- a/libcelt/mathops.h
+++ b/libcelt/mathops.h
@@ -246,7 +246,7 @@
    celt_word16_t frac;
    integer = SHR16(x,11);
    if (integer>14)
-      return 0x7fffffff;
+      return 0x7f000000;
    else if (integer < -15)
       return 0;
    frac = SHL16(x-SHL16(integer,11),3);
--- a/libcelt/quant_bands.c
+++ b/libcelt/quant_bands.c
@@ -52,10 +52,12 @@
 static inline celt_ener_t dB2Amp(celt_ener_t dB)
 {
    celt_ener_t amp;
+   if (dB>24659)
+      dB=24659;
    amp = PSHR32(celt_exp2(MULT16_16_Q14(21771,dB)),2)-QCONST16(.3f, 14);
    if (amp < 0)
       amp = 0;
-   return amp;
+   return PSHR32(amp,2);
 }
 
 #define DBofTWO 24661
@@ -62,7 +64,7 @@
 static inline celt_word16_t amp2dB(celt_ener_t 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); */
 }
 #else