summaryrefslogtreecommitdiffstats
path: root/libfaad2/sbr_hfadj.c
diff options
context:
space:
mode:
Diffstat (limited to 'libfaad2/sbr_hfadj.c')
-rw-r--r--libfaad2/sbr_hfadj.c144
1 files changed, 84 insertions, 60 deletions
diff --git a/libfaad2/sbr_hfadj.c b/libfaad2/sbr_hfadj.c
index 2fc35a333c..f2acde7c36 100644
--- a/libfaad2/sbr_hfadj.c
+++ b/libfaad2/sbr_hfadj.c
@@ -1,6 +1,6 @@
/*
** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003 M. Bakker, Ahead Software AG, http://www.nero.com
+** 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
@@ -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_hfadj.c,v 1.4 2003/09/09 18:37:32 menno Exp $
+** $Id: sbr_hfadj.c,v 1.2 2003/10/03 22:22:27 alex Exp $
**/
/* High Frequency adjustment */
@@ -37,15 +37,27 @@
#include "sbr_noise.h"
-void hf_adjustment(sbr_info *sbr, qmf_t *Xsbr
+
+/* static function delcarations */
+static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
+static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
+static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
+ qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
+static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
+#ifdef SBR_LOW_POWER
+static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
+static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
+#endif
+static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
+
+
+void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
#ifdef SBR_LOW_POWER
,real_t *deg /* aliasing degree */
#endif
,uint8_t ch)
{
- sbr_hfadj_info adj;
-
- memset(&adj, 0, sizeof(sbr_hfadj_info));
+ ALIGN sbr_hfadj_info adj = {{{0}}};
map_noise_data(sbr, &adj, ch);
map_sinusoids(sbr, &adj, ch);
@@ -188,8 +200,8 @@ static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
}
}
-static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr,
- uint8_t ch)
+static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
+ qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
{
uint8_t m, l, j, k, k_l, k_h, p;
real_t nrg, div;
@@ -211,9 +223,9 @@ static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t
for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
{
- nrg += MUL(QMF_RE(Xsbr[(i<<6) + m + sbr->kx]), QMF_RE(Xsbr[(i<<6) + m + sbr->kx]))
+ nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx]))
#ifndef SBR_LOW_POWER
- + MUL(QMF_IM(Xsbr[(i<<6) + m + sbr->kx]), QMF_IM(Xsbr[(i<<6) + m + sbr->kx]))
+ + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx]))
#endif
;
}
@@ -240,15 +252,15 @@ static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t
l_i = sbr->t_E[ch][l];
u_i = sbr->t_E[ch][l+1];
- div = (real_t)((u_i - l_i)*(k_h - k_l + 1));
+ div = (real_t)((u_i - l_i)*(k_h - k_l));
for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
{
for (j = k_l; j < k_h; j++)
{
- nrg += MUL(QMF_RE(Xsbr[(i<<6) + j]), QMF_RE(Xsbr[(i<<6) + j]))
+ nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j]))
#ifndef SBR_LOW_POWER
- + MUL(QMF_IM(Xsbr[(i<<6) + j]), QMF_IM(Xsbr[(i<<6) + j]))
+ + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j]))
#endif
;
}
@@ -264,6 +276,7 @@ static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t
}
}
+
#define EPS (1e-12)
#define ONE (1)
@@ -274,11 +287,11 @@ 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;
- real_t Q_M_lim[64];
- real_t G_lim[64];
- real_t G_boost;
- real_t S_M[64];
- uint8_t table_map_res_to_m[64];
+ ALIGN real_t Q_M_lim[64];
+ ALIGN real_t G_lim[64];
+ ALIGN real_t G_boost;
+ ALIGN real_t S_M[64];
+ ALIGN uint8_t table_map_res_to_m[64];
for (l = 0; l < sbr->L_E[ch]; l++)
@@ -319,18 +332,22 @@ static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
div2 = adj->Q_mapped[m][l] / (1 + adj->Q_mapped[m][l]);
Q_M = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div2;
- if (adj->S_mapped[m][l] == 0)
+ /* 12-Nov: Changed S_mapped to S_index_mapped */
+ if (adj->S_index_mapped[m][l] == 0)
{
S_M[m] = 0;
-
- /* fixed point: delta* can stay since it's either 1 or 0 */
- d = (1 + sbr->E_curr[ch][m][l]) * (1 + delta*adj->Q_mapped[m][l]);
- G = sbr->E_orig[ch][table_map_res_to_m[m]][l] / d;
} else {
real_t div;
- div = adj->S_mapped[m][l] / (1. + adj->Q_mapped[m][l]);
+ div = adj->S_index_mapped[m][l] / (1. + adj->Q_mapped[m][l]);
S_M[m] = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div;
+ }
+
+ if (adj->S_mapped[m][l] == 0)
+ {
+ d = (1 + sbr->E_curr[ch][m][l]) * (1 + delta*adj->Q_mapped[m][l]);
+ G = sbr->E_orig[ch][table_map_res_to_m[m]][l] / d;
+ } else {
G = (sbr->E_orig[ch][table_map_res_to_m[m]][l] / (1. + sbr->E_curr[ch][m][l])) * div2;
}
@@ -440,7 +457,7 @@ static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg,
/* E_total_est: integer */
/* E_total: integer */
E_total_est += sbr->E_curr[ch][m-sbr->kx][l];
- E_total += MUL(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]);
+ E_total += MUL_R(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]);
}
/* G_target: fixed point */
@@ -462,11 +479,11 @@ static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg,
alpha = deg[m];
}
- adj->G_lim_boost[l][m-sbr->kx] = MUL(alpha, G_target) +
- MUL((REAL_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]);
+ adj->G_lim_boost[l][m-sbr->kx] = MUL_R(alpha, G_target) +
+ MUL_R((REAL_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]);
/* acc: integer */
- acc += MUL(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]);
+ acc += MUL_R(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]);
}
/* acc: fixed point */
@@ -474,10 +491,9 @@ static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg,
acc = 0;
else
acc = E_total / (acc + EPS);
-
for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
{
- adj->G_lim_boost[l][m-sbr->kx] = MUL(acc, adj->G_lim_boost[l][m-sbr->kx]);
+ adj->G_lim_boost[l][m-sbr->kx] = MUL_R(acc, adj->G_lim_boost[l][m-sbr->kx]);
}
}
}
@@ -497,7 +513,7 @@ static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg,
#endif
static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
- qmf_t *Xsbr, uint8_t ch)
+ qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
{
static real_t h_smooth[] = {
COEF_CONST(0.03183050093751), COEF_CONST(0.11516383427084),
@@ -549,7 +565,6 @@ static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
assembly_reset = 0;
}
-
for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++)
{
#ifdef SBR_LOW_POWER
@@ -574,8 +589,8 @@ static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
{
for (n = 0; n <= 4; n++)
{
- G_filt += MUL_R_C(sbr->G_temp_prev[ch][n][m], h_smooth[j]);
- Q_filt += MUL_R_C(sbr->Q_temp_prev[ch][n][m], h_smooth[j]);
+ G_filt += MUL_C(sbr->G_temp_prev[ch][n][m], h_smooth[j]);
+ Q_filt += MUL_C(sbr->Q_temp_prev[ch][n][m], h_smooth[j]);
j++;
}
} else {
@@ -590,52 +605,61 @@ static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
/* the smoothed gain values are applied to Xsbr */
/* V is defined, not calculated */
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]))
- + MUL_R_C(Q_filt, RE(V[fIndexNoise]));
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
+ + MUL_F(Q_filt, RE(V[fIndexNoise]));
if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42)
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) = 16428320;
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320;
#ifndef SBR_LOW_POWER
- QMF_IM(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_IM(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]))
- + MUL_R_C(Q_filt, IM(V[fIndexNoise]));
+ QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
+ + MUL_F(Q_filt, IM(V[fIndexNoise]));
#endif
-
- if (adj->S_index_mapped[m][l])
+ //if (adj->S_index_mapped[m][l])
{
- int8_t rev = ((m + sbr->kx) & 1) ? -1 : 1;
- QMF_RE(psi) = MUL(adj->S_M_boost[l][m], phi_re[fIndexSine]);
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) += QMF_RE(psi);
+ int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1);
+ QMF_RE(psi) = MUL_R(adj->S_M_boost[l][m], phi_re[fIndexSine]);
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi);
#ifndef SBR_LOW_POWER
- QMF_IM(psi) = rev * MUL(adj->S_M_boost[l][m], phi_im[fIndexSine]);
- QMF_IM(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) += QMF_IM(psi);
+ QMF_IM(psi) = rev * MUL_R(adj->S_M_boost[l][m], phi_im[fIndexSine]);
+ QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi);
#else
i_min1 = (fIndexSine - 1) & 3;
i_plus1 = (fIndexSine + 1) & 3;
if (m == 0)
{
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx - 1]) -=
- (rev * MUL_R_C(MUL(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815)));
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
- (rev * MUL_R_C(MUL(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815)));
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) -=
+ (-1*rev * MUL_C(MUL_R(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815)));
+ if(m < sbr->M - 1)
+ {
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
+ (rev * MUL_C(MUL_R(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815)));
+ }
}
if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16))
{
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
- (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
- (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815)));
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
+ (rev * MUL_C(MUL_R(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
+ (rev * MUL_C(MUL_R(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815)));
}
- if ((m == sbr->M - 1) && (sinusoids < 16) && (m + sbr->kx + 1 < 63))
+ if ((m == sbr->M - 1) && (sinusoids < 16))
{
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx]) -=
- (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
- QMF_RE(Xsbr[((i + sbr->tHFAdj)<<6) + m+sbr->kx + 1]) -=
- (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_min1]), COEF_CONST(0.00815)));
+ if (m > 0)
+ {
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
+ (rev * MUL_C(MUL_R(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815)));
+ }
+ if (m + sbr->kx < 64)
+ {
+ QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) -=
+ (-1*rev * MUL_C(MUL_R(adj->S_M_boost[l][m], phi_re[i_min1]), COEF_CONST(0.00815)));
+ }
}
- sinusoids++;
+ if (adj->S_M_boost[l][m] != 0)
+ sinusoids++;
#endif
}
}