shithub: opus

Download patch

ref: eea914cb888209811e6d8f4b58f4f1224f913594
parent: 725e5f4b4cf0bb5a6c7917d72c4ec46129a1e627
author: Jean-Marc Valin <[email protected]>
date: Sun Sep 12 16:11:32 EDT 2010

Simplifies vector renormalisation (and using it less)

--- a/libcelt/bands.c
+++ b/libcelt/bands.c
@@ -177,7 +177,7 @@
    for (c=0;c<C;c++)
    {
       i=0; do {
-         renormalise_vector(X+M*eBands[i]+c*M*m->shortMdctSize, Q15ONE, M*eBands[i+1]-M*eBands[i], 1);
+         renormalise_vector(X+M*eBands[i]+c*M*m->shortMdctSize, M*eBands[i+1]-M*eBands[i]);
       } while (++i<end);
    }
 }
@@ -563,8 +563,12 @@
             if (stereo)
                stereo_band_mix(m, X, Y, bandE, 0, i, 1, N);
 
-            mid = renormalise_vector(X, Q15ONE, N, 1);
-            side = renormalise_vector(Y, Q15ONE, N, 1);
+            mid = vector_norm(X, N);
+            side = vector_norm(Y, N);
+            /* TODO: Renormalising X and Y *may* help fixed-point a bit at very high rate.
+                     Let's do that at higher complexity */
+            /*mid = renormalise_vector(X, Q15ONE, N, 1);
+            side = renormalise_vector(Y, Q15ONE, N, 1);*/
 
             /* theta is the atan() of the ratio between the (normalized)
                side and mid. With just that parameter, we can re-scale both
@@ -801,8 +805,8 @@
          stereo_band_mix(m, X, Y, bandE, 0, i, -1, N);
          /* We only need to renormalize because quantization may not
             have preserved orthogonality of mid and side */
-         renormalise_vector(X, Q15ONE, N, 1);
-         renormalise_vector(Y, Q15ONE, N, 1);
+         renormalise_vector(X, N);
+         renormalise_vector(Y, N);
       }
    }
 }
--- a/libcelt/vq.c
+++ b/libcelt/vq.c
@@ -191,7 +191,7 @@
             X[j] = (int)(*seed)>>20;
          }
       }
-      renormalise_vector(X, Q15ONE, N, 1);
+      renormalise_vector(X, N);
       return;
    }
    K = get_pulses(K);
@@ -368,7 +368,7 @@
             X[i] = (int)(*seed)>>20;
          }
       }
-      renormalise_vector(X, Q15ONE, N, 1);
+      renormalise_vector(X, N);
       return;
    }
    K = get_pulses(K);
@@ -384,9 +384,22 @@
    RESTORE_STACK;
 }
 
-celt_word16 renormalise_vector(celt_norm *X, celt_word16 value, int N, int stride)
+celt_word16 vector_norm(const celt_norm *X, int N)
 {
    int i;
+   celt_word32 E = EPSILON;
+   const celt_norm *xptr = X;
+   for (i=0;i<N;i++)
+   {
+      E = MAC16_16(E, *xptr, *xptr);
+      xptr++;
+   }
+   return celt_sqrt(E);
+}
+
+void renormalise_vector(celt_norm *X, int N)
+{
+   int i;
 #ifdef FIXED_POINT
    int k;
 #endif
@@ -397,20 +410,20 @@
    for (i=0;i<N;i++)
    {
       E = MAC16_16(E, *xptr, *xptr);
-      xptr += stride;
+      xptr++;
    }
 #ifdef FIXED_POINT
    k = celt_ilog2(E)>>1;
 #endif
    t = VSHR32(E, (k-7)<<1);
-   g = MULT16_16_Q15(value, celt_rsqrt_norm(t));
+   g = celt_rsqrt_norm(t);
 
    xptr = X;
    for (i=0;i<N;i++)
    {
       *xptr = EXTRACT16(PSHR32(MULT16_16(g, *xptr), k+1));
-      xptr += stride;
+      xptr++;
    }
-   return celt_sqrt(E);
+   /*return celt_sqrt(E);*/
 }
 
--- a/libcelt/vq.h
+++ b/libcelt/vq.h
@@ -62,6 +62,8 @@
  */
 void alg_unquant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband, ec_dec *dec, celt_int32 *seed);
 
-celt_word16 renormalise_vector(celt_norm *X, celt_word16 value, int N, int stride);
+void renormalise_vector(celt_norm *X, int N);
+
+celt_word16 vector_norm(const celt_norm *X, int N);
 
 #endif /* VQ_H */