blob: 55b4483bc8ddf569e002d06af9d6ea430a5c2f67
1 | /* |
2 | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding |
3 | ** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com |
4 | ** |
5 | ** This program is free software; you can redistribute it and/or modify |
6 | ** it under the terms of the GNU General Public License as published by |
7 | ** the Free Software Foundation; either version 2 of the License, or |
8 | ** (at your option) any later version. |
9 | ** |
10 | ** This program is distributed in the hope that it will be useful, |
11 | ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | ** GNU General Public License for more details. |
14 | ** |
15 | ** You should have received a copy of the GNU General Public License |
16 | ** along with this program; if not, write to the Free Software |
17 | ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
18 | ** |
19 | ** Any non-GPL usage of this software or parts of this software is strictly |
20 | ** forbidden. |
21 | ** |
22 | ** The "appropriate copyright message" mentioned in section 2c of the GPLv2 |
23 | ** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com" |
24 | ** |
25 | ** Commercial non-GPL licensing of this software is possible. |
26 | ** For more info contact Nero AG through Mpeg4AAClicense@nero.com. |
27 | ** |
28 | ** $Id: drc.c,v 1.28 2007/11/01 12:33:30 menno Exp $ |
29 | **/ |
30 | #include <stdlib.h> |
31 | #include "common.h" |
32 | #include "structs.h" |
33 | |
34 | #include <string.h> |
35 | #include "syntax.h" |
36 | #include "drc.h" |
37 | |
38 | drc_info *drc_init(real_t cut, real_t boost) |
39 | { |
40 | drc_info *drc = (drc_info*)faad_malloc(sizeof(drc_info)); |
41 | memset(drc, 0, sizeof(drc_info)); |
42 | |
43 | drc->ctrl1 = cut; |
44 | drc->ctrl2 = boost; |
45 | |
46 | drc->num_bands = 1; |
47 | drc->band_top[0] = 1024 / 4 - 1; |
48 | drc->dyn_rng_sgn[0] = 1; |
49 | drc->dyn_rng_ctl[0] = 0; |
50 | |
51 | return drc; |
52 | } |
53 | |
54 | void drc_end(drc_info *drc) |
55 | { |
56 | if (drc) { |
57 | faad_free(drc); |
58 | } |
59 | } |
60 | |
61 | #ifdef FIXED_POINT |
62 | static real_t drc_pow2_table[] = { |
63 | COEF_CONST(0.5146511183), |
64 | COEF_CONST(0.5297315472), |
65 | COEF_CONST(0.5452538663), |
66 | COEF_CONST(0.5612310242), |
67 | COEF_CONST(0.5776763484), |
68 | COEF_CONST(0.5946035575), |
69 | COEF_CONST(0.6120267717), |
70 | COEF_CONST(0.6299605249), |
71 | COEF_CONST(0.6484197773), |
72 | COEF_CONST(0.6674199271), |
73 | COEF_CONST(0.6869768237), |
74 | COEF_CONST(0.7071067812), |
75 | COEF_CONST(0.7278265914), |
76 | COEF_CONST(0.7491535384), |
77 | COEF_CONST(0.7711054127), |
78 | COEF_CONST(0.7937005260), |
79 | COEF_CONST(0.8169577266), |
80 | COEF_CONST(0.8408964153), |
81 | COEF_CONST(0.8655365610), |
82 | COEF_CONST(0.8908987181), |
83 | COEF_CONST(0.9170040432), |
84 | COEF_CONST(0.9438743127), |
85 | COEF_CONST(0.9715319412), |
86 | COEF_CONST(1.0000000000), |
87 | COEF_CONST(1.0293022366), |
88 | COEF_CONST(1.0594630944), |
89 | COEF_CONST(1.0905077327), |
90 | COEF_CONST(1.1224620483), |
91 | COEF_CONST(1.1553526969), |
92 | COEF_CONST(1.1892071150), |
93 | COEF_CONST(1.2240535433), |
94 | COEF_CONST(1.2599210499), |
95 | COEF_CONST(1.2968395547), |
96 | COEF_CONST(1.3348398542), |
97 | COEF_CONST(1.3739536475), |
98 | COEF_CONST(1.4142135624), |
99 | COEF_CONST(1.4556531828), |
100 | COEF_CONST(1.4983070769), |
101 | COEF_CONST(1.5422108254), |
102 | COEF_CONST(1.5874010520), |
103 | COEF_CONST(1.6339154532), |
104 | COEF_CONST(1.6817928305), |
105 | COEF_CONST(1.7310731220), |
106 | COEF_CONST(1.7817974363), |
107 | COEF_CONST(1.8340080864), |
108 | COEF_CONST(1.8877486254), |
109 | COEF_CONST(1.9430638823) |
110 | }; |
111 | #endif |
112 | |
113 | void drc_decode(drc_info *drc, real_t *spec) |
114 | { |
115 | uint16_t i, bd, top; |
116 | #ifdef FIXED_POINT |
117 | int32_t exp, frac; |
118 | #else |
119 | real_t factor, exp; |
120 | #endif |
121 | uint16_t bottom = 0; |
122 | |
123 | if (drc->num_bands == 1) { |
124 | drc->band_top[0] = 1024 / 4 - 1; |
125 | } |
126 | |
127 | for (bd = 0; bd < drc->num_bands; bd++) { |
128 | top = 4 * (drc->band_top[bd] + 1); |
129 | |
130 | #ifndef FIXED_POINT |
131 | /* Decode DRC gain factor */ |
132 | if (drc->dyn_rng_sgn[bd]) { /* compress */ |
133 | exp = (-drc->ctrl1 * drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) / REAL_CONST(24.0); |
134 | } else { /* boost */ |
135 | exp = (drc->ctrl2 * drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) / REAL_CONST(24.0); |
136 | } |
137 | factor = (real_t)pow(2.0, exp); |
138 | |
139 | /* Apply gain factor */ |
140 | for (i = bottom; i < top; i++) { |
141 | spec[i] *= factor; |
142 | } |
143 | #else |
144 | /* Decode DRC gain factor */ |
145 | if (drc->dyn_rng_sgn[bd]) { /* compress */ |
146 | exp = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) / 24; |
147 | frac = -1 * (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; |
148 | } else { /* boost */ |
149 | exp = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) / 24; |
150 | frac = (drc->dyn_rng_ctl[bd] - (DRC_REF_LEVEL - drc->prog_ref_level)) % 24; |
151 | } |
152 | |
153 | /* Apply gain factor */ |
154 | if (exp < 0) { |
155 | for (i = bottom; i < top; i++) { |
156 | spec[i] >>= -exp; |
157 | if (frac) { |
158 | spec[i] = MUL_R(spec[i], drc_pow2_table[frac + 23]); |
159 | } |
160 | } |
161 | } else { |
162 | for (i = bottom; i < top; i++) { |
163 | spec[i] <<= exp; |
164 | if (frac) { |
165 | spec[i] = MUL_R(spec[i], drc_pow2_table[frac + 23]); |
166 | } |
167 | } |
168 | } |
169 | #endif |
170 | |
171 | bottom = top; |
172 | } |
173 | } |
174 |