- Main Page
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

# 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 Mpeg4AAClicense@nero.com.
    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 }