ref: 62336dee445b3938cb71600d19efe96aa96f121e
parent: c095b2fdc5c1dc599dcfe9e2b93d23c2224617c7
author: menno <menno>
date: Mon Apr 12 14:17:42 EDT 2004
- PS fixed point - Minor updates in SBR - AUTHORS updated
--- a/AUTHORS
+++ b/AUTHORS
@@ -11,3 +11,7 @@
- DRM code
- lot's of bug fixes
+Gian-Carlo Pascutto (gpascutto(at)nero.com)
+ - DRM PS code
+ - bugfixes
+
\ No newline at end of file
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,6 @@
+12 april 2004 mbakker(at)nero.com
+ - common.h, ps_dec.c: Updates for PS fixed point, should completely work now
-- 30 mar 2004: Updated mpeg4ip libraries to version 1.0
-- xx mar 2004: First PS (Parametric Stereo) checkin
+12 april 2004 gpascutto(at)nero.com
+ - drm_dec.c, drm_dec.h: eliminated sqrt and SA mapping/dequantization from DRM PS decoder
-- 26 feb 2004: Added downsampled SBR support
-- 26 feb 2004: Optimised Low Power QMF filterbank
--- a/common/mp4ff/drms.c
+++ b/common/mp4ff/drms.c
@@ -2,7 +2,7 @@
* drms.c: DRMS
*****************************************************************************
* Copyright (C) 2004 VideoLAN
- * $Id: drms.c,v 1.5 2004/03/31 17:39:57 menno Exp $
+ * $Id: drms.c,v 1.6 2004/04/12 18:17:41 menno Exp $
*
* Authors: Jon Lech Johansen <[email protected]>
* Sam Hocevar <[email protected]>
--- a/common/mp4ff/drms.h
+++ b/common/mp4ff/drms.h
@@ -2,7 +2,7 @@
* drms.h : DRMS
*****************************************************************************
* Copyright (C) 2004 VideoLAN
- * $Id: drms.h,v 1.5 2004/03/31 17:39:57 menno Exp $
+ * $Id: drms.h,v 1.6 2004/04/12 18:17:41 menno Exp $
*
* Author: Jon Lech Johansen <[email protected]>
*
--- a/common/mp4ff/drmstables.h
+++ b/common/mp4ff/drmstables.h
@@ -2,7 +2,7 @@
* drmstables.h : AES/Rijndael block cipher and miscellaneous tables
*****************************************************************************
* Copyright (C) 2004 VideoLAN
- * $Id: drmstables.h,v 1.4 2004/03/31 17:39:57 menno Exp $
+ * $Id: drmstables.h,v 1.6 2005/02/01 13:15:55 menno Exp $
*
* Author: Jon Lech Johansen <[email protected]>
*
--- a/common/mp4ff/mp4atom.c
+++ b/common/mp4ff/mp4atom.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: mp4atom.c,v 1.19 2004/03/31 17:39:57 menno Exp $
+** $Id: mp4atom.c,v 1.20 2004/04/12 18:17:42 menno Exp $
**/
#include <stdlib.h>
@@ -30,7 +30,9 @@
#include "config.h"
#else
#include <tchar.h>
+#ifdef ITUNES_DRM
#include <shlobj.h>
+#endif
#include <windows.h>
#endif
#ifdef HAVE_GETPWUID
--- a/common/mp4ff/mp4ffint.h
+++ b/common/mp4ff/mp4ffint.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: mp4ffint.h,v 1.17 2004/03/31 17:39:57 menno Exp $
+** $Id: mp4ffint.h,v 1.18 2004/04/12 18:17:42 menno Exp $
**/
#ifndef MP4FF_INTERNAL_H
@@ -37,7 +37,6 @@
#if defined(_WIN32) && !defined(_WIN32_WCE)
#define ITUNES_DRM
-#endif
static __inline uint32_t GetDWLE( void const * _p )
{
@@ -80,6 +79,8 @@
#define FOURCC_iviv VLC_FOURCC( 'i', 'v', 'i', 'v' )
#define FOURCC_name VLC_FOURCC( 'n', 'a', 'm', 'e' )
#define FOURCC_priv VLC_FOURCC( 'p', 'r', 'i', 'v' )
+
+#endif
#define MAX_TRACKS 1024
#define TRACK_UNKNOWN 0
--- a/libfaad/common.h
+++ b/libfaad/common.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: common.h,v 1.58 2004/04/03 10:49:14 menno Exp $
+** $Id: common.h,v 1.59 2004/04/12 18:17:42 menno Exp $
**/
#ifndef __COMMON_H__
@@ -92,7 +92,7 @@
#define ALLOW_SMALL_FRAMELENGTH
-// Define LC_ONLY_DECODER if you want a pure AAC LC decoder (independant of SBR_DEC)
+// Define LC_ONLY_DECODER if you want a pure AAC LC decoder (independant of SBR_DEC and PS_DEC)
//#define LC_ONLY_DECODER
#ifdef LC_ONLY_DECODER
#undef LTP_DEC
@@ -107,14 +107,11 @@
//#define SBR_LOW_POWER
#define PS_DEC
-/* FIXED POINT: No MAIN decoding, forced SBR Low Power decoder */
+/* FIXED POINT: No MAIN decoding */
#ifdef FIXED_POINT
# ifdef MAIN_DEC
# undef MAIN_DEC
# endif
-# ifdef PS_DEC
-# undef PS_DEC
-# endif
#endif // FIXED_POINT
#ifdef DRM
@@ -131,9 +128,11 @@
#endif
#ifdef FIXED_POINT
-#define SBR_DIV(A, B) (((int64_t)A << REAL_BITS)/B)
+#define DIV_R(A, B) (((int64_t)A << REAL_BITS)/B)
+#define DIV_C(A, B) (((int64_t)A << COEF_BITS)/B)
#else
-#define SBR_DIV(A, B) ((A)/(B))
+#define DIV_R(A, B) ((A)/(B))
+#define DIV_C(A, B) ((A)/(B))
#endif
#ifndef SBR_LOW_POWER
--- a/libfaad/fixed.h
+++ b/libfaad/fixed.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: fixed.h,v 1.21 2004/03/19 10:37:55 menno Exp $
+** $Id: fixed.h,v 1.22 2004/04/12 18:17:42 menno Exp $
**/
#ifndef __FIXED_H__
@@ -32,7 +32,7 @@
extern "C" {
#endif
-#ifdef _WIN32_WCE
+#if defined(_WIN32_WCE) && defined(_ARM_)
#include <cmnintrin.h>
#endif
@@ -213,15 +213,15 @@
/* multiply with coef shift */
#define MUL_C(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (COEF_BITS-1))) >> COEF_BITS)
/* multiply with fractional shift */
-#ifndef _WIN32_WCE
- #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE)
- #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS)
-#else
+#if defined(_WIN32_WCE) && defined(_ARM_)
/* eVC for PocketPC has an intrinsic function that returns only the high 32 bits of a 32x32 bit multiply */
static INLINE real_t MUL_F(real_t A, real_t B)
{
return _MulHigh(A,B) << (32-FRAC_BITS);
}
+#else
+ #define _MulHigh(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_SIZE-1))) >> FRAC_SIZE)
+ #define MUL_F(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (FRAC_BITS-1))) >> FRAC_BITS)
#endif
#define MUL_Q2(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (Q2_BITS-1))) >> Q2_BITS)
#define MUL_SHIFT6(A,B) (real_t)(((int64_t)(A)*(int64_t)(B)+(1 << (6-1))) >> 6)
--- a/libfaad/ps_dec.c
+++ b/libfaad/ps_dec.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: ps_dec.c,v 1.5 2004/04/03 19:08:38 menno Exp $
+** $Id: ps_dec.c,v 1.6 2004/04/12 18:17:42 menno Exp $
**/
#include "common.h"
@@ -926,7 +926,7 @@
static void ps_decorrelate(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64],
qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32])
{
- uint8_t gr, m, n, bk;
+ uint8_t gr, n, m, bk;
uint8_t temp_delay;
uint8_t sb, maxsb;
const complex_t *Phi_Fract_SubQmf;
@@ -946,7 +946,6 @@
}
/* clear the energy values */
-#if 0
for (n = 0; n < 32; n++)
{
for (bk = 0; bk < 34; bk++)
@@ -954,7 +953,6 @@
P[n][bk] = 0;
}
}
-#endif
/* calculate the energy in each parameter band b(k) */
for (gr = 0; gr < ps->num_groups; gr++)
@@ -969,6 +967,10 @@
{
for (n = ps->border_position[0]; n < ps->border_position[ps->num_env]; n++)
{
+#ifdef FIXED_POINT
+ uint32_t in_re, in_im;
+#endif
+
/* input from hybrid subbands or QMF subbands */
if (gr < ps->num_hybrid_groups)
{
@@ -980,11 +982,34 @@
}
/* accumulate energy */
+#ifdef FIXED_POINT
+ /* NOTE: all input is scaled by 2^(-5) because of fixed point QMF
+ * meaning that P will be scaled by 2^(-10) compared to floating point version
+ */
+ in_re = ((abs(RE(inputLeft))+(1<<(REAL_BITS-1)))>>REAL_BITS);
+ in_im = ((abs(IM(inputLeft))+(1<<(REAL_BITS-1)))>>REAL_BITS);
+ P[n][bk] += in_re*in_re + in_im*in_im;
+#else
P[n][bk] += MUL_R(RE(inputLeft),RE(inputLeft)) + MUL_R(IM(inputLeft),IM(inputLeft));
+#endif
}
}
}
+#if 0
+ for (n = 0; n < 32; n++)
+ {
+ for (bk = 0; bk < 34; bk++)
+ {
+#ifdef FIXED_POINT
+ printf("%d %d: %d\n", n, bk, P[n][bk] /*/(float)REAL_PRECISION*/);
+#else
+ printf("%d %d: %f\n", n, bk, P[n][bk]/1024.0);
+#endif
+ }
+ }
+#endif
+
/* calculate transient reduction ratio for each parameter band b(k) */
for (bk = 0; bk < ps->nr_par_bands; bk++)
{
@@ -1011,11 +1036,25 @@
{
G_TransientRatio[n][bk] = REAL_CONST(1.0);
} else {
- G_TransientRatio[n][bk] = SBR_DIV(nrg, (MUL_C(P_SmoothPeakDecayDiffNrg, gamma)));
+ G_TransientRatio[n][bk] = DIV_R(nrg, (MUL_C(P_SmoothPeakDecayDiffNrg, gamma)));
}
}
}
+#if 0
+ for (n = 0; n < 32; n++)
+ {
+ for (bk = 0; bk < 34; bk++)
+ {
+#ifdef FIXED_POINT
+ printf("%d %d: %f\n", n, bk, G_TransientRatio[n][bk]/(float)REAL_PRECISION);
+#else
+ printf("%d %d: %f\n", n, bk, G_TransientRatio[n][bk]);
+#endif
+ }
+ }
+#endif
+
/* apply stereo decorrelation filter to the signal */
for (gr = 0; gr < ps->num_groups; gr++)
{
@@ -1028,6 +1067,7 @@
for (sb = ps->group_border[gr]; sb < maxsb; sb++)
{
real_t g_DecaySlope;
+ real_t g_DecaySlope_filt[NO_ALLPASS_LINKS];
/* g_DecaySlope: [0..1] */
if (gr < ps->num_hybrid_groups || sb <= ps->decay_cutoff)
@@ -1044,7 +1084,13 @@
}
}
+ /* calculate g_DecaySlope_filt for every m multiplied by filter_a[m] */
+ for (m = 0; m < NO_ALLPASS_LINKS; m++)
+ {
+ g_DecaySlope_filt[m] = MUL_F(g_DecaySlope, filter_a[m]);
+ }
+
/* set delay indices */
temp_delay = ps->saved_delay;
for (n = 0; n < NO_ALLPASS_LINKS; n++)
@@ -1110,7 +1156,7 @@
RE(R0) = RE(tmp);
IM(R0) = IM(tmp);
- for (m = 0; m < NO_ALLPASS_LINKS ; m++)
+ for (m = 0; m < NO_ALLPASS_LINKS; m++)
{
complex_t Q_Fract_allpass, tmp2;
@@ -1143,12 +1189,12 @@
ComplexMult(&RE(tmp), &IM(tmp), RE(tmp0), IM(tmp0), RE(Q_Fract_allpass), IM(Q_Fract_allpass));
/* -a(m) * g_DecaySlope[k] */
- RE(tmp) += -MUL_F(g_DecaySlope, MUL_F(filter_a[m], RE(R0)));
- IM(tmp) += -MUL_F(g_DecaySlope, MUL_F(filter_a[m], IM(R0)));
+ RE(tmp) += -MUL_F(g_DecaySlope_filt[m], RE(R0));
+ IM(tmp) += -MUL_F(g_DecaySlope_filt[m], IM(R0));
/* -a(m) * g_DecaySlope[k] * Q_Fract_allpass[k,m] * z^(-d(m)) */
- RE(tmp2) = RE(R0) + MUL_F(g_DecaySlope, MUL_F(filter_a[m], RE(tmp)));
- IM(tmp2) = IM(R0) + MUL_F(g_DecaySlope, MUL_F(filter_a[m], IM(tmp)));
+ RE(tmp2) = RE(R0) + MUL_F(g_DecaySlope_filt[m], RE(tmp));
+ IM(tmp2) = IM(R0) + MUL_F(g_DecaySlope_filt[m], IM(tmp));
/* store sample */
if (gr < ps->num_hybrid_groups)
@@ -1160,6 +1206,7 @@
IM(ps->delay_Qmf_ser[m][temp_delay_ser[m]][sb]) = IM(tmp2);
}
+ /* store for next iteration (or as output value if last iteration) */
RE(R0) = RE(tmp);
IM(R0) = IM(tmp);
}
@@ -1192,6 +1239,7 @@
/* update delay indices */
if (sb > ps->nr_allpass_bands && gr >= ps->num_hybrid_groups)
{
+ /* delay_D depends on the samplerate, it can hold the values 14 and 1 */
if (++ps->delay_buf_index_delay[sb] >= ps->delay_D[sb])
{
ps->delay_buf_index_delay[sb] = 0;
@@ -1215,10 +1263,41 @@
ps->delay_buf_index_ser[m] = temp_delay_ser[m];
}
+#ifdef FIXED_POINT
+#define step(shift) \
+ if ((0x40000000l >> shift) + root <= value) \
+ { \
+ value -= (0x40000000l >> shift) + root; \
+ root = (root >> 1) | (0x40000000l >> shift); \
+ } else { \
+ root = root >> 1; \
+ }
+
+/* fixed point square root approximation */
+static real_t ps_sqrt(real_t value)
+{
+ real_t root = 0;
+
+ step( 0); step( 2); step( 4); step( 6);
+ step( 8); step(10); step(12); step(14);
+ step(16); step(18); step(20); step(22);
+ step(24); step(26); step(28); step(30);
+
+ if (root < value)
+ ++root;
+
+ root <<= (REAL_BITS/2);
+
+ return root;
+}
+#else
+#define ps_sqrt(A) sqrt(A)
+#endif
+
static void ps_mix_phase(ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64],
qmf_t X_hybrid_left[32][32], qmf_t X_hybrid_right[32][32])
{
- uint8_t i;
+ uint8_t n;
uint8_t gr;
uint8_t bk = 0;
uint8_t sb, maxsb;
@@ -1315,9 +1394,6 @@
RE(h12) = MUL_C(c_1, (ab1 + ab2));
RE(h21) = MUL_C(c_2, (ab3 + ab4));
RE(h22) = MUL_C(c_1, (ab3 - ab4));
-
- //printf("%d %f %f %f %f\n", ps->iid_index[env][bin], scaleR, scaleL, alpha, beta);
-
} else {
/* type 'B' mixing as described in 8.6.4.6.2.2 */
real_t sina, cosa;
@@ -1385,27 +1461,32 @@
*/
if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par))
{
- real_t ipd, opd;
+ int8_t i;
real_t xxyy, ppqq;
real_t yq, xp, xq, py, tmp;
- ipd = (float)( M_PI/4.0f ) * ps->ipd_index[env][bk];
- opd = (float)( M_PI/4.0f ) * ps->opd_index[env][bk];
-
/* ringbuffer index */
i = ps->phase_hist;
/* previous value */
+#ifdef FIXED_POINT
+ /* divide by 4, shift right 2 bits */
+ RE(tempLeft) = RE(ps->ipd_prev[bk][i]) >> 2;
+ IM(tempLeft) = IM(ps->ipd_prev[bk][i]) >> 2;
+ RE(tempRight) = RE(ps->opd_prev[bk][i]) >> 2;
+ IM(tempRight) = IM(ps->opd_prev[bk][i]) >> 2;
+#else
RE(tempLeft) = MUL_F(RE(ps->ipd_prev[bk][i]), FRAC_CONST(0.25));
IM(tempLeft) = MUL_F(IM(ps->ipd_prev[bk][i]), FRAC_CONST(0.25));
RE(tempRight) = MUL_F(RE(ps->opd_prev[bk][i]), FRAC_CONST(0.25));
IM(tempRight) = MUL_F(IM(ps->opd_prev[bk][i]), FRAC_CONST(0.25));
+#endif
/* save current value */
- RE(ps->ipd_prev[bk][i]) = (float)cos(ipd);
- IM(ps->ipd_prev[bk][i]) = (float)sin(ipd);
- RE(ps->opd_prev[bk][i]) = (float)cos(opd);
- IM(ps->opd_prev[bk][i]) = (float)sin(opd);
+ RE(ps->ipd_prev[bk][i]) = (float)cos((float)( M_PI/4.0f ) * ps->ipd_index[env][bk]);
+ IM(ps->ipd_prev[bk][i]) = (float)sin((float)( M_PI/4.0f ) * ps->ipd_index[env][bk]);
+ RE(ps->opd_prev[bk][i]) = (float)cos((float)( M_PI/4.0f ) * ps->opd_index[env][bk]);
+ IM(ps->opd_prev[bk][i]) = (float)sin((float)( M_PI/4.0f ) * ps->opd_index[env][bk]);
/* add current value */
RE(tempLeft) += RE(ps->ipd_prev[bk][i]);
@@ -1421,12 +1502,20 @@
i--;
/* get value before previous */
+#ifdef FIXED_POINT
+ /* dividing by 2, shift right 1 bit */
+ RE(tempLeft) += (RE(ps->ipd_prev[bk][i]) >> 1);
+ IM(tempLeft) += (IM(ps->ipd_prev[bk][i]) >> 1);
+ RE(tempRight) += (RE(ps->opd_prev[bk][i]) >> 1);
+ IM(tempRight) += (IM(ps->opd_prev[bk][i]) >> 1);
+#else
RE(tempLeft) += MUL_F(RE(ps->ipd_prev[bk][i]), FRAC_CONST(0.5));
IM(tempLeft) += MUL_F(IM(ps->ipd_prev[bk][i]), FRAC_CONST(0.5));
RE(tempRight) += MUL_F(RE(ps->opd_prev[bk][i]), FRAC_CONST(0.5));
IM(tempRight) += MUL_F(IM(ps->opd_prev[bk][i]), FRAC_CONST(0.5));
+#endif
-#if 0
+#if 0 /* original code */
ipd = (float)atan2(IM(tempLeft), RE(tempLeft));
opd = (float)atan2(IM(tempRight), RE(tempRight));
@@ -1441,41 +1530,49 @@
// sin(atan2(x,y)) = x/(y*sqrt(1 + (x*x)/(y*y)))
// cos(atan2(x,y)-atan2(p,q)) = (y*q+x*p)/(y*q * sqrt(1 + (x*x)/(y*y)) * sqrt(1 + (p*p)/(q*q)));
// sin(atan2(x,y)-atan2(p,q)) = (x*q-p*y)/(y*q * sqrt(1 + (x*x)/(y*y)) * sqrt(1 + (p*p)/(q*q)));
-#define DIV_C(A,B) ((A)/(B))
- xxyy = DIV_C(MUL_C(IM(tempLeft),IM(tempLeft)), MUL_C(RE(tempLeft),RE(tempLeft)));
- ppqq = DIV_C(MUL_C(IM(tempRight),IM(tempRight)), MUL_C(RE(tempRight),RE(tempRight)));
- xxyy += COEF_CONST(1);
- ppqq += COEF_CONST(1);
+ /* (x*x)/(y*y) (REAL > 0) */
+ xxyy = DIV_R(MUL_C(IM(tempLeft),IM(tempLeft)), MUL_C(RE(tempLeft),RE(tempLeft)));
+ ppqq = DIV_R(MUL_C(IM(tempRight),IM(tempRight)), MUL_C(RE(tempRight),RE(tempRight)));
- xxyy = sqrt(xxyy);
- ppqq = sqrt(ppqq);
+ /* 1 + (x*x)/(y*y) (REAL > 1) */
+ xxyy += REAL_CONST(1);
+ ppqq += REAL_CONST(1);
+ /* 1 / sqrt(1 + (x*x)/(y*y)) (FRAC <= 1) */
+ xxyy = DIV_R(FRAC_CONST(1), ps_sqrt(xxyy));
+ ppqq = DIV_R(FRAC_CONST(1), ps_sqrt(ppqq));
+
+ /* COEF */
yq = MUL_C(RE(tempLeft), RE(tempRight));
xp = MUL_C(IM(tempLeft), IM(tempRight));
xq = MUL_C(IM(tempLeft), RE(tempRight));
- py = MUL_C(IM(tempRight), RE(tempLeft));
+ py = MUL_C(RE(tempLeft), IM(tempRight));
- RE(phaseLeft) = 1.f/xxyy;
- IM(phaseLeft) = IM(tempLeft)/(RE(tempLeft)*xxyy);
+ RE(phaseLeft) = xxyy;
+ IM(phaseLeft) = MUL_R(xxyy, (DIV_R(IM(tempLeft), RE(tempLeft))));
- tmp = 1.f / (yq * xxyy * ppqq);
- RE(phaseRight) = (yq+xp) * tmp;
- IM(phaseRight) = (xq-py) * tmp;
+ tmp = DIV_C(MUL_F(xxyy, ppqq), yq);
+
+ /* MUL_C(FRAC,COEF) = FRAC */
+ RE(phaseRight) = MUL_C(tmp, (yq+xp));
+ IM(phaseRight) = MUL_C(tmp, (xq-py));
#endif
- IM(h11) = RE(h11) * IM(phaseLeft);
- IM(h12) = RE(h12) * IM(phaseRight);
- IM(h21) = RE(h21) * IM(phaseLeft);
- IM(h22) = RE(h22) * IM(phaseRight);
+ /* MUL_F(COEF, FRAC) = COEF */
+ IM(h11) = MUL_F(RE(h11), IM(phaseLeft));
+ IM(h12) = MUL_F(RE(h12), IM(phaseRight));
+ IM(h21) = MUL_F(RE(h21), IM(phaseLeft));
+ IM(h22) = MUL_F(RE(h22), IM(phaseRight));
- RE(h11) *= RE(phaseLeft);
- RE(h12) *= RE(phaseRight);
- RE(h21) *= RE(phaseLeft);
- RE(h22) *= RE(phaseRight);
+ RE(h11) = MUL_F(RE(h11), RE(phaseLeft));
+ RE(h12) = MUL_F(RE(h12), RE(phaseRight));
+ RE(h21) = MUL_F(RE(h21), RE(phaseLeft));
+ RE(h22) = MUL_F(RE(h22), RE(phaseRight));
}
/* length of the envelope n_e+1 - n_e (in time samples) */
+ /* 0 < L <= 32: integer */
L = (real_t)(ps->border_position[env + 1] - ps->border_position[env]);
/* obtain final H_xy by means of linear interpolation */
@@ -1528,9 +1625,9 @@
}
/* apply H_xy to the current envelope band of the decorrelated subband */
- for (i = ps->border_position[env]; i < ps->border_position[env + 1]; i++)
+ for (n = ps->border_position[env]; n < ps->border_position[env + 1]; n++)
{
- /* addition finalises the interpolation */
+ /* addition finalises the interpolation over every n */
RE(H11) += RE(deltaH11);
RE(H12) += RE(deltaH12);
RE(H21) += RE(deltaH21);
@@ -1551,45 +1648,45 @@
/* load decorrelated samples */
if (gr < ps->num_hybrid_groups)
{
- RE(inLeft) = RE(X_hybrid_left[i][sb]);
- IM(inLeft) = IM(X_hybrid_left[i][sb]);
- RE(inRight) = RE(X_hybrid_right[i][sb]);
- IM(inRight) = IM(X_hybrid_right[i][sb]);
+ RE(inLeft) = RE(X_hybrid_left[n][sb]);
+ IM(inLeft) = IM(X_hybrid_left[n][sb]);
+ RE(inRight) = RE(X_hybrid_right[n][sb]);
+ IM(inRight) = IM(X_hybrid_right[n][sb]);
} else {
- RE(inLeft) = RE(X_left[i][sb]);
- IM(inLeft) = IM(X_left[i][sb]);
- RE(inRight) = RE(X_right[i][sb]);
- IM(inRight) = IM(X_right[i][sb]);
+ RE(inLeft) = RE(X_left[n][sb]);
+ IM(inLeft) = IM(X_left[n][sb]);
+ RE(inRight) = RE(X_right[n][sb]);
+ IM(inRight) = IM(X_right[n][sb]);
}
/* apply mixing */
- RE(tempLeft) = RE(H11) * RE(inLeft) + RE(H21) * RE(inRight);
- IM(tempLeft) = RE(H11) * IM(inLeft) + RE(H21) * IM(inRight);
- RE(tempRight) = RE(H12) * RE(inLeft) + RE(H22) * RE(inRight);
- IM(tempRight) = RE(H12) * IM(inLeft) + RE(H22) * IM(inRight);
+ RE(tempLeft) = MUL_C(RE(H11), RE(inLeft)) + MUL_C(RE(H21), RE(inRight));
+ IM(tempLeft) = MUL_C(RE(H11), IM(inLeft)) + MUL_C(RE(H21), IM(inRight));
+ RE(tempRight) = MUL_C(RE(H12), RE(inLeft)) + MUL_C(RE(H22), RE(inRight));
+ IM(tempRight) = MUL_C(RE(H12), IM(inLeft)) + MUL_C(RE(H22), IM(inRight));
/* only perform imaginary operations when needed */
if ((ps->enable_ipdopd) && (bk < nr_ipdopd_par))
{
/* apply rotation */
- RE(tempLeft) -= IM(H11) * IM(inLeft) + IM(H21) * IM(inRight);
- IM(tempLeft) += IM(H11) * RE(inLeft) + IM(H21) * RE(inRight);
- RE(tempRight) -= IM(H12) * IM(inLeft) + IM(H22) * IM(inRight);
- IM(tempRight) += IM(H12) * RE(inLeft) + IM(H22) * RE(inRight);
+ RE(tempLeft) -= MUL_C(IM(H11), IM(inLeft)) + MUL_C(IM(H21), IM(inRight));
+ IM(tempLeft) += MUL_C(IM(H11), RE(inLeft)) + MUL_C(IM(H21), RE(inRight));
+ RE(tempRight) -= MUL_C(IM(H12), IM(inLeft)) + MUL_C(IM(H22), IM(inRight));
+ IM(tempRight) += MUL_C(IM(H12), RE(inLeft)) + MUL_C(IM(H22), RE(inRight));
}
/* store final samples */
if (gr < ps->num_hybrid_groups)
{
- RE(X_hybrid_left[i][sb]) = RE(tempLeft);
- IM(X_hybrid_left[i][sb]) = IM(tempLeft);
- RE(X_hybrid_right[i][sb]) = RE(tempRight);
- IM(X_hybrid_right[i][sb]) = IM(tempRight);
+ RE(X_hybrid_left[n][sb]) = RE(tempLeft);
+ IM(X_hybrid_left[n][sb]) = IM(tempLeft);
+ RE(X_hybrid_right[n][sb]) = RE(tempRight);
+ IM(X_hybrid_right[n][sb]) = IM(tempRight);
} else {
- RE(X_left[i][sb]) = RE(tempLeft);
- IM(X_left[i][sb]) = IM(tempLeft);
- RE(X_right[i][sb]) = RE(tempRight);
- IM(X_right[i][sb]) = IM(tempRight);
+ RE(X_left[n][sb]) = RE(tempLeft);
+ IM(X_left[n][sb]) = IM(tempLeft);
+ RE(X_right[n][sb]) = RE(tempRight);
+ IM(X_right[n][sb]) = IM(tempRight);
}
}
}
--- a/libfaad/ps_dec.h
+++ b/libfaad/ps_dec.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: ps_dec.h,v 1.3 2004/04/03 19:08:38 menno Exp $
+** $Id: ps_dec.h,v 1.6 2004/07/31 15:48:56 menno Exp $
**/
#ifndef __PS_DEC_H__
@@ -104,10 +104,10 @@
uint8_t delay_D[64];
uint8_t delay_buf_index_delay[64];
- complex_t delay_Qmf[14][64]; /* 14 samples delay, 64 QMF channels */
- complex_t delay_SubQmf[14][32]; /* 14 samples delay */
- complex_t delay_Qmf_ser[NO_ALLPASS_LINKS][14][64]; /* 14 samples delay, 64 QMF channels */
- complex_t delay_SubQmf_ser[NO_ALLPASS_LINKS][14][32]; /* 14 samples delay */
+ complex_t delay_Qmf[14][64]; /* 14 samples delay max, 64 QMF channels */
+ complex_t delay_SubQmf[2][32]; /* 2 samples delay max (SubQmf is always allpass filtered) */
+ complex_t delay_Qmf_ser[NO_ALLPASS_LINKS][5][64]; /* 5 samples delay max (table 8.34), 64 QMF channels */
+ complex_t delay_SubQmf_ser[NO_ALLPASS_LINKS][5][32]; /* 5 samples delay max (table 8.34) */
/* transients */
real_t alpha_decay;
--- 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 [email protected].
**
-** $Id: sbr_dec.c,v 1.34 2004/04/03 10:49:15 menno Exp $
+** $Id: sbr_dec.c,v 1.35 2004/04/12 18:17:42 menno Exp $
**/
@@ -96,6 +96,9 @@
sbr->numTimeSlotsRate = RATE * NO_TIME_SLOTS;
sbr->numTimeSlots = NO_TIME_SLOTS;
}
+
+ sbr->GQ_ringbuf_index[0] = 0;
+ sbr->GQ_ringbuf_index[1] = 0;
if (id_aac == ID_CPE)
{
--- 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 [email protected].
**
-** $Id: sbr_dec.h,v 1.30 2004/04/03 10:49:15 menno Exp $
+** $Id: sbr_dec.h,v 1.31 2004/04/12 18:17:42 menno Exp $
**/
#ifndef __SBR_DEC_H__
@@ -43,6 +43,10 @@
#define MAX_NTSRHFG 40
#define MAX_NTSR 32 /* max number_time_slots * rate, ok for DRM and not DRM mode */
+/* MAX_M: maximum value for M */
+#define MAX_M 49
+/* MAX_L_E: maximum value for L_E */
+#define MAX_L_E 5
typedef struct {
real_t *x;
@@ -98,18 +102,19 @@
uint8_t L_E_prev[2];
uint8_t L_Q[2];
- uint8_t t_E[2][6];
+ uint8_t t_E[2][MAX_L_E+1];
uint8_t t_Q[2][3];
- uint8_t f[2][6];
+ uint8_t f[2][MAX_L_E+1];
uint8_t f_prev[2];
real_t *G_temp_prev[2][5];
real_t *Q_temp_prev[2][5];
+ int8_t GQ_ringbuf_index[2];
- int16_t E[2][64][5];
+ int16_t E[2][64][MAX_L_E];
int16_t E_prev[2][64];
- real_t E_orig[2][64][5];
- real_t E_curr[2][64][5];
+ real_t E_orig[2][64][MAX_L_E];
+ real_t E_curr[2][64][MAX_L_E];
int32_t Q[2][64][2];
real_t Q_div[2][64][2];
real_t Q_div2[2][64][2];
@@ -118,8 +123,8 @@
int8_t l_A[2];
int8_t l_A_prev[2];
- uint8_t bs_invf_mode[2][5];
- uint8_t bs_invf_mode_prev[2][5];
+ uint8_t bs_invf_mode[2][MAX_L_E];
+ uint8_t bs_invf_mode_prev[2][MAX_L_E];
real_t bwArray[2][64];
real_t bwArray_prev[2][64];
--- a/libfaad/sbr_fbt.c
+++ b/libfaad/sbr_fbt.c
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: sbr_fbt.c,v 1.12 2004/03/10 19:45:41 menno Exp $
+** $Id: sbr_fbt.c,v 1.13 2004/04/12 18:17:42 menno Exp $
**/
/* Calculate frequency band tables */
@@ -594,7 +594,7 @@
printf("f_table_noise[%d]: ", sbr->N_Q);
for (k = 0; k <= sbr->N_Q; k++)
{
- printf("%d ", sbr->f_table_noise[k]);
+ printf("%d ", sbr->f_table_noise[k] - sbr->kx);
}
printf("\n");
#endif
@@ -626,6 +626,15 @@
sbr->f_table_lim[0][1] = sbr->f_table_res[LO_RES][sbr->N_low] - sbr->kx;
sbr->N_L[0] = 1;
+#if 0
+ printf("f_table_lim[%d][%d]: ", 0, sbr->N_L[0]);
+ for (k = 0; k <= sbr->N_L[0]; k++)
+ {
+ printf("%d ", sbr->f_table_lim[0][k]);
+ }
+ printf("\n");
+#endif
+
for (s = 1; s < 4; s++)
{
int32_t limTable[100 /*TODO*/] = {0};
@@ -668,7 +677,7 @@
nOctaves = REAL_CONST(log((float)limTable[k]/(float)limTable[k-1])/log(2.0));
#else
#ifdef FIXED_POINT
- nOctaves = SBR_DIV(REAL_CONST(limTable[k]),REAL_CONST(limTable[k-1]));
+ nOctaves = DIV_R(REAL_CONST(limTable[k]),REAL_CONST(limTable[k-1]));
#else
nOctaves = (real_t)limTable[k]/(real_t)limTable[k-1];
#endif
--- a/libfaad/sbr_hfadj.c
+++ b/libfaad/sbr_hfadj.c
@@ -1,19 +1,19 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
-**
+**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
-**
+**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
-**
+**
** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
+** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
** Any non-GPL usage of this software or parts of this software is strictly
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: sbr_hfadj.c,v 1.13 2004/03/19 10:37:55 menno Exp $
+** $Id: sbr_hfadj.c,v 1.14 2004/04/12 18:17:42 menno Exp $
**/
/* High Frequency adjustment */
@@ -77,28 +77,25 @@
static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
{
uint8_t l, i;
- uint32_t m;
+ uint8_t m;
for (l = 0; l < sbr->L_E[ch]; l++)
{
- for (i = 0; i < sbr->N_Q; i++)
+ uint8_t k;
+
+ /* select the noise time band k that completely holds the current envelope time band l */
+ for (k = 0; k < 2; k++)
{
- for (m = sbr->f_table_noise[i]; m < sbr->f_table_noise[i+1]; m++)
+ if ((sbr->t_E[ch][l] >= sbr->t_Q[ch][k]) && (sbr->t_E[ch][l+1] <= sbr->t_Q[ch][k+1]))
{
- uint8_t k;
-
- adj->Q_div_mapped[m - sbr->kx][l] = 0;
- adj->Q_div2_mapped[m - sbr->kx][l] = 0;
-
- for (k = 0; k < 2; k++)
+ for (i = 0; i < sbr->N_Q; i++)
{
- if ((sbr->t_E[ch][l] >= sbr->t_Q[ch][k]) &&
- (sbr->t_E[ch][l+1] <= sbr->t_Q[ch][k+1]))
+ for (m = sbr->f_table_noise[i]; m < sbr->f_table_noise[i+1]; m++)
{
- adj->Q_div_mapped[m - sbr->kx][l] =
+ adj->Q_div_mapped[l][m - sbr->kx] =
sbr->Q_div[ch][i][k];
- adj->Q_div2_mapped[m - sbr->kx][l] =
+ adj->Q_div2_mapped[l][m - sbr->kx] =
sbr->Q_div2[ch][i][k];
}
}
@@ -130,8 +127,8 @@
{
for (i = 0; i < 64; i++)
{
- adj->S_index_mapped[i][l] = 0;
- adj->S_mapped[i][l] = 0;
+ adj->S_index_mapped[l][i] = 0;
+ adj->S_mapped[l][i] = 0;
}
}
@@ -139,22 +136,12 @@
{
for (i = 0; i < sbr->N_high; i++)
{
- for (m = sbr->f_table_res[HI_RES][i]; m < sbr->f_table_res[HI_RES][i+1]; m++)
+ if ((l >= sbr->l_A[ch]) ||
+ (sbr->bs_add_harmonic_prev[ch][i] && sbr->bs_add_harmonic_flag_prev[ch]))
{
- uint8_t delta_step = 0;
- if ((l >= sbr->l_A[ch]) || ((sbr->bs_add_harmonic_prev[ch][i]) &&
- (sbr->bs_add_harmonic_flag_prev[ch])))
- {
- delta_step = 1;
- }
-
- if (m == (int32_t)((real_t)(sbr->f_table_res[HI_RES][i+1]+sbr->f_table_res[HI_RES][i])/2.))
- {
- adj->S_index_mapped[m - sbr->kx][l] =
- delta_step * sbr->bs_add_harmonic[ch][i];
- } else {
- adj->S_index_mapped[m - sbr->kx][l] = 0;
- }
+ /* find the middle subband of the frequency band */
+ m = (sbr->f_table_res[HI_RES][i+1] + sbr->f_table_res[HI_RES][i]) >> 1;
+ adj->S_index_mapped[l][m - sbr->kx] = /*delta_step **/ sbr->bs_add_harmonic[ch][i];
}
}
}
@@ -163,7 +150,7 @@
{
for (i = 0; i < sbr->N_high; i++)
{
- if (sbr->f[ch][l] == 1)
+ if (sbr->f[ch][l] == HI_RES)
{
k1 = i;
k2 = i + 1;
@@ -192,18 +179,59 @@
delta_S = 0;
for (k = l_i; k < u_i; k++)
{
- if (adj->S_index_mapped[k - sbr->kx][l] == 1)
+ if (adj->S_index_mapped[l][k - sbr->kx] == 1)
delta_S = 1;
}
for (m = l_i; m < u_i; m++)
{
- adj->S_mapped[m - sbr->kx][l] = delta_S;
+ adj->S_mapped[l][m - sbr->kx] = delta_S;
}
}
}
}
+static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band)
+{
+ if (sbr->f[ch][l] == HI_RES)
+ {
+ /* in case of using f_table_high we just have 1 to 1 mapping
+ * from bs_add_harmonic[l][k]
+ */
+ if ((l >= sbr->l_A[ch]) ||
+ (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch]))
+ {
+ return sbr->bs_add_harmonic[ch][current_band];
+ }
+ } else {
+ uint8_t b, lb, ub;
+
+ /* in case of f_table_low we check if any of the HI_RES bands
+ * within this LO_RES band has bs_add_harmonic[l][k] turned on
+ * (note that borders in the LO_RES table are also present in
+ * the HI_RES table)
+ */
+
+ /* find first HI_RES band in current LO_RES band */
+ lb = 2*current_band - ((sbr->N_high & 1) ? 1 : 0);
+ /* find first HI_RES band in next LO_RES band */
+ ub = 2*(current_band+1) - ((sbr->N_high & 1) ? 1 : 0);
+
+ /* check all HI_RES bands in current LO_RES band for sinusoid */
+ for (b = lb; b < ub; b++)
+ {
+ if ((l >= sbr->l_A[ch]) ||
+ (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch]))
+ {
+ if (sbr->bs_add_harmonic[ch][b] == 1)
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
{
@@ -445,13 +473,13 @@
{
uint8_t m, l, k, i;
- ALIGN real_t Q_M_lim[64];
- ALIGN real_t G_lim[64];
+ ALIGN real_t Q_M_lim[MAX_M];
+ ALIGN real_t G_lim[MAX_M];
ALIGN real_t G_boost;
- ALIGN real_t S_M[64];
- ALIGN uint8_t table_map_res_to_m[64];
- ALIGN uint8_t G_is_frac[64];
- ALIGN uint8_t Q_M_is_real[64];
+ ALIGN real_t S_M[MAX_M];
+ ALIGN uint8_t table_map_res_to_m[MAX_M];
+ ALIGN uint8_t G_is_frac[MAX_M];
+ ALIGN uint8_t Q_M_is_real[MAX_M];
for (l = 0; l < sbr->L_E[ch]; l++)
@@ -549,9 +577,9 @@
/* Q_mapped: fixed point */
/* Q_div1: [0..1] FRAC_CONST */
- Q_div1 = adj->Q_div_mapped[m][l];
+ Q_div1 = adj->Q_div_mapped[l][m];
/* Q_div2: [0..1] FRAC_CONST */
- Q_div2 = adj->Q_div2_mapped[m][l];
+ Q_div2 = adj->Q_div2_mapped[l][m];
/* E_orig: integer */
E_orig = sbr->E_orig[ch][table_map_res_to_m[m]][l];
@@ -564,18 +592,18 @@
Q_M = ((int64_t)(E_orig>>4) * Q_div2) >> FRAC_BITS;
Q_M_is_real[m] = 0;
- S_M[m] = adj->S_index_mapped[m][l] * MUL_F((E_orig>>4), Q_div1);
+ S_M[m] = adj->S_index_mapped[l][m] * MUL_F((E_orig>>4), Q_div1);
} else if (E_orig > (1<<4)) {
Q_M = ((int64_t)(E_orig>>4) * Q_div2) >> (FRAC_BITS-REAL_BITS);
Q_M_is_real[m] = 1;
- S_M[m] = adj->S_index_mapped[m][l] * MUL_F((E_orig>>4), Q_div1);
+ S_M[m] = adj->S_index_mapped[l][m] * MUL_F((E_orig>>4), Q_div1);
} else {
Q_M = ((int64_t)E_orig * Q_div2) >> (FRAC_BITS-REAL_BITS);
Q_M >>= 4;
Q_M_is_real[m] = 1;
- S_M[m] = adj->S_index_mapped[m][l] * MUL_F(E_orig, Q_div1);
+ S_M[m] = adj->S_index_mapped[l][m] * MUL_F(E_orig, Q_div1);
S_M[m] >>= 4;
}
@@ -617,7 +645,7 @@
G_is_frac[m] = 0;
}
- if (adj->S_mapped[m][l] == 1)
+ if (adj->S_mapped[l][m] == 1)
{
G = MUL_F(G, Q_div2);
} else if (delta == 1) {
@@ -668,7 +696,7 @@
den_int += MUL_F(sbr->E_curr[ch][m][l], G_lim[m]);
}
den_int += S_M[m];
- if ((!adj->S_index_mapped[m][l]) && (l != sbr->l_A[ch]))
+ if ((!adj->S_index_mapped[l][m]) && (l != sbr->l_A[ch]))
{
if (Q_M_is_real[m] == 1)
{
@@ -727,7 +755,7 @@
}
/* S_M_boost: integer */
- if (adj->S_index_mapped[m][l])
+ if (adj->S_index_mapped[l][m])
{
adj->S_M_boost[l][m] = SBR_SQRT_INT(MUL_R(S_M[m], G_boost));
} else {
@@ -742,24 +770,30 @@
static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
{
static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 };
- uint8_t m, l, k, i;
+ uint8_t m, l, k;
- ALIGN real_t Q_M_lim[64];
- ALIGN real_t G_lim[64];
+ uint8_t current_t_noise_band = 0;
+ uint8_t S_mapped;
+
+ ALIGN real_t Q_M_lim[MAX_M];
+ ALIGN real_t G_lim[MAX_M];
ALIGN real_t G_boost;
- ALIGN real_t S_M[64];
- ALIGN uint8_t table_map_res_to_m[64];
+ ALIGN real_t S_M[MAX_M];
for (l = 0; l < sbr->L_E[ch]; l++)
{
+ uint8_t current_f_noise_band = 0;
+ uint8_t current_res_band = 0;
+ uint8_t current_res_band2 = 0;
+ uint8_t current_hi_res_band = 0;
+
real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
- for (i = 0; i < sbr->n[sbr->f[ch][l]]; i++)
+ S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
+
+ if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
{
- for (m = sbr->f_table_res[sbr->f[ch][l]][i]; m < sbr->f_table_res[sbr->f[ch][l]][i+1]; m++)
- {
- table_map_res_to_m[m - sbr->kx] = i;
- }
+ current_t_noise_band++;
}
for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
@@ -768,6 +802,7 @@
real_t den = 0;
real_t acc1 = 0;
real_t acc2 = 0;
+ uint8_t current_res_band_size = 0;
uint8_t ml1, ml2;
@@ -778,39 +813,110 @@
/* calculate the accumulated E_orig and E_curr over the limiter band */
for (m = ml1; m < ml2; m++)
{
- acc1 += sbr->E_orig[ch][table_map_res_to_m[m]][l];
+ if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
+ {
+ current_res_band++;
+ }
+ acc1 += sbr->E_orig[ch][current_res_band][l];
acc2 += sbr->E_curr[ch][m][l];
}
- G_max = ((EPS + acc1)/(EPS + acc2)) * limGain[sbr->bs_limiter_gains];
+
+ /* calculate the maximum gain */
+ /* ratio of the energy of the original signal and the energy
+ * of the HF generated signal
+ */
+ G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains];
G_max = min(G_max, 1e10);
+
for (m = ml1; m < ml2; m++)
{
real_t Q_M, G;
real_t Q_div, Q_div2;
+ uint8_t S_index_mapped;
+
+ /* check if m is on a noise band border */
+ if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
+ {
+ /* step to next noise band */
+ current_f_noise_band++;
+ }
+
+
+ /* check if m is on a resolution band border */
+ if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
+ {
+ /* step to next resolution band */
+ current_res_band2++;
+
+ /* if we move to a new resolution band, we should check if we are
+ * going to add a sinusoid in this band
+ */
+ S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
+ }
+
+
+ /* check if m is on a HI_RES band border */
+ if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
+ {
+ /* step to next HI_RES band */
+ current_hi_res_band++;
+ }
+
+
+ /* find S_index_mapped
+ * S_index_mapped can only be 1 for the m in the middle of the
+ * current HI_RES band
+ */
+ S_index_mapped = 0;
+ if ((l >= sbr->l_A[ch]) ||
+ (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
+ {
+ /* find the middle subband of the HI_RES frequency band */
+ if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1)
+ S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
+ }
+
+
/* Q_div: [0..1] (1/(1+Q_mapped)) */
- Q_div = adj->Q_div_mapped[m][l];
+ Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band];
+
/* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */
- Q_div2 = adj->Q_div2_mapped[m][l];
+ Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band];
- Q_M = sbr->E_orig[ch][table_map_res_to_m[m]][l] * Q_div2;
- /* 12-Nov: Changed S_mapped to S_index_mapped */
- if (adj->S_index_mapped[m][l] == 0)
+ /* Q_M only depends on E_orig and Q_div2:
+ * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on
+ * a change of current noise band
+ */
+ Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2;
+
+
+ /* S_M only depends on E_orig, Q_div and S_index_mapped:
+ * S_index_mapped can only be non-zero once per HI_RES band
+ */
+ if (S_index_mapped == 0)
{
S_M[m] = 0;
} else {
- S_M[m] = sbr->E_orig[ch][table_map_res_to_m[m]][l] * Q_div;
+ S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div;
+
+ /* accumulate sinusoid part of the total energy */
+ den += S_M[m];
}
- G = sbr->E_orig[ch][table_map_res_to_m[m]][l] / (1.0 + sbr->E_curr[ch][m][l]);
- if ((adj->S_mapped[m][l] == 0) && (delta == 1))
+ /* calculate gain */
+ /* ratio of the energy of the original signal and the energy
+ * of the HF generated signal
+ */
+ G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]);
+ if ((S_mapped == 0) && (delta == 1))
G *= Q_div;
- else if (adj->S_mapped[m][l] == 1)
+ else if (S_mapped == 1)
G *= Q_div2;
@@ -821,14 +927,14 @@
Q_M_lim[m] = Q_M;
G_lim[m] = G;
} else {
- Q_M_lim[m] = Q_M * G_max / G; /* equivalent to code below */
+ Q_M_lim[m] = Q_M * G_max / G;
G_lim[m] = G_max;
}
+
+ /* accumulate the total energy */
den += sbr->E_curr[ch][m][l] * G_lim[m];
- if (adj->S_index_mapped[m][l])
- den += S_M[m];
- else if (l != sbr->l_A[ch])
+ if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
den += Q_M_lim[m];
}
@@ -849,7 +955,7 @@
#endif
adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost);
- if (adj->S_index_mapped[m][l])
+ if (S_M[m] != 0)
{
adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost);
} else {
@@ -874,7 +980,7 @@
for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++)
{
- if (deg[k + 1] && adj->S_mapped[k-sbr->kx][l] == 0)
+ if (deg[k + 1] && adj->S_mapped[l][k-sbr->kx] == 0)
{
if (grouping == 0)
{
@@ -885,7 +991,7 @@
} else {
if (grouping)
{
- if (adj->S_mapped[k-sbr->kx][l])
+ if (adj->S_mapped[l][k-sbr->kx])
{
sbr->f_group[l][i] = k;
} else {
@@ -895,7 +1001,7 @@
i++;
}
}
- }
+ }
if (grouping)
{
@@ -917,7 +1023,7 @@
for (k = 0; k < sbr->N_G[l]; k++)
{
E_total_est = E_total = 0;
-
+
for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++)
{
/* E_curr: integer */
@@ -1023,7 +1129,6 @@
uint16_t fIndexNoise = 0;
uint8_t fIndexSine = 0;
uint8_t assembly_reset = 0;
- real_t *temp;
real_t G_filt, Q_filt;
@@ -1058,6 +1163,8 @@
memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
}
+ /* reset ringbuffer index */
+ sbr->GQ_ringbuf_index[ch] = 4;
assembly_reset = 0;
}
@@ -1068,8 +1175,9 @@
uint8_t sinusoids = 0;
#endif
- memcpy(sbr->G_temp_prev[ch][4], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
- memcpy(sbr->Q_temp_prev[ch][4], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
+ /* load new values into ringbuffer */
+ memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
+ memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
for (m = 0; m < sbr->M; m++)
{
@@ -1083,13 +1191,16 @@
{
for (n = 0; n <= 4; n++)
{
- G_filt += MUL_F(sbr->G_temp_prev[ch][n][m], h_smooth[n]);
- Q_filt += MUL_F(sbr->Q_temp_prev[ch][n][m], h_smooth[n]);
+ uint8_t ri = sbr->GQ_ringbuf_index[ch] + 1 + n;
+ if (ri >= 5)
+ ri -= 5;
+ G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], h_smooth[n]);
+ Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], h_smooth[n]);
}
} else {
#endif
- G_filt = sbr->G_temp_prev[ch][4][m];
- Q_filt = sbr->Q_temp_prev[ch][4][m];
+ G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
+ Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
#ifndef SBR_LOW_POWER
}
#endif
@@ -1219,16 +1330,10 @@
fIndexSine = (fIndexSine + 1) & 3;
-
- temp = sbr->G_temp_prev[ch][0];
- for (n = 0; n < 4; n++)
- sbr->G_temp_prev[ch][n] = sbr->G_temp_prev[ch][n+1];
- sbr->G_temp_prev[ch][4] = temp;
-
- temp = sbr->Q_temp_prev[ch][0];
- for (n = 0; n < 4; n++)
- sbr->Q_temp_prev[ch][n] = sbr->Q_temp_prev[ch][n+1];
- sbr->Q_temp_prev[ch][4] = temp;
+ /* update the ringbuffer index used for filtering G and Q with h_smooth */
+ sbr->GQ_ringbuf_index[ch]++;
+ if (sbr->GQ_ringbuf_index[ch] >= 5)
+ sbr->GQ_ringbuf_index[ch] = 0;
}
}
--- a/libfaad/sbr_hfadj.h
+++ b/libfaad/sbr_hfadj.h
@@ -22,7 +22,7 @@
** Commercial non-GPL licensing of this software is possible.
** For more info contact Ahead Software through [email protected].
**
-** $Id: sbr_hfadj.h,v 1.11 2004/03/10 19:45:42 menno Exp $
+** $Id: sbr_hfadj.h,v 1.12 2004/04/12 18:17:42 menno Exp $
**/
#ifndef __SBR_HFADJ_H__
@@ -34,15 +34,15 @@
typedef struct
{
- real_t Q_div_mapped[64][5];
- real_t Q_div2_mapped[64][5];
+ real_t Q_div_mapped[MAX_L_E][MAX_M];
+ real_t Q_div2_mapped[MAX_L_E][MAX_M];
- uint8_t S_index_mapped[64][5];
- uint8_t S_mapped[64][5];
+ uint8_t S_index_mapped[MAX_L_E][MAX_M];
+ uint8_t S_mapped[MAX_L_E][MAX_M];
- real_t G_lim_boost[5][64];
- real_t Q_M_lim_boost[5][64];
- real_t S_M_boost[5][64];
+ real_t G_lim_boost[MAX_L_E][MAX_M];
+ real_t Q_M_lim_boost[MAX_L_E][MAX_M];
+ real_t S_M_boost[MAX_L_E][MAX_M];
} sbr_hfadj_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 [email protected].
**
-** $Id: sbr_hfgen.c,v 1.16 2004/04/03 10:49:15 menno Exp $
+** $Id: sbr_hfgen.c,v 1.17 2004/04/12 18:17:42 menno Exp $
**/
/* High Frequency generation */
@@ -384,9 +384,9 @@
} else {
#ifdef FIXED_POINT
tmp = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11)));
- RE(alpha_1[k]) = SBR_DIV(tmp, ac.det);
+ RE(alpha_1[k]) = DIV_R(tmp, ac.det);
tmp = (MUL_R(IM(ac.r01), RE(ac.r12)) + MUL_R(RE(ac.r01), IM(ac.r12)) - MUL_R(IM(ac.r02), RE(ac.r11)));
- IM(alpha_1[k]) = SBR_DIV(tmp, ac.det);
+ IM(alpha_1[k]) = DIV_R(tmp, ac.det);
#else
tmp = REAL_CONST(1.0) / ac.det;
RE(alpha_1[k]) = (MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(IM(ac.r01), IM(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11))) * tmp;
@@ -401,9 +401,9 @@
} else {
#ifdef FIXED_POINT
tmp = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12)));
- RE(alpha_0[k]) = SBR_DIV(tmp, RE(ac.r11));
+ RE(alpha_0[k]) = DIV_R(tmp, RE(ac.r11));
tmp = -(IM(ac.r01) + MUL_R(IM(alpha_1[k]), RE(ac.r12)) - MUL_R(RE(alpha_1[k]), IM(ac.r12)));
- IM(alpha_0[k]) = SBR_DIV(tmp, RE(ac.r11));
+ IM(alpha_0[k]) = DIV_R(tmp, RE(ac.r11));
#else
tmp = 1.0f / RE(ac.r11);
RE(alpha_0[k]) = -(RE(ac.r01) + MUL_R(RE(alpha_1[k]), RE(ac.r12)) + MUL_R(IM(alpha_1[k]), IM(ac.r12))) * tmp;
@@ -438,10 +438,10 @@
RE(alpha_1[k]) = 0;
} else {
tmp = MUL_R(RE(ac.r01), RE(ac.r22)) - MUL_R(RE(ac.r12), RE(ac.r02));
- RE(alpha_0[k]) = SBR_DIV(tmp, (-ac.det));
+ RE(alpha_0[k]) = DIV_R(tmp, (-ac.det));
tmp = MUL_R(RE(ac.r01), RE(ac.r12)) - MUL_R(RE(ac.r02), RE(ac.r11));
- RE(alpha_1[k]) = SBR_DIV(tmp, ac.det);
+ RE(alpha_1[k]) = DIV_R(tmp, ac.det);
}
if ((RE(alpha_0[k]) >= REAL_CONST(4)) || (RE(alpha_1[k]) >= REAL_CONST(4)))
@@ -455,11 +455,7 @@
{
rxx[k] = COEF_CONST(0.0);
} else {
-#ifdef FIXED_POINT
- rxx[k] = ((int64_t)RE(ac.r01) << COEF_BITS) / RE(ac.r11);
-#else
- rxx[k] = RE(ac.r01) / RE(ac.r11);
-#endif
+ rxx[k] = DIV_C(RE(ac.r01), RE(ac.r11));
rxx[k] = -rxx[k];
if (rxx[k] > COEF_CONST(1.0)) rxx[k] = COEF_CONST(1.0);
if (rxx[k] < COEF_CONST(-1.0)) rxx[k] = COEF_CONST(-1.0);