Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.xiph.org/xiph/opus.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2013-12-16 10:08:21 +0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2013-12-16 10:08:21 +0400
commit306d7f5a308e30ce10ba1a1dcdbeeb81de3b2872 (patch)
tree9db4ef75957c9c797f3defe76a28af467a8c96fe /celt/bands.c
parente0f26246b08122cef31c1ac85f7ed228e2daca61 (diff)
fixed-point: slight (but free) accuracy improvement in compute_band_energies()
Also moves the VSHR32() condition outside the loop just in case some compilers don't optimize that properly.
Diffstat (limited to 'celt/bands.c')
-rw-r--r--celt/bands.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/celt/bands.c b/celt/bands.c
index 73346445..ee230912 100644
--- a/celt/bands.c
+++ b/celt/bands.c
@@ -92,11 +92,11 @@ static int bitexact_log2tan(int isin,int icos)
#ifdef FIXED_POINT
/* Compute the amplitude (sqrt energy) in each of the bands */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)
{
int i, c, N;
const opus_int16 *eBands = m->eBands;
- N = M*m->shortMdctSize;
+ N = m->shortMdctSize<<LM;
c=0; do {
for (i=0;i<end;i++)
{
@@ -104,18 +104,23 @@ void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *band
opus_val32 maxval=0;
opus_val32 sum = 0;
- j=M*eBands[i]; do {
- maxval = MAX32(maxval, X[j+c*N]);
- maxval = MAX32(maxval, -X[j+c*N]);
- } while (++j<M*eBands[i+1]);
-
+ maxval = celt_maxabs32(&X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);
if (maxval > 0)
{
- int shift = celt_ilog2(maxval)-10;
- j=M*eBands[i]; do {
- sum = MAC16_16(sum, EXTRACT16(VSHR32(X[j+c*N],shift)),
- EXTRACT16(VSHR32(X[j+c*N],shift)));
- } while (++j<M*eBands[i+1]);
+ int shift = celt_ilog2(maxval) - 14 + (((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)));
+ } 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)));
+ } while (++j<eBands[i+1]<<LM);
+ }
/* We're adding one here to ensure the normalized band isn't larger than unity norm */
bandE[i+c*m->nbEBands] = EPSILON+VSHR32(EXTEND32(celt_sqrt(sum)),-shift);
} else {
@@ -150,16 +155,16 @@ void normalise_bands(const CELTMode *m, const celt_sig * OPUS_RESTRICT freq, cel
#else /* FIXED_POINT */
/* Compute the amplitude (sqrt energy) in each of the bands */
-void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int M)
+void compute_band_energies(const CELTMode *m, const celt_sig *X, celt_ener *bandE, int end, int C, int LM)
{
int i, c, N;
const opus_int16 *eBands = m->eBands;
- N = M*m->shortMdctSize;
+ N = m->shortMdctSize<<LM;
c=0; do {
for (i=0;i<end;i++)
{
opus_val32 sum;
- sum = 1e-27f + celt_inner_prod(&X[c*N+M*eBands[i]], &X[c*N+M*eBands[i]], M*(eBands[i+1]-eBands[i]));
+ sum = 1e-27f + celt_inner_prod(&X[c*N+(eBands[i]<<LM)], &X[c*N+(eBands[i]<<LM)], (eBands[i+1]-eBands[i])<<LM);
bandE[i+c*m->nbEBands] = celt_sqrt(sum);
/*printf ("%f ", bandE[i+c*m->nbEBands]);*/
}