diff src/aac/libfaad2/drm_dec.c @ 691:e6c5fdae6e88 trunk

[svn] - oh yes, commit mplayer patches as well
author nenolod
date Tue, 20 Feb 2007 06:38:03 -0800
parents 1d8b08df98c3
children f1b6f1b2cdb3
line wrap: on
line diff
--- a/src/aac/libfaad2/drm_dec.c	Tue Feb 20 06:31:29 2007 -0800
+++ b/src/aac/libfaad2/drm_dec.c	Tue Feb 20 06:38:03 2007 -0800
@@ -1,33 +1,28 @@
 /*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**  
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR and PS 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
 ** forbidden.
 **
-** Software using this code must display the following message visibly in or
-** on each copy of the software:
-** "FAAD2 AAC/HE-AAC/HE-AACv2/DRM decoder (c) Nero AG, www.nero.com"
-** in, for example, the about-box or help/startup screen.
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
 **
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
-**
-** $Id: drm_dec.c,v 1.7 2006/05/07 18:09:00 menno Exp $
+** $Id: drm_dec.c 18142 2006-04-18 19:39:34Z rtognimp $
 **/
 
 #include <stdlib.h>
@@ -248,9 +243,17 @@
     { FRAC_CONST(0.929071574),  FRAC_CONST(0)           }
 };
 
-static const uint8_t sa_freq_scale[9] = 
+static const uint8_t sa_freq_scale[9][2] = 
 {
-    0, 1, 2, 3, 5, 7, 10, 13, 23
+    { 0, 0},  
+    { 1, 1},  
+    { 2, 2},  
+    { 3, 3},  
+    { 5, 5},  
+    { 7, 7},  
+    {10,10},  
+    {13,13},  
+    {46,23}
 };
 
 static const uint8_t pan_freq_scale[21] = 
@@ -287,9 +290,9 @@
     FRAC_CONST(0.48954165955695)
 };
 
-static const uint8_t delay_length[3] = 
+static const uint8_t delay_length[][2] = 
 {
-    3, 4, 5
+    { 1, 3 }, { 2, 4 }, { 3, 5 }
 };
 
 static const real_t delay_fraction[] = 
@@ -297,9 +300,15 @@
     FRAC_CONST(0.43), FRAC_CONST(0.75), FRAC_CONST(0.347)
 };
 
-static const real_t peak_decay = FRAC_CONST(0.76592833836465);
+static const real_t peak_decay[2] = 
+{
+    FRAC_CONST(0.58664621951003), FRAC_CONST(0.76592833836465)
+};
 
-static const real_t smooth_coeff = FRAC_CONST(0.25);
+static const real_t smooth_coeff[2] = 
+{
+    FRAC_CONST(0.6), FRAC_CONST(0.25)
+};
 
 /* Please note that these are the same tables as in plain PS */
 static const complex_t Q_Fract_allpass_Qmf[][3] = {
@@ -557,22 +566,25 @@
     {    
         if (ps->bs_sa_dt_flag && !ps->g_last_had_sa) 
         {        
-            /* wait until we get a DT frame */
-            ps->bs_enable_sa = 0;
-        } else if (ps->bs_sa_dt_flag) {
-            /* DT frame, we have a last frame, so we can decode */
+            for (band = 0; band < DRM_NUM_SA_BANDS; band++)
+            {   
+                ps->g_prev_sa_index[band] = 0;
+            }           
+        }       
+        if (ps->bs_sa_dt_flag)
+        {
             ps->g_sa_index[0] = sa_delta_clip(ps, ps->g_prev_sa_index[0]+ps->bs_sa_data[0]);            
+
         } else {
-            /* DF always decodable */
             ps->g_sa_index[0] = sa_delta_clip(ps,ps->bs_sa_data[0]);          
         }
         
         for (band = 1; band < DRM_NUM_SA_BANDS; band++)
         {   
-            if (ps->bs_sa_dt_flag && ps->g_last_had_sa)
+            if (ps->bs_sa_dt_flag)
             {
                 ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_prev_sa_index[band] + ps->bs_sa_data[band]);
-            } else if (!ps->bs_sa_dt_flag) {
+            } else {
                 ps->g_sa_index[band] = sa_delta_clip(ps, ps->g_sa_index[band-1] + ps->bs_sa_data[band]);                
             }
         }
@@ -606,19 +618,28 @@
     {
         if (ps->bs_pan_dt_flag && !ps->g_last_had_pan) 
         {
-            ps->bs_enable_pan = 0;
-        }  else if (ps->bs_pan_dt_flag) {   
-            ps->g_pan_index[0] = pan_delta_clip(ps,  ps->g_prev_pan_index[0]+ps->bs_pan_data[0]);
+/* The DRM PS spec doesn't say anything about this case. (deltacoded in time without a previous frame)
+   AAC PS spec you must tread previous frame as 0, so that's what we try. 
+*/
+            for (band = 0; band < DRM_NUM_PAN_BANDS; band++)
+            {   
+                ps->g_prev_pan_index[band] = 0;
+            }
+        } 
+
+        if (ps->bs_pan_dt_flag)
+        {   
+             ps->g_pan_index[0] = pan_delta_clip(ps,  ps->g_prev_pan_index[0]+ps->bs_pan_data[0]);
         } else {
-            ps->g_pan_index[0] = pan_delta_clip(ps, ps->bs_pan_data[0]);
+             ps->g_pan_index[0] = pan_delta_clip(ps, ps->bs_pan_data[0]);
         }
     
         for (band = 1; band < DRM_NUM_PAN_BANDS; band++)
         {   
-            if (ps->bs_pan_dt_flag && ps->g_last_had_pan)
+            if (ps->bs_pan_dt_flag)
             {
                 ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_prev_pan_index[band] + ps->bs_pan_data[band]);
-            } else if (!ps->bs_pan_dt_flag) {
+            } else {
                 ps->g_pan_index[band] = pan_delta_clip(ps, ps->g_pan_index[band-1] + ps->bs_pan_data[band]);
             }
         }
@@ -637,7 +658,7 @@
     }
 }
 
-static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64]) 
+static void drm_calc_sa_side_signal(drm_ps_info *ps, qmf_t X[38][64], uint8_t rateselect) 
 {      
     uint8_t s, b, k;
     complex_t qfrac, tmp0, tmp, in, R0;
@@ -652,7 +673,7 @@
     uint32_t in_re, in_im;
 #endif
 
-    for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++)
+    for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
     {
         /* set delay indices */    
         for (k = 0; k < NUM_OF_LINKS; k++)
@@ -680,16 +701,16 @@
             power = MUL_R(RE(in),RE(in)) + MUL_R(IM(in),IM(in));
 #endif
 
-            ps->peakdecay_fast[b] = MUL_F(ps->peakdecay_fast[b], peak_decay);
+            ps->peakdecay_fast[b] = MUL_F(ps->peakdecay_fast[b], peak_decay[rateselect]);
             if (ps->peakdecay_fast[b] < power)
                 ps->peakdecay_fast[b] = power;
 
             peakdiff = ps->prev_peakdiff[b];
-            peakdiff += MUL_F((ps->peakdecay_fast[b] - power - ps->prev_peakdiff[b]), smooth_coeff);
+            peakdiff += MUL_F((ps->peakdecay_fast[b] - power - ps->prev_peakdiff[b]), smooth_coeff[rateselect]);
             ps->prev_peakdiff[b] = peakdiff;
 
             nrg = ps->prev_nrg[b];
-            nrg += MUL_F((power - ps->prev_nrg[b]), smooth_coeff);
+            nrg += MUL_F((power - ps->prev_nrg[b]), smooth_coeff[rateselect]);
             ps->prev_nrg[b] = nrg;
 
             if (MUL_R(peakdiff, gamma) <= nrg) {
@@ -742,7 +763,7 @@
 
             for (k = 0; k < NUM_OF_LINKS; k++)
             {
-                if (++temp_delay_ser[k] >= delay_length[k])
+                if (++temp_delay_ser[k] >= delay_length[k][rateselect])
                     temp_delay_ser[k] = 0;
             }
         }       
@@ -752,7 +773,7 @@
         ps->delay_buf_index_ser[k] = temp_delay_ser[k];
 }
 
-static void drm_add_ambiance(drm_ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) 
+static void drm_add_ambiance(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[38][64], qmf_t X_right[38][64]) 
 {
     uint8_t s, b, ifreq, qclass;    
     real_t sa_map[MAX_SA_BAND], sa_dir_map[MAX_SA_BAND], k_sa_map[MAX_SA_BAND], k_sa_dir_map[MAX_SA_BAND];
@@ -762,7 +783,7 @@
     {
         /* Instead of dequantization and mapping, we use an inverse mapping
            to look up all the values we need */
-        for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++)
+        for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
         {
             const real_t inv_f_num_of_subsamples = FRAC_CONST(0.03333333333);
 
@@ -783,7 +804,7 @@
 
         for (s = 0; s < NUM_OF_SUBSAMPLES; s++)
         {
-            for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS]; b++)
+            for (b = 0; b < sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b++)
             {                
                 QMF_RE(X_right[s][b]) = MUL_F(QMF_RE(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_RE(ps->SA[s][b]), sa_map[b]);
                 QMF_IM(X_right[s][b]) = MUL_F(QMF_IM(X_left[s][b]), sa_dir_map[b]) - MUL_F(QMF_IM(ps->SA[s][b]), sa_map[b]);
@@ -793,7 +814,7 @@
                 sa_map[b]     += k_sa_map[b];
                 sa_dir_map[b] += k_sa_dir_map[b];
             }
-            for (b = sa_freq_scale[DRM_NUM_SA_BANDS]; b < NUM_OF_QMF_CHANNELS; b++)
+            for (b = sa_freq_scale[DRM_NUM_SA_BANDS][rateselect]; b < NUM_OF_QMF_CHANNELS; b++)
             {                
                 QMF_RE(X_right[s][b]) = QMF_RE(X_left[s][b]);
                 QMF_IM(X_right[s][b]) = QMF_IM(X_left[s][b]);
@@ -812,7 +833,7 @@
     }
 }
 
-static void drm_add_pan(drm_ps_info *ps, qmf_t X_left[38][64], qmf_t X_right[38][64]) 
+static void drm_add_pan(drm_ps_info *ps, uint8_t rateselect, qmf_t X_left[38][64], qmf_t X_right[38][64]) 
 {
     uint8_t s, b, qclass, ifreq;
     real_t tmp, coeff1, coeff2;
@@ -903,8 +924,10 @@
 }
 
 /* main DRM PS decoding function */
-uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, qmf_t X_left[38][64], qmf_t X_right[38][64])
-{       
+uint8_t drm_ps_decode(drm_ps_info *ps, uint8_t guess, uint32_t samplerate, qmf_t X_left[38][64], qmf_t X_right[38][64])
+{
+    uint8_t rateselect = (samplerate >= 24000);
+    
     if (ps == NULL) 
     {
         memcpy(X_right, X_left, sizeof(qmf_t)*30*64);
@@ -935,8 +958,8 @@
   
     ps->drm_ps_data_available = 0;
 
-    drm_calc_sa_side_signal(ps, X_left);
-    drm_add_ambiance(ps, X_left, X_right);
+    drm_calc_sa_side_signal(ps, X_left, rateselect);
+    drm_add_ambiance(ps, rateselect, X_left, X_right);
 
     if (ps->bs_enable_sa)
     {
@@ -950,7 +973,7 @@
     
     if (ps->bs_enable_pan)
     {
-        drm_add_pan(ps, X_left, X_right);
+        drm_add_pan(ps, rateselect, X_left, X_right);
     
         ps->g_last_had_pan = 1;