diff libfaad2/sbr_hfadj.c @ 12527:4a370c80fe5c

update to the 2.0 release of faad, patch by adland
author diego
date Wed, 02 Jun 2004 22:59:04 +0000
parents 3185f64f6350
children d81145997036
line wrap: on
line diff
--- a/libfaad2/sbr_hfadj.c	Wed Jun 02 22:52:00 2004 +0000
+++ b/libfaad2/sbr_hfadj.c	Wed Jun 02 22:59:04 2004 +0000
@@ -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 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 @@
 
                 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 @@
                     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 @@
     }
 }
 
+
 #define EPS (1e-12)
 
 #define ONE (1)
@@ -274,11 +287,11 @@
     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 @@
                 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;
+                } else {
+                    real_t div;
 
-                    /* fixed point: delta* can stay since it's either 1 or 0 */
+                    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 {
-                    real_t div;
-
-                    div = adj->S_mapped[m][l] / (1. + adj->Q_mapped[m][l]);
-                    S_M[m] = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div;
                     G = (sbr->E_orig[ch][table_map_res_to_m[m]][l] / (1. + sbr->E_curr[ch][m][l])) * div2;
                 }
 
@@ -440,7 +457,7 @@
                 /* 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 @@
                     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 @@
                 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 @@
 #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 @@
             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 @@
                 {
                     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 @@
 
                 /* 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
                 }
             }