From eea914cb888209811e6d8f4b58f4f1224f913594 Mon Sep 17 00:00:00 2001 From: Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> Date: Sun, 12 Sep 2010 20:11:32 -0400 Subject: [PATCH] Simplifies vector renormalisation (and using it less) --- libcelt/bands.c | 14 +++++++++----- libcelt/vq.c | 27 ++++++++++++++++++++------- libcelt/vq.h | 4 +++- 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/libcelt/bands.c b/libcelt/bands.c index 396835ccf..df311f7e1 100644 --- a/libcelt/bands.c +++ b/libcelt/bands.c @@ -177,7 +177,7 @@ void renormalise_bands(const CELTMode *m, celt_norm * restrict X, int end, int _ 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 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_ 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 @@ static void quant_band(int encode, const CELTMode *m, int i, celt_norm *X, celt_ 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); } } } diff --git a/libcelt/vq.c b/libcelt/vq.c index 4876b5986..1b52ce19f 100644 --- a/libcelt/vq.c +++ b/libcelt/vq.c @@ -191,7 +191,7 @@ void alg_quant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband X[j] = (int)(*seed)>>20; } } - renormalise_vector(X, Q15ONE, N, 1); + renormalise_vector(X, N); return; } K = get_pulses(K); @@ -368,7 +368,7 @@ void alg_unquant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowba X[i] = (int)(*seed)>>20; } } - renormalise_vector(X, Q15ONE, N, 1); + renormalise_vector(X, N); return; } K = get_pulses(K); @@ -384,7 +384,20 @@ void alg_unquant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowba 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 @@ -397,20 +410,20 @@ celt_word16 renormalise_vector(celt_norm *X, celt_word16 value, int N, int strid 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);*/ } diff --git a/libcelt/vq.h b/libcelt/vq.h index 432c8e580..5bea13205 100644 --- a/libcelt/vq.h +++ b/libcelt/vq.h @@ -62,6 +62,8 @@ void alg_quant(celt_norm *X, int N, int K, int spread, int B, celt_norm *lowband */ 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 */ -- GitLab