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 */