shithub: opus

Download patch

ref: 377cfaa2a314f9c1ef312ba68fb6c61189d38314
parent: 5beef6501a7b94814a8c732cfc1e521276bcbb56
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Fri Feb 28 11:58:04 EST 2025

Delay forward MDCT scaling to improve accuracy

--- a/celt/mdct.c
+++ b/celt/mdct.c
@@ -210,10 +210,15 @@
          im = *yp++;
          yr = S_MUL(re,t0)  -  S_MUL(im,t1);
          yi = S_MUL(im,t0)  +  S_MUL(re,t1);
+         /* For QEXT, it's best to scale before the FFT, but otherwise it's best to scale after.
+            For floating-point it doesn't matter. */
+#ifdef ENABLE_QEXT
          yc.r = yr;
          yc.i = yi;
-         yc.r = S_MUL2(yc.r, scale);
-         yc.i = S_MUL2(yc.i, scale);
+#else
+         yc.r = S_MUL2(yr, scale);
+         yc.i = S_MUL2(yi, scale);
+#endif
 #ifdef FIXED_POINT
          maxval = MAX32(maxval, MAX32(ABS32(yc.r), ABS32(yc.i)));
 #endif
@@ -238,8 +243,16 @@
       for(i=0;i<N4;i++)
       {
          kiss_fft_scalar yr, yi;
-         yr = PSHR32(S_MUL(fp->i,t[N4+i]) - S_MUL(fp->r,t[i]), headroom);
-         yi = PSHR32(S_MUL(fp->r,t[N4+i]) + S_MUL(fp->i,t[i]), headroom);
+         kiss_fft_scalar t0, t1;
+#ifdef ENABLE_QEXT
+         t0 = S_MUL2(t[i], scale);
+         t1 = S_MUL2(t[N4+i], scale);
+#else
+         t0 = t[i];
+         t1 = t[N4+i];
+#endif
+         yr = PSHR32(S_MUL(fp->i,t1) - S_MUL(fp->r,t0), headroom);
+         yi = PSHR32(S_MUL(fp->r,t1) + S_MUL(fp->i,t0), headroom);
          *yp1 = yr;
          *yp2 = yi;
          fp++;
--