drc.c

00001 /*
00002 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
00003 ** Copyright (C) 2003-2005 M. Bakker, Ahead Software AG, http://www.nero.com
00004 **  
00005 ** This program is free software; you can redistribute it and/or modify
00006 ** it under the terms of the GNU General Public License as published by
00007 ** the Free Software Foundation; either version 2 of the License, or
00008 ** (at your option) any later version.
00009 ** 
00010 ** This program is distributed in the hope that it will be useful,
00011 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 ** GNU General Public License for more details.
00014 ** 
00015 ** You should have received a copy of the GNU General Public License
00016 ** along with this program; if not, write to the Free Software 
00017 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00018 **
00019 ** Any non-GPL usage of this software or parts of this software is strictly
00020 ** forbidden.
00021 **
00022 ** Software using this code must display the following message visibly in the
00023 ** software:
00024 ** "FAAD2 AAC/HE-AAC/HE-AACv2/DRM decoder (c) Ahead Software, www.nero.com"
00025 ** in, for example, the about-box or help/startup screen.
00026 **
00027 ** Commercial non-GPL licensing of this software is possible.
00028 ** For more info contact Ahead Software through [email protected].
00029 **
00030 ** $Id: drc.c,v 1.2 2005/11/01 21:41:43 gabest Exp $
00031 **/
00032 
00033 #include "common.h"
00034 #include "structs.h"
00035 
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include "syntax.h"
00039 #include "drc.h"
00040 
00041 drc_info *drc_init(real_t cut, real_t boost)
00042 {
00043     drc_info *drc = (drc_info*)faad_malloc(sizeof(drc_info));
00044     memset(drc, 0, sizeof(drc_info));
00045 
00046     drc->ctrl1 = cut;
00047     drc->ctrl2 = boost;
00048 
00049     drc->num_bands = 1;
00050     drc->band_top[0] = 1024/4 - 1;
00051     drc->dyn_rng_sgn[0] = 1;
00052     drc->dyn_rng_ctl[0] = 0;
00053 
00054     return drc;
00055 }
00056 
00057 void drc_end(drc_info *drc)
00058 {
00059     if (drc) faad_free(drc);
00060 }
00061 
00062 #ifdef FIXED_POINT
00063 static real_t drc_pow2_table[] =
00064 {
00065     COEF_CONST(0.5146511183),
00066     COEF_CONST(0.5297315472),
00067     COEF_CONST(0.5452538663),
00068     COEF_CONST(0.5612310242),
00069     COEF_CONST(0.5776763484),
00070     COEF_CONST(0.5946035575),
00071     COEF_CONST(0.6120267717),
00072     COEF_CONST(0.6299605249),
00073     COEF_CONST(0.6484197773),
00074     COEF_CONST(0.6674199271),
00075     COEF_CONST(0.6869768237),
00076     COEF_CONST(0.7071067812),
00077     COEF_CONST(0.7278265914),
00078     COEF_CONST(0.7491535384),
00079     COEF_CONST(0.7711054127),
00080     COEF_CONST(0.7937005260),
00081     COEF_CONST(0.8169577266),
00082     COEF_CONST(0.8408964153),
00083     COEF_CONST(0.8655365610),
00084     COEF_CONST(0.8908987181),
00085     COEF_CONST(0.9170040432),
00086     COEF_CONST(0.9438743127),
00087     COEF_CONST(0.9715319412),
00088     COEF_CONST(1.0000000000),
00089     COEF_CONST(1.0293022366),
00090     COEF_CONST(1.0594630944),
00091     COEF_CONST(1.0905077327),
00092     COEF_CONST(1.1224620483),
00093     COEF_CONST(1.1553526969),
00094     COEF_CONST(1.1892071150),
00095     COEF_CONST(1.2240535433),
00096     COEF_CONST(1.2599210499),
00097     COEF_CONST(1.2968395547),
00098     COEF_CONST(1.3348398542),
00099     COEF_CONST(1.3739536475),
00100     COEF_CONST(1.4142135624),
00101     COEF_CONST(1.4556531828),
00102     COEF_CONST(1.4983070769),
00103     COEF_CONST(1.5422108254),
00104     COEF_CONST(1.5874010520),
00105     COEF_CONST(1.6339154532),
00106     COEF_CONST(1.6817928305),
00107     COEF_CONST(1.7310731220),
00108     COEF_CONST(1.7817974363),
00109     COEF_CONST(1.8340080864),
00110     COEF_CONST(1.8877486254),
00111     COEF_CONST(1.9430638823)
00112 };
00113 #endif
00114 
00115 void drc_decode(drc_info *drc, real_t *spec)
00116 {
00117     uint16_t i, bd, top;
00118 #ifdef FIXED_POINT
00119     int32_t exp, frac;
00120 #else
00121     real_t factor, exp;
00122 #endif
00123     uint16_t bottom = 0;
00124 
00125     if (drc->num_bands == 1)
00126         drc->band_top[0] = 1024/4 - 1;
00127 
00128     for (bd = 0; bd < drc->num_bands; bd++)
00129     {
00130         top = 4 * (drc->band_top[bd] + 1);
00131 
00132 #ifndef FIXED_POINT
00133         /* Decode DRC gain factor */
00134         if (drc->dyn_rng_sgn[bd])  /* compress */
00135             exp = -drc->ctrl1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0);
00136         else /* boost */
00137             exp = drc->ctrl2 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/REAL_CONST(24.0);
00138         factor = (real_t)pow(2.0, exp);
00139 
00140         /* Apply gain factor */
00141         for (i = bottom; i < top; i++)
00142             spec[i] *= factor;
00143 #else
00144         /* Decode DRC gain factor */
00145         if (drc->dyn_rng_sgn[bd])  /* compress */
00146         {
00147             exp = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24;
00148             frac = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24;
00149         } else { /* boost */
00150             exp = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level))/ 24;
00151             frac = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24;
00152         }
00153 
00154         /* Apply gain factor */
00155         if (exp < 0)
00156         {
00157             for (i = bottom; i < top; i++)
00158             {
00159                 spec[i] >>= -exp;
00160                 if (frac)
00161                     spec[i] = MUL_R(spec[i],drc_pow2_table[frac+23]);
00162             }
00163         } else {
00164             for (i = bottom; i < top; i++)
00165             {
00166                 spec[i] <<= exp;
00167                 if (frac)
00168                     spec[i] = MUL_R(spec[i],drc_pow2_table[frac+23]);
00169             }
00170         }
00171 #endif
00172 
00173         bottom = top;
00174     }
00175 }

Generated on Tue Dec 13 14:47:30 2005 for guliverkli by  doxygen 1.4.5