shithub: opus

Download patch

ref: cdba712c8c3fd702c6aab1b06cc3f87e51ce6666
parent: e9d7842caf2f1cc698efc8ebea1672db5a1fb666
author: Jean-Marc Valin <jeanmarcv@google.com>
date: Sat Jun 29 21:47:29 EDT 2024

More accurate fixed-point compute_band_energies()

--- a/celt/bands.c
+++ b/celt/bands.c
@@ -108,19 +108,26 @@
          maxval = celt_maxabs32(&X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);
          if (maxval > 0)
          {
-            int shift = celt_ilog2(maxval) - 14 + (((m->logN[i]>>BITRES)+LM+1)>>1);
+            int shift, shift2;
+            shift = celt_ilog2(maxval) - 14;
+            shift2 = (((m->logN[i]>>BITRES)+LM+1)>>1);
             j=eBands[i]<<LM;
             if (shift>0)
             {
                do {
-                  sum = MAC16_16(sum, EXTRACT16(SHR32(X[j+c*N],shift)),
-                        EXTRACT16(SHR32(X[j+c*N],shift)));
+                  sum = ADD32(sum, SHR32(MULT16_16(EXTRACT16(SHR32(X[j+c*N],shift)),
+                        EXTRACT16(SHR32(X[j+c*N],shift))), 2*shift2));
                } while (++j<eBands[i+1]<<LM);
             } else {
                do {
-                  sum = MAC16_16(sum, EXTRACT16(SHL32(X[j+c*N],-shift)),
-                        EXTRACT16(SHL32(X[j+c*N],-shift)));
+                  sum = ADD32(sum, SHR32(MULT16_16(EXTRACT16(SHL32(X[j+c*N],-shift)),
+                        EXTRACT16(SHL32(X[j+c*N],-shift))), 2*shift2));
                } while (++j<eBands[i+1]<<LM);
+            }
+            shift+=shift2;
+            while (sum < 1<<28) {
+               sum <<=2;
+               shift -= 1;
             }
             /* We're adding one here to ensure the normalized band isn't larger than unity norm */
             bandE[i+c*m->nbEBands] = EPSILON+VSHR32(celt_sqrt(sum),-shift);
--