ref: cee530ebf697214ed884926fd79146ef591f86ed
parent: b1299db24cc5817dba58ef02e73d8526eff25072
author: menno <menno>
date: Thu Sep 25 08:04:31 EDT 2003
QMF improvements Covariance speedup
--- a/libfaad/sbr_dec.c
+++ b/libfaad/sbr_dec.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dec.c,v 1.11 2003/09/22 13:15:38 menno Exp $
+** $Id: sbr_dec.c,v 1.12 2003/09/25 12:04:31 menno Exp $
**/
@@ -239,6 +239,7 @@
else
ch_buf = right_channel;
+#if 0
for (i = 0; i < sbr->tHFAdj; i++)
{
int8_t j;
@@ -250,6 +251,7 @@
#endif
}
}
+#endif
/* subband analysis */
if (dont_process)
--- a/libfaad/sbr_dec.h
+++ b/libfaad/sbr_dec.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_dec.h,v 1.6 2003/09/18 13:38:38 menno Exp $
+** $Id: sbr_dec.h,v 1.7 2003/09/25 12:04:31 menno Exp $
**/
#ifndef __SBR_DEC_H__
@@ -34,13 +34,12 @@
typedef struct {
real_t *x;
- uint16_t x_index;
uint8_t channels;
} qmfa_info;
typedef struct {
- real_t *v;
- uint16_t v_index;
+ real_t *v[2];
+ uint8_t v_index;
uint8_t channels;
} qmfs_info;
--- a/libfaad/sbr_hfgen.c
+++ b/libfaad/sbr_hfgen.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_hfgen.c,v 1.5 2003/09/22 13:09:43 menno Exp $
+** $Id: sbr_hfgen.c,v 1.6 2003/09/25 12:04:31 menno Exp $
**/
/* High Frequency generation */
@@ -36,7 +36,7 @@
#include "sbr_hfgen.h"
#include "sbr_fbt.h"
-void hf_generation(sbr_info *sbr, qmf_t *Xlow,
+void hf_generation(sbr_info *sbr, const qmf_t *Xlow,
qmf_t *Xhigh
#ifdef SBR_LOW_POWER
,real_t *deg
@@ -109,6 +109,7 @@
bw = sbr->bwArray[ch][g];
bw2 = MUL_C_C(bw, bw);
+
/* do the patching */
/* with or without filtering */
if (bw2 > 0)
@@ -174,18 +175,15 @@
#define SBR_ABS(A) ((A) < 0) ? -(A) : (A)
-static void auto_correlation(sbr_info *sbr, acorr_coef *ac, qmf_t *buffer,
+#ifdef SBR_LOW_POWER
+static void auto_correlation(sbr_info *sbr, acorr_coef *ac, const qmf_t *buffer,
uint8_t bd, uint8_t len)
{
int8_t j, jminus1, jminus2;
uint8_t offset;
-#ifdef FIXED_POINT
- const real_t rel = COEF_CONST(0.9999999999999);
- uint32_t maxi = 0;
- uint32_t pow2, exp;
-#else
+ real_t r01, i01, r11;
const real_t rel = 1 / (1 + 1e-6f);
-#endif
+
#ifdef DRM
if (sbr->Is_DRM_SBR)
offset = sbr->tHFGen;
@@ -195,92 +193,82 @@
offset = sbr->tHFAdj;
}
-#ifdef FIXED_POINT
- /*
- * For computing the covariance matrix and the filter coefficients
- * in fixed point, all values are normalised so that the fixed point
- * values don't overflow.
- */
- for (j = offset-2; j < len + offset; j++)
+ memset(ac, 0, sizeof(acorr_coef));
+
+ r01 = QMF_RE(buffer[(offset-1)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]);
+ r11 = QMF_RE(buffer[(offset-2)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]);
+
+ for (j = offset; j < len + offset; j++)
{
- maxi = max(SBR_ABS(QMF_RE(buffer[j*32 + bd])>>REAL_BITS), maxi);
+ jminus1 = j - 1;
+ jminus2 = j - 2;
+
+ RE(ac->r12) += r01;
+ r01 = QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
+ RE(ac->r01) += r01;
+ RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
+ RE(ac->r22) += r11;
+ r11 = QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
+ RE(ac->r11) += r11;
}
- /* find the first power of 2 bigger than max to avoid division */
- pow2 = 1;
- exp = 0;
- while (maxi > pow2)
+ ac->det = MUL(RE(ac->r11), RE(ac->r22)) - MUL_R_C(MUL(RE(ac->r12), RE(ac->r12)), rel);
+}
+#else
+static void auto_correlation(sbr_info *sbr, acorr_coef *ac, const qmf_t *buffer,
+ uint8_t bd, uint8_t len)
+{
+ int8_t j, jminus1, jminus2;
+ uint8_t offset;
+ real_t r01, i01, r11;
+ const real_t rel = 1 / (1 + 1e-6f);
+
+#ifdef DRM
+ if (sbr->Is_DRM_SBR)
+ offset = sbr->tHFGen;
+ else
+#endif
{
- pow2 <<= 1;
- exp++;
+ offset = sbr->tHFAdj;
}
-#endif
memset(ac, 0, sizeof(acorr_coef));
+ r01 = QMF_RE(buffer[(offset-1)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]) +
+ QMF_IM(buffer[(offset-1)*32 + bd]) * QMF_IM(buffer[(offset-2)*32 + bd]);
+ i01 = QMF_IM(buffer[(offset-1)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]) -
+ QMF_RE(buffer[(offset-1)*32 + bd]) * QMF_IM(buffer[(offset-2)*32 + bd]);
+ r11 = QMF_RE(buffer[(offset-2)*32 + bd]) * QMF_RE(buffer[(offset-2)*32 + bd]) +
+ QMF_IM(buffer[(offset-2)*32 + bd]) * QMF_IM(buffer[(offset-2)*32 + bd]);
+
for (j = offset; j < len + offset; j++)
{
jminus1 = j - 1;
- jminus2 = jminus1 - 1;
+ jminus2 = j - 2;
-#ifdef SBR_LOW_POWER
-#ifdef FIXED_POINT
- /* normalisation with rounding */
- RE(ac->r01) += MUL(((QMF_RE(buffer[j*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp));
- RE(ac->r02) += MUL(((QMF_RE(buffer[j*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp));
- RE(ac->r11) += MUL(((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp));
- RE(ac->r12) += MUL(((QMF_RE(buffer[jminus1*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp));
- RE(ac->r22) += MUL(((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp), ((QMF_RE(buffer[jminus2*32 + bd])+(1<<(exp-1)))>>exp));
-#else
- RE(ac->r01) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
- RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
- RE(ac->r11) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]);
- RE(ac->r12) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
- RE(ac->r22) += QMF_RE(buffer[jminus2*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]);
-#endif
-#else
- /* RE(ac[0][1]) */
- RE(ac->r01) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
+ RE(ac->r12) += r01;
+ IM(ac->r12) += i01;
+ r01 = QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
QMF_IM(buffer[j*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);
-
- /* IM(ac[0][1]) */
- IM(ac->r01) += QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) -
+ RE(ac->r01) += r01;
+ i01 = QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) -
QMF_RE(buffer[j*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);
-
- /* RE(ac[0][2]) */
+ IM(ac->r01) += i01;
RE(ac->r02) += QMF_RE(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
QMF_IM(buffer[j*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
-
- /* IM(ac[0][2]) */
IM(ac->r02) += QMF_IM(buffer[j*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) -
QMF_RE(buffer[j*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
-
- /* RE(ac[1][1]) */
- RE(ac->r11) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
+ RE(ac->r22) += r11;
+ r11 = QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus1*32 + bd]) +
QMF_IM(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus1*32 + bd]);
-
- /* RE(ac[1][2]) */
- RE(ac->r12) += QMF_RE(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
- QMF_IM(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
-
- /* IM(ac[1][2]) */
- IM(ac->r12) += QMF_IM(buffer[jminus1*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) -
- QMF_RE(buffer[jminus1*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
-
- /* RE(ac[2][2]) */
- RE(ac->r22) += QMF_RE(buffer[jminus2*32 + bd]) * QMF_RE(buffer[jminus2*32 + bd]) +
- QMF_IM(buffer[jminus2*32 + bd]) * QMF_IM(buffer[jminus2*32 + bd]);
-#endif
+ RE(ac->r11) += r11;
}
-#ifdef SBR_LOW_POWER
- ac->det = MUL(RE(ac->r11), RE(ac->r22)) - MUL_R_C(MUL(RE(ac->r12), RE(ac->r12)), rel);
-#else
ac->det = RE(ac->r11) * RE(ac->r22) - rel * (RE(ac->r12) * RE(ac->r12) + IM(ac->r12) * IM(ac->r12));
-#endif
}
+#endif
-static void calc_prediction_coef(sbr_info *sbr, qmf_t *Xlow,
+static void calc_prediction_coef(sbr_info *sbr, const qmf_t *Xlow,
complex_t *alpha_0, complex_t *alpha_1
#ifdef SBR_LOW_POWER
, real_t *rxx
@@ -507,8 +495,7 @@
k = sbr->N_master;
} while (sb != (sbr->kx + sbr->M));
- if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) &&
- (sbr->noPatches > 1))
+ if ((sbr->patchNoSubbands[sbr->noPatches-1] < 3) && (sbr->noPatches > 1))
{
sbr->noPatches--;
}
--- a/libfaad/sbr_qmf.c
+++ b/libfaad/sbr_qmf.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
**
-** $Id: sbr_qmf.c,v 1.11 2003/09/24 19:55:34 menno Exp $
+** $Id: sbr_qmf.c,v 1.12 2003/09/25 12:04:31 menno Exp $
**/
#include "common.h"
@@ -92,11 +92,11 @@
/* window and summation to create array u */
for (n = 0; n < 64; n++)
{
- u[n] = MUL_R_C(qmfa->x[n], qmf_c_2[n]) +
- MUL_R_C(qmfa->x[n + 64], qmf_c_2[n + 64]) +
- MUL_R_C(qmfa->x[n + 128], qmf_c_2[n + 128]) +
- MUL_R_C(qmfa->x[n + 192], qmf_c_2[n + 192]) +
- MUL_R_C(qmfa->x[n + 256], qmf_c_2[n + 256]);
+ u[n] = MUL_R_C(qmfa->x[n], qmf_c[2*n]) +
+ MUL_R_C(qmfa->x[n + 64], qmf_c[2*(n + 64)]) +
+ MUL_R_C(qmfa->x[n + 128], qmf_c[2*(n + 128)]) +
+ MUL_R_C(qmfa->x[n + 192], qmf_c[2*(n + 192)]) +
+ MUL_R_C(qmfa->x[n + 256], qmf_c[2*(n + 256)]);
}
/* calculate 32 subband samples by introducing X */
@@ -111,11 +111,16 @@
for (n = 0; n < 32; n++)
{
+ if (n < kx)
+ {
#ifdef FIXED_POINT
- QMF_RE(X[((l + offset)<<5) + n]) = u[n] << 1;
+ QMF_RE(X[((l + offset)<<5) + n]) = u[n] << 1;
#else
- QMF_RE(X[((l + offset)<<5) + n]) = 2. * u[n];
+ QMF_RE(X[((l + offset)<<5) + n]) = 2. * u[n];
#endif
+ } else {
+ QMF_RE(X[((l + offset)<<5) + n]) = 0;
+ }
}
#else
x[0] = u[0];