diff options
Diffstat (limited to 'apps/codecs/libfaad/sbr_hfadj.c')
-rw-r--r-- | apps/codecs/libfaad/sbr_hfadj.c | 1720 |
1 files changed, 1720 insertions, 0 deletions
diff --git a/apps/codecs/libfaad/sbr_hfadj.c b/apps/codecs/libfaad/sbr_hfadj.c new file mode 100644 index 0000000000..17d63f41c2 --- /dev/null +++ b/apps/codecs/libfaad/sbr_hfadj.c | |||
@@ -0,0 +1,1720 @@ | |||
1 | /* | ||
2 | ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | ||
3 | ** Copyright (C) 2003-2004 M. Bakker, Ahead Software 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 | ** Commercial non-GPL licensing of this software is possible. | ||
23 | ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com. | ||
24 | ** | ||
25 | ** $Id$ | ||
26 | **/ | ||
27 | |||
28 | /* High Frequency adjustment */ | ||
29 | |||
30 | #include "common.h" | ||
31 | #include "structs.h" | ||
32 | |||
33 | #ifdef SBR_DEC | ||
34 | |||
35 | #include "sbr_syntax.h" | ||
36 | #include "sbr_hfadj.h" | ||
37 | |||
38 | #include "sbr_noise.h" | ||
39 | |||
40 | |||
41 | /* static function declarations */ | ||
42 | static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, | ||
43 | qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); | ||
44 | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch); | ||
45 | #ifdef SBR_LOW_POWER | ||
46 | static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); | ||
47 | static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); | ||
48 | #endif | ||
49 | static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); | ||
50 | |||
51 | |||
52 | void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64] | ||
53 | #ifdef SBR_LOW_POWER | ||
54 | ,real_t *deg /* aliasing degree */ | ||
55 | #endif | ||
56 | ,uint8_t ch) | ||
57 | { | ||
58 | ALIGN sbr_hfadj_info adj = {{{0}}}; | ||
59 | |||
60 | if (sbr->bs_frame_class[ch] == FIXFIX) | ||
61 | { | ||
62 | sbr->l_A[ch] = -1; | ||
63 | } else if (sbr->bs_frame_class[ch] == VARFIX) { | ||
64 | if (sbr->bs_pointer[ch] > 1) | ||
65 | sbr->l_A[ch] = -1; | ||
66 | else | ||
67 | sbr->l_A[ch] = sbr->bs_pointer[ch] - 1; | ||
68 | } else { | ||
69 | if (sbr->bs_pointer[ch] == 0) | ||
70 | sbr->l_A[ch] = -1; | ||
71 | else | ||
72 | sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; | ||
73 | } | ||
74 | |||
75 | estimate_current_envelope(sbr, &adj, Xsbr, ch); | ||
76 | |||
77 | calculate_gain(sbr, &adj, ch); | ||
78 | |||
79 | #ifdef SBR_LOW_POWER | ||
80 | calc_gain_groups(sbr, &adj, deg, ch); | ||
81 | aliasing_reduction(sbr, &adj, deg, ch); | ||
82 | #endif | ||
83 | |||
84 | hf_assembly(sbr, &adj, Xsbr, ch); | ||
85 | } | ||
86 | |||
87 | static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band) | ||
88 | { | ||
89 | if (sbr->f[ch][l] == HI_RES) | ||
90 | { | ||
91 | /* in case of using f_table_high we just have 1 to 1 mapping | ||
92 | * from bs_add_harmonic[l][k] | ||
93 | */ | ||
94 | if ((l >= sbr->l_A[ch]) || | ||
95 | (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch])) | ||
96 | { | ||
97 | return sbr->bs_add_harmonic[ch][current_band]; | ||
98 | } | ||
99 | } else { | ||
100 | uint8_t b, lb, ub; | ||
101 | |||
102 | /* in case of f_table_low we check if any of the HI_RES bands | ||
103 | * within this LO_RES band has bs_add_harmonic[l][k] turned on | ||
104 | * (note that borders in the LO_RES table are also present in | ||
105 | * the HI_RES table) | ||
106 | */ | ||
107 | |||
108 | /* find first HI_RES band in current LO_RES band */ | ||
109 | lb = 2*current_band - ((sbr->N_high & 1) ? 1 : 0); | ||
110 | /* find first HI_RES band in next LO_RES band */ | ||
111 | ub = 2*(current_band+1) - ((sbr->N_high & 1) ? 1 : 0); | ||
112 | |||
113 | /* check all HI_RES bands in current LO_RES band for sinusoid */ | ||
114 | for (b = lb; b < ub; b++) | ||
115 | { | ||
116 | if ((l >= sbr->l_A[ch]) || | ||
117 | (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch])) | ||
118 | { | ||
119 | if (sbr->bs_add_harmonic[ch][b] == 1) | ||
120 | return 1; | ||
121 | } | ||
122 | } | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, | ||
129 | qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) | ||
130 | { | ||
131 | uint8_t m, l, j, k, k_l, k_h, p; | ||
132 | real_t nrg, div; | ||
133 | |||
134 | if (sbr->bs_interpol_freq == 1) | ||
135 | { | ||
136 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
137 | { | ||
138 | uint8_t i, l_i, u_i; | ||
139 | |||
140 | l_i = sbr->t_E[ch][l]; | ||
141 | u_i = sbr->t_E[ch][l+1]; | ||
142 | |||
143 | div = (real_t)(u_i - l_i); | ||
144 | |||
145 | for (m = 0; m < sbr->M; m++) | ||
146 | { | ||
147 | nrg = 0; | ||
148 | |||
149 | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) | ||
150 | { | ||
151 | #ifdef FIXED_POINT | ||
152 | #ifdef SBR_LOW_POWER | ||
153 | nrg += ((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS); | ||
154 | #else | ||
155 | nrg += ((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS) + | ||
156 | ((QMF_IM(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_IM(Xsbr[i][m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS); | ||
157 | #endif | ||
158 | #else | ||
159 | nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx])) | ||
160 | #ifndef SBR_LOW_POWER | ||
161 | + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx])) | ||
162 | #endif | ||
163 | ; | ||
164 | #endif | ||
165 | } | ||
166 | |||
167 | sbr->E_curr[ch][m][l] = nrg / div; | ||
168 | #ifdef SBR_LOW_POWER | ||
169 | #ifdef FIXED_POINT | ||
170 | sbr->E_curr[ch][m][l] <<= 1; | ||
171 | #else | ||
172 | sbr->E_curr[ch][m][l] *= 2; | ||
173 | #endif | ||
174 | #endif | ||
175 | } | ||
176 | } | ||
177 | } else { | ||
178 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
179 | { | ||
180 | for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) | ||
181 | { | ||
182 | k_l = sbr->f_table_res[sbr->f[ch][l]][p]; | ||
183 | k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; | ||
184 | |||
185 | for (k = k_l; k < k_h; k++) | ||
186 | { | ||
187 | uint8_t i, l_i, u_i; | ||
188 | nrg = 0; | ||
189 | |||
190 | l_i = sbr->t_E[ch][l]; | ||
191 | u_i = sbr->t_E[ch][l+1]; | ||
192 | |||
193 | div = (real_t)((u_i - l_i)*(k_h - k_l)); | ||
194 | |||
195 | for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) | ||
196 | { | ||
197 | for (j = k_l; j < k_h; j++) | ||
198 | { | ||
199 | #ifdef FIXED_POINT | ||
200 | #ifdef SBR_LOW_POWER | ||
201 | nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS); | ||
202 | #else | ||
203 | nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS) + | ||
204 | ((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS); | ||
205 | #endif | ||
206 | #else | ||
207 | nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j])) | ||
208 | #ifndef SBR_LOW_POWER | ||
209 | + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j])) | ||
210 | #endif | ||
211 | ; | ||
212 | #endif | ||
213 | } | ||
214 | } | ||
215 | |||
216 | sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; | ||
217 | #ifdef SBR_LOW_POWER | ||
218 | #ifdef FIXED_POINT | ||
219 | sbr->E_curr[ch][k - sbr->kx][l] <<= 1; | ||
220 | #else | ||
221 | sbr->E_curr[ch][k - sbr->kx][l] *= 2; | ||
222 | #endif | ||
223 | #endif | ||
224 | } | ||
225 | } | ||
226 | } | ||
227 | } | ||
228 | } | ||
229 | |||
230 | #ifdef FIXED_POINT | ||
231 | #define EPS (1) /* smallest number available in fixed point */ | ||
232 | #else | ||
233 | #define EPS (1e-12) | ||
234 | #endif | ||
235 | |||
236 | |||
237 | |||
238 | #ifdef FIXED_POINT | ||
239 | |||
240 | /* log2 values of [0..63] */ | ||
241 | static const real_t log2_int_tab[] = { | ||
242 | LOG2_MIN_INF, REAL_CONST(0.000000000000000), REAL_CONST(1.000000000000000), REAL_CONST(1.584962500721156), | ||
243 | REAL_CONST(2.000000000000000), REAL_CONST(2.321928094887362), REAL_CONST(2.584962500721156), REAL_CONST(2.807354922057604), | ||
244 | REAL_CONST(3.000000000000000), REAL_CONST(3.169925001442313), REAL_CONST(3.321928094887363), REAL_CONST(3.459431618637297), | ||
245 | REAL_CONST(3.584962500721156), REAL_CONST(3.700439718141092), REAL_CONST(3.807354922057604), REAL_CONST(3.906890595608519), | ||
246 | REAL_CONST(4.000000000000000), REAL_CONST(4.087462841250339), REAL_CONST(4.169925001442312), REAL_CONST(4.247927513443585), | ||
247 | REAL_CONST(4.321928094887362), REAL_CONST(4.392317422778761), REAL_CONST(4.459431618637297), REAL_CONST(4.523561956057013), | ||
248 | REAL_CONST(4.584962500721156), REAL_CONST(4.643856189774724), REAL_CONST(4.700439718141093), REAL_CONST(4.754887502163468), | ||
249 | REAL_CONST(4.807354922057604), REAL_CONST(4.857980995127572), REAL_CONST(4.906890595608519), REAL_CONST(4.954196310386875), | ||
250 | REAL_CONST(5.000000000000000), REAL_CONST(5.044394119358453), REAL_CONST(5.087462841250340), REAL_CONST(5.129283016944966), | ||
251 | REAL_CONST(5.169925001442312), REAL_CONST(5.209453365628949), REAL_CONST(5.247927513443585), REAL_CONST(5.285402218862248), | ||
252 | REAL_CONST(5.321928094887363), REAL_CONST(5.357552004618084), REAL_CONST(5.392317422778761), REAL_CONST(5.426264754702098), | ||
253 | REAL_CONST(5.459431618637297), REAL_CONST(5.491853096329675), REAL_CONST(5.523561956057013), REAL_CONST(5.554588851677637), | ||
254 | REAL_CONST(5.584962500721156), REAL_CONST(5.614709844115208), REAL_CONST(5.643856189774724), REAL_CONST(5.672425341971495), | ||
255 | REAL_CONST(5.700439718141093), REAL_CONST(5.727920454563200), REAL_CONST(5.754887502163469), REAL_CONST(5.781359713524660), | ||
256 | REAL_CONST(5.807354922057605), REAL_CONST(5.832890014164742), REAL_CONST(5.857980995127572), REAL_CONST(5.882643049361842), | ||
257 | REAL_CONST(5.906890595608518), REAL_CONST(5.930737337562887), REAL_CONST(5.954196310386876), REAL_CONST(5.977279923499916) | ||
258 | }; | ||
259 | |||
260 | static const real_t pan_log2_tab[] = { | ||
261 | REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), | ||
262 | REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054), | ||
263 | REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), | ||
264 | REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667) | ||
265 | }; | ||
266 | |||
267 | static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) | ||
268 | { | ||
269 | /* check for coupled energy/noise data */ | ||
270 | if (sbr->bs_coupling == 1) | ||
271 | { | ||
272 | uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1; | ||
273 | uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1; | ||
274 | real_t tmp = (7 << REAL_BITS) + (sbr->E[0][k][l] << (REAL_BITS-amp0)); | ||
275 | real_t pan; | ||
276 | |||
277 | /* E[1] should always be even so shifting is OK */ | ||
278 | uint8_t E = sbr->E[1][k][l] >> amp1; | ||
279 | |||
280 | if (ch == 0) | ||
281 | { | ||
282 | if (E > 12) | ||
283 | { | ||
284 | /* negative */ | ||
285 | pan = pan_log2_tab[-12 + E]; | ||
286 | } else { | ||
287 | /* positive */ | ||
288 | pan = pan_log2_tab[12 - E] + ((12 - E)<<REAL_BITS); | ||
289 | } | ||
290 | } else { | ||
291 | if (E < 12) | ||
292 | { | ||
293 | /* negative */ | ||
294 | pan = pan_log2_tab[-E + 12]; | ||
295 | } else { | ||
296 | /* positive */ | ||
297 | pan = pan_log2_tab[E - 12] + ((E - 12)<<REAL_BITS); | ||
298 | } | ||
299 | } | ||
300 | |||
301 | /* tmp / pan in log2 */ | ||
302 | return tmp - pan; | ||
303 | } else { | ||
304 | uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1; | ||
305 | |||
306 | return (6 << REAL_BITS) + (sbr->E[ch][k][l] << (REAL_BITS-amp)); | ||
307 | } | ||
308 | } | ||
309 | |||
310 | static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) | ||
311 | { | ||
312 | /* check for coupled energy/noise data */ | ||
313 | if (sbr->bs_coupling == 1) | ||
314 | { | ||
315 | real_t tmp = (7 << REAL_BITS) - (sbr->Q[0][k][l] << REAL_BITS); | ||
316 | real_t pan; | ||
317 | |||
318 | uint8_t Q = sbr->Q[1][k][l]; | ||
319 | |||
320 | if (ch == 0) | ||
321 | { | ||
322 | if (Q > 12) | ||
323 | { | ||
324 | /* negative */ | ||
325 | pan = pan_log2_tab[-12 + Q]; | ||
326 | } else { | ||
327 | /* positive */ | ||
328 | pan = pan_log2_tab[12 - Q] + ((12 - Q)<<REAL_BITS); | ||
329 | } | ||
330 | } else { | ||
331 | if (Q < 12) | ||
332 | { | ||
333 | /* negative */ | ||
334 | pan = pan_log2_tab[-Q + 12]; | ||
335 | } else { | ||
336 | /* positive */ | ||
337 | pan = pan_log2_tab[Q - 12] + ((Q - 12)<<REAL_BITS); | ||
338 | } | ||
339 | } | ||
340 | |||
341 | /* tmp / pan in log2 */ | ||
342 | return tmp - pan; | ||
343 | } else { | ||
344 | return (6 << REAL_BITS) - (sbr->Q[ch][k][l] << REAL_BITS); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | static const real_t log_Qplus1_pan[31][13] = { | ||
349 | { REAL_CONST(0.044383447617292), REAL_CONST(0.169768601655960), REAL_CONST(0.583090126514435), REAL_CONST(1.570089221000671), REAL_CONST(3.092446088790894), REAL_CONST(4.733354568481445), REAL_CONST(6.022367954254150), REAL_CONST(6.692092418670654), REAL_CONST(6.924463272094727), REAL_CONST(6.989034175872803), REAL_CONST(7.005646705627441), REAL_CONST(7.009829998016357), REAL_CONST(7.010877609252930) }, | ||
350 | { REAL_CONST(0.022362394258380), REAL_CONST(0.087379962205887), REAL_CONST(0.320804953575134), REAL_CONST(0.988859415054321), REAL_CONST(2.252387046813965), REAL_CONST(3.786596298217773), REAL_CONST(5.044394016265869), REAL_CONST(5.705977916717529), REAL_CONST(5.936291694641113), REAL_CONST(6.000346660614014), REAL_CONST(6.016829967498779), REAL_CONST(6.020981311798096), REAL_CONST(6.022020816802979) }, | ||
351 | { REAL_CONST(0.011224525049329), REAL_CONST(0.044351425021887), REAL_CONST(0.169301137328148), REAL_CONST(0.577544987201691), REAL_CONST(1.527246952056885), REAL_CONST(2.887525320053101), REAL_CONST(4.087462902069092), REAL_CONST(4.733354568481445), REAL_CONST(4.959661006927490), REAL_CONST(5.022709369659424), REAL_CONST(5.038940429687500), REAL_CONST(5.043028831481934), REAL_CONST(5.044052600860596) }, | ||
352 | { REAL_CONST(0.005623178556561), REAL_CONST(0.022346137091517), REAL_CONST(0.087132595479488), REAL_CONST(0.317482173442841), REAL_CONST(0.956931233406067), REAL_CONST(2.070389270782471), REAL_CONST(3.169924974441528), REAL_CONST(3.786596298217773), REAL_CONST(4.005294322967529), REAL_CONST(4.066420555114746), REAL_CONST(4.082170009613037), REAL_CONST(4.086137294769287), REAL_CONST(4.087131500244141) }, | ||
353 | { REAL_CONST(0.002814328996465), REAL_CONST(0.011216334067285), REAL_CONST(0.044224001467228), REAL_CONST(0.167456731200218), REAL_CONST(0.556393325328827), REAL_CONST(1.378511548042297), REAL_CONST(2.321928024291992), REAL_CONST(2.887525320053101), REAL_CONST(3.092446088790894), REAL_CONST(3.150059700012207), REAL_CONST(3.164926528930664), REAL_CONST(3.168673276901245), REAL_CONST(3.169611930847168) }, | ||
354 | { REAL_CONST(0.001407850766554), REAL_CONST(0.005619067233056), REAL_CONST(0.022281449288130), REAL_CONST(0.086156636476517), REAL_CONST(0.304854571819305), REAL_CONST(0.847996890544891), REAL_CONST(1.584962487220764), REAL_CONST(2.070389270782471), REAL_CONST(2.252387046813965), REAL_CONST(2.304061651229858), REAL_CONST(2.317430257797241), REAL_CONST(2.320801734924316), REAL_CONST(2.321646213531494) }, | ||
355 | { REAL_CONST(0.000704097095877), REAL_CONST(0.002812269143760), REAL_CONST(0.011183738708496), REAL_CONST(0.043721374124289), REAL_CONST(0.160464659333229), REAL_CONST(0.485426813364029), REAL_CONST(1.000000000000000), REAL_CONST(1.378511548042297), REAL_CONST(1.527246952056885), REAL_CONST(1.570089221000671), REAL_CONST(1.581215262413025), REAL_CONST(1.584023833274841), REAL_CONST(1.584727644920349) }, | ||
356 | { REAL_CONST(0.000352177477907), REAL_CONST(0.001406819908880), REAL_CONST(0.005602621007711), REAL_CONST(0.022026389837265), REAL_CONST(0.082462236285210), REAL_CONST(0.263034462928772), REAL_CONST(0.584962487220764), REAL_CONST(0.847996890544891), REAL_CONST(0.956931233406067), REAL_CONST(0.988859415054321), REAL_CONST(0.997190535068512), REAL_CONST(0.999296069145203), REAL_CONST(0.999823868274689) }, | ||
357 | { REAL_CONST(0.000176099492819), REAL_CONST(0.000703581434209), REAL_CONST(0.002804030198604), REAL_CONST(0.011055230163038), REAL_CONST(0.041820213198662), REAL_CONST(0.137503549456596), REAL_CONST(0.321928083896637), REAL_CONST(0.485426813364029), REAL_CONST(0.556393325328827), REAL_CONST(0.577544987201691), REAL_CONST(0.583090126514435), REAL_CONST(0.584493279457092), REAL_CONST(0.584845066070557) }, | ||
358 | { REAL_CONST(0.000088052431238), REAL_CONST(0.000351833587047), REAL_CONST(0.001402696361765), REAL_CONST(0.005538204684854), REAL_CONST(0.021061634644866), REAL_CONST(0.070389263331890), REAL_CONST(0.169925004243851), REAL_CONST(0.263034462928772), REAL_CONST(0.304854571819305), REAL_CONST(0.317482173442841), REAL_CONST(0.320804953575134), REAL_CONST(0.321646571159363), REAL_CONST(0.321857661008835) }, | ||
359 | { REAL_CONST(0.000044026888645), REAL_CONST(0.000175927518285), REAL_CONST(0.000701518612914), REAL_CONST(0.002771759871393), REAL_CONST(0.010569252073765), REAL_CONST(0.035623874515295), REAL_CONST(0.087462842464447), REAL_CONST(0.137503549456596), REAL_CONST(0.160464659333229), REAL_CONST(0.167456731200218), REAL_CONST(0.169301137328148), REAL_CONST(0.169768601655960), REAL_CONST(0.169885858893394) }, | ||
360 | { REAL_CONST(0.000022013611670), REAL_CONST(0.000088052431238), REAL_CONST(0.000350801943569), REAL_CONST(0.001386545598507), REAL_CONST(0.005294219125062), REAL_CONST(0.017921976745129), REAL_CONST(0.044394120573997), REAL_CONST(0.070389263331890), REAL_CONST(0.082462236285210), REAL_CONST(0.086156636476517), REAL_CONST(0.087132595479488), REAL_CONST(0.087379962205887), REAL_CONST(0.087442122399807) }, | ||
361 | { REAL_CONST(0.000011006847672), REAL_CONST(0.000044026888645), REAL_CONST(0.000175411638338), REAL_CONST(0.000693439331371), REAL_CONST(0.002649537986144), REAL_CONST(0.008988817222416), REAL_CONST(0.022367812693119), REAL_CONST(0.035623874515295), REAL_CONST(0.041820213198662), REAL_CONST(0.043721374124289), REAL_CONST(0.044224001467228), REAL_CONST(0.044351425021887), REAL_CONST(0.044383447617292) }, | ||
362 | { REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000087708482170), REAL_CONST(0.000346675369656), REAL_CONST(0.001325377263129), REAL_CONST(0.004501323681325), REAL_CONST(0.011227255687118), REAL_CONST(0.017921976745129), REAL_CONST(0.021061634644866), REAL_CONST(0.022026389837265), REAL_CONST(0.022281449288130), REAL_CONST(0.022346137091517), REAL_CONST(0.022362394258380) }, | ||
363 | { REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043854910473), REAL_CONST(0.000173348103999), REAL_CONST(0.000662840844598), REAL_CONST(0.002252417383716), REAL_CONST(0.005624548997730), REAL_CONST(0.008988817222416), REAL_CONST(0.010569252073765), REAL_CONST(0.011055230163038), REAL_CONST(0.011183738708496), REAL_CONST(0.011216334067285), REAL_CONST(0.011224525049329) }, | ||
364 | { REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000086676649516), REAL_CONST(0.000331544462824), REAL_CONST(0.001126734190620), REAL_CONST(0.002815015614033), REAL_CONST(0.004501323681325), REAL_CONST(0.005294219125062), REAL_CONST(0.005538204684854), REAL_CONST(0.005602621007711), REAL_CONST(0.005619067233056), REAL_CONST(0.005623178556561) }, | ||
365 | { REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043338975956), REAL_CONST(0.000165781748365), REAL_CONST(0.000563477107789), REAL_CONST(0.001408194424585), REAL_CONST(0.002252417383716), REAL_CONST(0.002649537986144), REAL_CONST(0.002771759871393), REAL_CONST(0.002804030198604), REAL_CONST(0.002812269143760), REAL_CONST(0.002814328996465) }, | ||
366 | { REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000021669651687), REAL_CONST(0.000082893253420), REAL_CONST(0.000281680084299), REAL_CONST(0.000704268983100), REAL_CONST(0.001126734190620), REAL_CONST(0.001325377263129), REAL_CONST(0.001386545598507), REAL_CONST(0.001402696361765), REAL_CONST(0.001406819908880), REAL_CONST(0.001407850766554) }, | ||
367 | { REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010834866771), REAL_CONST(0.000041447223339), REAL_CONST(0.000140846910654), REAL_CONST(0.000352177477907), REAL_CONST(0.000563477107789), REAL_CONST(0.000662840844598), REAL_CONST(0.000693439331371), REAL_CONST(0.000701518612914), REAL_CONST(0.000703581434209), REAL_CONST(0.000704097095877) }, | ||
368 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000020637769921), REAL_CONST(0.000070511166996), REAL_CONST(0.000176099492819), REAL_CONST(0.000281680084299), REAL_CONST(0.000331544462824), REAL_CONST(0.000346675369656), REAL_CONST(0.000350801943569), REAL_CONST(0.000351833587047), REAL_CONST(0.000352177477907) }, | ||
369 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010318922250), REAL_CONST(0.000035256012779), REAL_CONST(0.000088052431238), REAL_CONST(0.000140846910654), REAL_CONST(0.000165781748365), REAL_CONST(0.000173348103999), REAL_CONST(0.000175411638338), REAL_CONST(0.000175927518285), REAL_CONST(0.000176099492819) }, | ||
370 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005159470220), REAL_CONST(0.000017542124624), REAL_CONST(0.000044026888645), REAL_CONST(0.000070511166996), REAL_CONST(0.000082893253420), REAL_CONST(0.000086676649516), REAL_CONST(0.000087708482170), REAL_CONST(0.000088052431238), REAL_CONST(0.000088052431238) }, | ||
371 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002579737384), REAL_CONST(0.000008771088687), REAL_CONST(0.000022013611670), REAL_CONST(0.000035256012779), REAL_CONST(0.000041447223339), REAL_CONST(0.000043338975956), REAL_CONST(0.000043854910473), REAL_CONST(0.000044026888645), REAL_CONST(0.000044026888645) }, | ||
372 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000004471542070), REAL_CONST(0.000011006847672), REAL_CONST(0.000017542124624), REAL_CONST(0.000020637769921), REAL_CONST(0.000021669651687), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670) }, | ||
373 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002235772627), REAL_CONST(0.000005503434295), REAL_CONST(0.000008771088687), REAL_CONST(0.000010318922250), REAL_CONST(0.000010834866771), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672) }, | ||
374 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001031895522), REAL_CONST(0.000002751719876), REAL_CONST(0.000004471542070), REAL_CONST(0.000005159470220), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295) }, | ||
375 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000515947875), REAL_CONST(0.000001375860506), REAL_CONST(0.000002235772627), REAL_CONST(0.000002579737384), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876) }, | ||
376 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000000687930424), REAL_CONST(0.000001031895522), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506) }, | ||
377 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000515947875), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424) }, | ||
378 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269) }, | ||
379 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634) } | ||
380 | }; | ||
381 | |||
382 | static const real_t log_Qplus1[31] = { | ||
383 | REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339), | ||
384 | REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156), | ||
385 | REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), | ||
386 | REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), | ||
387 | REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), | ||
388 | REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), | ||
389 | REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), | ||
390 | REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667), | ||
391 | REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551), | ||
392 | REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641), | ||
393 | REAL_CONST(0.000000000000000) | ||
394 | }; | ||
395 | |||
396 | static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) | ||
397 | { | ||
398 | /* check for coupled energy/noise data */ | ||
399 | if (sbr->bs_coupling == 1) | ||
400 | { | ||
401 | if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) && | ||
402 | (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24)) | ||
403 | { | ||
404 | if (ch == 0) | ||
405 | { | ||
406 | return log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]; | ||
407 | } else { | ||
408 | return log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]; | ||
409 | } | ||
410 | } else { | ||
411 | return 0; | ||
412 | } | ||
413 | } else { | ||
414 | if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30) | ||
415 | { | ||
416 | return log_Qplus1[sbr->Q[ch][k][l]]; | ||
417 | } else { | ||
418 | return 0; | ||
419 | } | ||
420 | } | ||
421 | } | ||
422 | |||
423 | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | ||
424 | { | ||
425 | /* log2 values of limiter gains */ | ||
426 | static real_t limGain[] = { | ||
427 | REAL_CONST(-1.0), REAL_CONST(0.0), REAL_CONST(1.0), REAL_CONST(33.219) | ||
428 | }; | ||
429 | uint8_t m, l, k; | ||
430 | |||
431 | uint8_t current_t_noise_band = 0; | ||
432 | uint8_t S_mapped; | ||
433 | |||
434 | ALIGN real_t Q_M_lim[MAX_M]; | ||
435 | ALIGN real_t G_lim[MAX_M]; | ||
436 | ALIGN real_t G_boost; | ||
437 | ALIGN real_t S_M[MAX_M]; | ||
438 | |||
439 | |||
440 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
441 | { | ||
442 | uint8_t current_f_noise_band = 0; | ||
443 | uint8_t current_res_band = 0; | ||
444 | uint8_t current_res_band2 = 0; | ||
445 | uint8_t current_hi_res_band = 0; | ||
446 | |||
447 | real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; | ||
448 | |||
449 | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); | ||
450 | |||
451 | if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) | ||
452 | { | ||
453 | current_t_noise_band++; | ||
454 | } | ||
455 | |||
456 | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | ||
457 | { | ||
458 | real_t Q_M = 0; | ||
459 | real_t G_max; | ||
460 | real_t den = 0; | ||
461 | real_t acc1 = 0; | ||
462 | real_t acc2 = 0; | ||
463 | uint8_t current_res_band_size = 0; | ||
464 | uint8_t Q_M_size = 0; | ||
465 | |||
466 | uint8_t ml1, ml2; | ||
467 | |||
468 | /* bounds of current limiter bands */ | ||
469 | ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | ||
470 | ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; | ||
471 | |||
472 | |||
473 | /* calculate the accumulated E_orig and E_curr over the limiter band */ | ||
474 | for (m = ml1; m < ml2; m++) | ||
475 | { | ||
476 | if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) | ||
477 | { | ||
478 | current_res_band_size++; | ||
479 | } else { | ||
480 | acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)); | ||
481 | |||
482 | current_res_band++; | ||
483 | current_res_band_size = 1; | ||
484 | } | ||
485 | |||
486 | acc2 += sbr->E_curr[ch][m][l]; | ||
487 | } | ||
488 | acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)); | ||
489 | |||
490 | |||
491 | if (acc1 == 0) | ||
492 | acc1 = LOG2_MIN_INF; | ||
493 | else | ||
494 | acc1 = log2_int(acc1); | ||
495 | |||
496 | |||
497 | /* calculate the maximum gain */ | ||
498 | /* ratio of the energy of the original signal and the energy | ||
499 | * of the HF generated signal | ||
500 | */ | ||
501 | G_max = acc1 - log2_int(acc2) + limGain[sbr->bs_limiter_gains]; | ||
502 | G_max = min(G_max, limGain[3]); | ||
503 | |||
504 | |||
505 | for (m = ml1; m < ml2; m++) | ||
506 | { | ||
507 | real_t G; | ||
508 | real_t E_curr, E_orig; | ||
509 | real_t Q_orig, Q_orig_plus1; | ||
510 | uint8_t S_index_mapped; | ||
511 | |||
512 | |||
513 | /* check if m is on a noise band border */ | ||
514 | if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) | ||
515 | { | ||
516 | /* step to next noise band */ | ||
517 | current_f_noise_band++; | ||
518 | } | ||
519 | |||
520 | |||
521 | /* check if m is on a resolution band border */ | ||
522 | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) | ||
523 | { | ||
524 | /* accumulate a whole range of equal Q_Ms */ | ||
525 | if (Q_M_size > 0) | ||
526 | den += pow2_int(log2_int_tab[Q_M_size] + Q_M); | ||
527 | Q_M_size = 0; | ||
528 | |||
529 | /* step to next resolution band */ | ||
530 | current_res_band2++; | ||
531 | |||
532 | /* if we move to a new resolution band, we should check if we are | ||
533 | * going to add a sinusoid in this band | ||
534 | */ | ||
535 | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); | ||
536 | } | ||
537 | |||
538 | |||
539 | /* check if m is on a HI_RES band border */ | ||
540 | if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) | ||
541 | { | ||
542 | /* step to next HI_RES band */ | ||
543 | current_hi_res_band++; | ||
544 | } | ||
545 | |||
546 | |||
547 | /* find S_index_mapped | ||
548 | * S_index_mapped can only be 1 for the m in the middle of the | ||
549 | * current HI_RES band | ||
550 | */ | ||
551 | S_index_mapped = 0; | ||
552 | if ((l >= sbr->l_A[ch]) || | ||
553 | (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) | ||
554 | { | ||
555 | /* find the middle subband of the HI_RES frequency band */ | ||
556 | if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) | ||
557 | S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; | ||
558 | } | ||
559 | |||
560 | |||
561 | /* find bitstream parameters */ | ||
562 | if (sbr->E_curr[ch][m][l] == 0) | ||
563 | E_curr = LOG2_MIN_INF; | ||
564 | else | ||
565 | E_curr = log2_int(sbr->E_curr[ch][m][l]); | ||
566 | E_orig = -REAL_CONST(10) + find_log2_E(sbr, current_res_band2, l, ch); | ||
567 | |||
568 | |||
569 | Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch); | ||
570 | Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch); | ||
571 | |||
572 | |||
573 | /* Q_M only depends on E_orig and Q_div2: | ||
574 | * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on | ||
575 | * a change of current res band (HI or LO) | ||
576 | */ | ||
577 | Q_M = E_orig + Q_orig - Q_orig_plus1; | ||
578 | |||
579 | |||
580 | /* S_M only depends on E_orig, Q_div and S_index_mapped: | ||
581 | * S_index_mapped can only be non-zero once per HI_RES band | ||
582 | */ | ||
583 | if (S_index_mapped == 0) | ||
584 | { | ||
585 | S_M[m] = LOG2_MIN_INF; /* -inf */ | ||
586 | } else { | ||
587 | S_M[m] = E_orig - Q_orig_plus1; | ||
588 | |||
589 | /* accumulate sinusoid part of the total energy */ | ||
590 | den += pow2_int(S_M[m]); | ||
591 | } | ||
592 | |||
593 | |||
594 | /* calculate gain */ | ||
595 | /* ratio of the energy of the original signal and the energy | ||
596 | * of the HF generated signal | ||
597 | */ | ||
598 | /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */ | ||
599 | /* scaled by -10 */ | ||
600 | G = E_orig - max(-REAL_CONST(10), E_curr); | ||
601 | if ((S_mapped == 0) && (delta == 1)) | ||
602 | { | ||
603 | /* G = G * 1/(1+Q) */ | ||
604 | G -= Q_orig_plus1; | ||
605 | } else if (S_mapped == 1) { | ||
606 | /* G = G * Q/(1+Q) */ | ||
607 | G += Q_orig - Q_orig_plus1; | ||
608 | } | ||
609 | |||
610 | |||
611 | /* limit the additional noise energy level */ | ||
612 | /* and apply the limiter */ | ||
613 | if (G_max > G) | ||
614 | { | ||
615 | Q_M_lim[m] = Q_M; | ||
616 | G_lim[m] = G; | ||
617 | |||
618 | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) | ||
619 | { | ||
620 | Q_M_size++; | ||
621 | } | ||
622 | } else { | ||
623 | /* G > G_max */ | ||
624 | Q_M_lim[m] = Q_M + G_max - G; | ||
625 | G_lim[m] = G_max; | ||
626 | |||
627 | /* accumulate limited Q_M */ | ||
628 | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) | ||
629 | { | ||
630 | den += pow2_int(Q_M_lim[m]); | ||
631 | } | ||
632 | } | ||
633 | |||
634 | |||
635 | /* accumulate the total energy */ | ||
636 | /* E_curr changes for every m so we do need to accumulate every m */ | ||
637 | den += pow2_int(E_curr + G_lim[m]); | ||
638 | } | ||
639 | |||
640 | /* accumulate last range of equal Q_Ms */ | ||
641 | if (Q_M_size > 0) | ||
642 | { | ||
643 | den += pow2_int(log2_int_tab[Q_M_size] + Q_M); | ||
644 | } | ||
645 | |||
646 | |||
647 | /* calculate the final gain */ | ||
648 | /* G_boost: [0..2.51188643] */ | ||
649 | G_boost = acc1 - log2_int(den /*+ EPS*/); | ||
650 | G_boost = min(G_boost, REAL_CONST(1.328771237) /* log2(1.584893192 ^ 2) */); | ||
651 | |||
652 | |||
653 | for (m = ml1; m < ml2; m++) | ||
654 | { | ||
655 | /* apply compensation to gain, noise floor sf's and sinusoid levels */ | ||
656 | #ifndef SBR_LOW_POWER | ||
657 | adj->G_lim_boost[l][m] = pow2_fix((G_lim[m] + G_boost) >> 1); | ||
658 | #else | ||
659 | /* sqrt() will be done after the aliasing reduction to save a | ||
660 | * few multiplies | ||
661 | */ | ||
662 | adj->G_lim_boost[l][m] = pow2_fix(G_lim[m] + G_boost); | ||
663 | #endif | ||
664 | adj->Q_M_lim_boost[l][m] = pow2_fix((Q_M_lim[m] + G_boost) >> 1); | ||
665 | |||
666 | if (S_M[m] != LOG2_MIN_INF) | ||
667 | { | ||
668 | adj->S_M_boost[l][m] = pow2_int((S_M[m] + G_boost) >> 1); | ||
669 | } else { | ||
670 | adj->S_M_boost[l][m] = 0; | ||
671 | } | ||
672 | } | ||
673 | } | ||
674 | } | ||
675 | } | ||
676 | |||
677 | #else | ||
678 | |||
679 | //#define LOG2_TEST | ||
680 | |||
681 | #ifdef LOG2_TEST | ||
682 | |||
683 | #define LOG2_MIN_INF -100000 | ||
684 | |||
685 | __inline float pow2(float val) | ||
686 | { | ||
687 | return pow(2.0, val); | ||
688 | } | ||
689 | __inline float log2(float val) | ||
690 | { | ||
691 | return log(val)/log(2.0); | ||
692 | } | ||
693 | |||
694 | #define RB 14 | ||
695 | |||
696 | float QUANTISE2REAL(float val) | ||
697 | { | ||
698 | __int32 ival = (__int32)(val * (1<<RB)); | ||
699 | return (float)ival / (float)((1<<RB)); | ||
700 | } | ||
701 | |||
702 | float QUANTISE2INT(float val) | ||
703 | { | ||
704 | return floor(val); | ||
705 | } | ||
706 | |||
707 | /* log2 values of [0..63] */ | ||
708 | static const real_t log2_int_tab[] = { | ||
709 | LOG2_MIN_INF, 0.000000000000000, 1.000000000000000, 1.584962500721156, | ||
710 | 2.000000000000000, 2.321928094887362, 2.584962500721156, 2.807354922057604, | ||
711 | 3.000000000000000, 3.169925001442313, 3.321928094887363, 3.459431618637297, | ||
712 | 3.584962500721156, 3.700439718141092, 3.807354922057604, 3.906890595608519, | ||
713 | 4.000000000000000, 4.087462841250339, 4.169925001442312, 4.247927513443585, | ||
714 | 4.321928094887362, 4.392317422778761, 4.459431618637297, 4.523561956057013, | ||
715 | 4.584962500721156, 4.643856189774724, 4.700439718141093, 4.754887502163468, | ||
716 | 4.807354922057604, 4.857980995127572, 4.906890595608519, 4.954196310386875, | ||
717 | 5.000000000000000, 5.044394119358453, 5.087462841250340, 5.129283016944966, | ||
718 | 5.169925001442312, 5.209453365628949, 5.247927513443585, 5.285402218862248, | ||
719 | 5.321928094887363, 5.357552004618084, 5.392317422778761, 5.426264754702098, | ||
720 | 5.459431618637297, 5.491853096329675, 5.523561956057013, 5.554588851677637, | ||
721 | 5.584962500721156, 5.614709844115208, 5.643856189774724, 5.672425341971495, | ||
722 | 5.700439718141093, 5.727920454563200, 5.754887502163469, 5.781359713524660, | ||
723 | 5.807354922057605, 5.832890014164742, 5.857980995127572, 5.882643049361842, | ||
724 | 5.906890595608518, 5.930737337562887, 5.954196310386876, 5.977279923499916 | ||
725 | }; | ||
726 | |||
727 | static const real_t pan_log2_tab[] = { | ||
728 | 1.000000000000000, 0.584962500721156, 0.321928094887362, 0.169925001442312, 0.087462841250339, | ||
729 | 0.044394119358453, 0.022367813028455, 0.011227255423254, 0.005624549193878, 0.002815015607054, | ||
730 | 0.001408194392808, 0.000704269011247, 0.000352177480301, 0.000176099486443, 0.000088052430122, | ||
731 | 0.000044026886827, 0.000022013611360, 0.000011006847667 | ||
732 | }; | ||
733 | |||
734 | static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) | ||
735 | { | ||
736 | /* check for coupled energy/noise data */ | ||
737 | if (sbr->bs_coupling == 1) | ||
738 | { | ||
739 | real_t amp0 = (sbr->amp_res[0]) ? 1.0 : 0.5; | ||
740 | real_t amp1 = (sbr->amp_res[1]) ? 1.0 : 0.5; | ||
741 | float tmp = QUANTISE2REAL(7.0 + (real_t)sbr->E[0][k][l] * amp0); | ||
742 | float pan; | ||
743 | |||
744 | int E = (int)(sbr->E[1][k][l] * amp1); | ||
745 | |||
746 | if (ch == 0) | ||
747 | { | ||
748 | if (E > 12) | ||
749 | { | ||
750 | /* negative */ | ||
751 | pan = QUANTISE2REAL(pan_log2_tab[-12 + E]); | ||
752 | } else { | ||
753 | /* positive */ | ||
754 | pan = QUANTISE2REAL(pan_log2_tab[12 - E] + (12 - E)); | ||
755 | } | ||
756 | } else { | ||
757 | if (E < 12) | ||
758 | { | ||
759 | /* negative */ | ||
760 | pan = QUANTISE2REAL(pan_log2_tab[-E + 12]); | ||
761 | } else { | ||
762 | /* positive */ | ||
763 | pan = QUANTISE2REAL(pan_log2_tab[E - 12] + (E - 12)); | ||
764 | } | ||
765 | } | ||
766 | |||
767 | /* tmp / pan in log2 */ | ||
768 | return QUANTISE2REAL(tmp - pan); | ||
769 | } else { | ||
770 | real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5; | ||
771 | |||
772 | return QUANTISE2REAL(6.0 + (real_t)sbr->E[ch][k][l] * amp); | ||
773 | } | ||
774 | } | ||
775 | |||
776 | static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) | ||
777 | { | ||
778 | /* check for coupled energy/noise data */ | ||
779 | if (sbr->bs_coupling == 1) | ||
780 | { | ||
781 | float tmp = QUANTISE2REAL(7.0 - (real_t)sbr->Q[0][k][l]); | ||
782 | float pan; | ||
783 | |||
784 | int Q = (int)(sbr->Q[1][k][l]); | ||
785 | |||
786 | if (ch == 0) | ||
787 | { | ||
788 | if (Q > 12) | ||
789 | { | ||
790 | /* negative */ | ||
791 | pan = QUANTISE2REAL(pan_log2_tab[-12 + Q]); | ||
792 | } else { | ||
793 | /* positive */ | ||
794 | pan = QUANTISE2REAL(pan_log2_tab[12 - Q] + (12 - Q)); | ||
795 | } | ||
796 | } else { | ||
797 | if (Q < 12) | ||
798 | { | ||
799 | /* negative */ | ||
800 | pan = QUANTISE2REAL(pan_log2_tab[-Q + 12]); | ||
801 | } else { | ||
802 | /* positive */ | ||
803 | pan = QUANTISE2REAL(pan_log2_tab[Q - 12] + (Q - 12)); | ||
804 | } | ||
805 | } | ||
806 | |||
807 | /* tmp / pan in log2 */ | ||
808 | return QUANTISE2REAL(tmp - pan); | ||
809 | } else { | ||
810 | return QUANTISE2REAL(6.0 - (real_t)sbr->Q[ch][k][l]); | ||
811 | } | ||
812 | } | ||
813 | |||
814 | static const real_t log_Qplus1_pan[31][13] = { | ||
815 | { REAL_CONST(0.044383447617292), REAL_CONST(0.169768601655960), REAL_CONST(0.583090126514435), REAL_CONST(1.570089221000671), REAL_CONST(3.092446088790894), REAL_CONST(4.733354568481445), REAL_CONST(6.022367954254150), REAL_CONST(6.692092418670654), REAL_CONST(6.924463272094727), REAL_CONST(6.989034175872803), REAL_CONST(7.005646705627441), REAL_CONST(7.009829998016357), REAL_CONST(7.010877609252930) }, | ||
816 | { REAL_CONST(0.022362394258380), REAL_CONST(0.087379962205887), REAL_CONST(0.320804953575134), REAL_CONST(0.988859415054321), REAL_CONST(2.252387046813965), REAL_CONST(3.786596298217773), REAL_CONST(5.044394016265869), REAL_CONST(5.705977916717529), REAL_CONST(5.936291694641113), REAL_CONST(6.000346660614014), REAL_CONST(6.016829967498779), REAL_CONST(6.020981311798096), REAL_CONST(6.022020816802979) }, | ||
817 | { REAL_CONST(0.011224525049329), REAL_CONST(0.044351425021887), REAL_CONST(0.169301137328148), REAL_CONST(0.577544987201691), REAL_CONST(1.527246952056885), REAL_CONST(2.887525320053101), REAL_CONST(4.087462902069092), REAL_CONST(4.733354568481445), REAL_CONST(4.959661006927490), REAL_CONST(5.022709369659424), REAL_CONST(5.038940429687500), REAL_CONST(5.043028831481934), REAL_CONST(5.044052600860596) }, | ||
818 | { REAL_CONST(0.005623178556561), REAL_CONST(0.022346137091517), REAL_CONST(0.087132595479488), REAL_CONST(0.317482173442841), REAL_CONST(0.956931233406067), REAL_CONST(2.070389270782471), REAL_CONST(3.169924974441528), REAL_CONST(3.786596298217773), REAL_CONST(4.005294322967529), REAL_CONST(4.066420555114746), REAL_CONST(4.082170009613037), REAL_CONST(4.086137294769287), REAL_CONST(4.087131500244141) }, | ||
819 | { REAL_CONST(0.002814328996465), REAL_CONST(0.011216334067285), REAL_CONST(0.044224001467228), REAL_CONST(0.167456731200218), REAL_CONST(0.556393325328827), REAL_CONST(1.378511548042297), REAL_CONST(2.321928024291992), REAL_CONST(2.887525320053101), REAL_CONST(3.092446088790894), REAL_CONST(3.150059700012207), REAL_CONST(3.164926528930664), REAL_CONST(3.168673276901245), REAL_CONST(3.169611930847168) }, | ||
820 | { REAL_CONST(0.001407850766554), REAL_CONST(0.005619067233056), REAL_CONST(0.022281449288130), REAL_CONST(0.086156636476517), REAL_CONST(0.304854571819305), REAL_CONST(0.847996890544891), REAL_CONST(1.584962487220764), REAL_CONST(2.070389270782471), REAL_CONST(2.252387046813965), REAL_CONST(2.304061651229858), REAL_CONST(2.317430257797241), REAL_CONST(2.320801734924316), REAL_CONST(2.321646213531494) }, | ||
821 | { REAL_CONST(0.000704097095877), REAL_CONST(0.002812269143760), REAL_CONST(0.011183738708496), REAL_CONST(0.043721374124289), REAL_CONST(0.160464659333229), REAL_CONST(0.485426813364029), REAL_CONST(1.000000000000000), REAL_CONST(1.378511548042297), REAL_CONST(1.527246952056885), REAL_CONST(1.570089221000671), REAL_CONST(1.581215262413025), REAL_CONST(1.584023833274841), REAL_CONST(1.584727644920349) }, | ||
822 | { REAL_CONST(0.000352177477907), REAL_CONST(0.001406819908880), REAL_CONST(0.005602621007711), REAL_CONST(0.022026389837265), REAL_CONST(0.082462236285210), REAL_CONST(0.263034462928772), REAL_CONST(0.584962487220764), REAL_CONST(0.847996890544891), REAL_CONST(0.956931233406067), REAL_CONST(0.988859415054321), REAL_CONST(0.997190535068512), REAL_CONST(0.999296069145203), REAL_CONST(0.999823868274689) }, | ||
823 | { REAL_CONST(0.000176099492819), REAL_CONST(0.000703581434209), REAL_CONST(0.002804030198604), REAL_CONST(0.011055230163038), REAL_CONST(0.041820213198662), REAL_CONST(0.137503549456596), REAL_CONST(0.321928083896637), REAL_CONST(0.485426813364029), REAL_CONST(0.556393325328827), REAL_CONST(0.577544987201691), REAL_CONST(0.583090126514435), REAL_CONST(0.584493279457092), REAL_CONST(0.584845066070557) }, | ||
824 | { REAL_CONST(0.000088052431238), REAL_CONST(0.000351833587047), REAL_CONST(0.001402696361765), REAL_CONST(0.005538204684854), REAL_CONST(0.021061634644866), REAL_CONST(0.070389263331890), REAL_CONST(0.169925004243851), REAL_CONST(0.263034462928772), REAL_CONST(0.304854571819305), REAL_CONST(0.317482173442841), REAL_CONST(0.320804953575134), REAL_CONST(0.321646571159363), REAL_CONST(0.321857661008835) }, | ||
825 | { REAL_CONST(0.000044026888645), REAL_CONST(0.000175927518285), REAL_CONST(0.000701518612914), REAL_CONST(0.002771759871393), REAL_CONST(0.010569252073765), REAL_CONST(0.035623874515295), REAL_CONST(0.087462842464447), REAL_CONST(0.137503549456596), REAL_CONST(0.160464659333229), REAL_CONST(0.167456731200218), REAL_CONST(0.169301137328148), REAL_CONST(0.169768601655960), REAL_CONST(0.169885858893394) }, | ||
826 | { REAL_CONST(0.000022013611670), REAL_CONST(0.000088052431238), REAL_CONST(0.000350801943569), REAL_CONST(0.001386545598507), REAL_CONST(0.005294219125062), REAL_CONST(0.017921976745129), REAL_CONST(0.044394120573997), REAL_CONST(0.070389263331890), REAL_CONST(0.082462236285210), REAL_CONST(0.086156636476517), REAL_CONST(0.087132595479488), REAL_CONST(0.087379962205887), REAL_CONST(0.087442122399807) }, | ||
827 | { REAL_CONST(0.000011006847672), REAL_CONST(0.000044026888645), REAL_CONST(0.000175411638338), REAL_CONST(0.000693439331371), REAL_CONST(0.002649537986144), REAL_CONST(0.008988817222416), REAL_CONST(0.022367812693119), REAL_CONST(0.035623874515295), REAL_CONST(0.041820213198662), REAL_CONST(0.043721374124289), REAL_CONST(0.044224001467228), REAL_CONST(0.044351425021887), REAL_CONST(0.044383447617292) }, | ||
828 | { REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000087708482170), REAL_CONST(0.000346675369656), REAL_CONST(0.001325377263129), REAL_CONST(0.004501323681325), REAL_CONST(0.011227255687118), REAL_CONST(0.017921976745129), REAL_CONST(0.021061634644866), REAL_CONST(0.022026389837265), REAL_CONST(0.022281449288130), REAL_CONST(0.022346137091517), REAL_CONST(0.022362394258380) }, | ||
829 | { REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043854910473), REAL_CONST(0.000173348103999), REAL_CONST(0.000662840844598), REAL_CONST(0.002252417383716), REAL_CONST(0.005624548997730), REAL_CONST(0.008988817222416), REAL_CONST(0.010569252073765), REAL_CONST(0.011055230163038), REAL_CONST(0.011183738708496), REAL_CONST(0.011216334067285), REAL_CONST(0.011224525049329) }, | ||
830 | { REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000022013611670), REAL_CONST(0.000086676649516), REAL_CONST(0.000331544462824), REAL_CONST(0.001126734190620), REAL_CONST(0.002815015614033), REAL_CONST(0.004501323681325), REAL_CONST(0.005294219125062), REAL_CONST(0.005538204684854), REAL_CONST(0.005602621007711), REAL_CONST(0.005619067233056), REAL_CONST(0.005623178556561) }, | ||
831 | { REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000011006847672), REAL_CONST(0.000043338975956), REAL_CONST(0.000165781748365), REAL_CONST(0.000563477107789), REAL_CONST(0.001408194424585), REAL_CONST(0.002252417383716), REAL_CONST(0.002649537986144), REAL_CONST(0.002771759871393), REAL_CONST(0.002804030198604), REAL_CONST(0.002812269143760), REAL_CONST(0.002814328996465) }, | ||
832 | { REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000021669651687), REAL_CONST(0.000082893253420), REAL_CONST(0.000281680084299), REAL_CONST(0.000704268983100), REAL_CONST(0.001126734190620), REAL_CONST(0.001325377263129), REAL_CONST(0.001386545598507), REAL_CONST(0.001402696361765), REAL_CONST(0.001406819908880), REAL_CONST(0.001407850766554) }, | ||
833 | { REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010834866771), REAL_CONST(0.000041447223339), REAL_CONST(0.000140846910654), REAL_CONST(0.000352177477907), REAL_CONST(0.000563477107789), REAL_CONST(0.000662840844598), REAL_CONST(0.000693439331371), REAL_CONST(0.000701518612914), REAL_CONST(0.000703581434209), REAL_CONST(0.000704097095877) }, | ||
834 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005503434295), REAL_CONST(0.000020637769921), REAL_CONST(0.000070511166996), REAL_CONST(0.000176099492819), REAL_CONST(0.000281680084299), REAL_CONST(0.000331544462824), REAL_CONST(0.000346675369656), REAL_CONST(0.000350801943569), REAL_CONST(0.000351833587047), REAL_CONST(0.000352177477907) }, | ||
835 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002751719876), REAL_CONST(0.000010318922250), REAL_CONST(0.000035256012779), REAL_CONST(0.000088052431238), REAL_CONST(0.000140846910654), REAL_CONST(0.000165781748365), REAL_CONST(0.000173348103999), REAL_CONST(0.000175411638338), REAL_CONST(0.000175927518285), REAL_CONST(0.000176099492819) }, | ||
836 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000005159470220), REAL_CONST(0.000017542124624), REAL_CONST(0.000044026888645), REAL_CONST(0.000070511166996), REAL_CONST(0.000082893253420), REAL_CONST(0.000086676649516), REAL_CONST(0.000087708482170), REAL_CONST(0.000088052431238), REAL_CONST(0.000088052431238) }, | ||
837 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002579737384), REAL_CONST(0.000008771088687), REAL_CONST(0.000022013611670), REAL_CONST(0.000035256012779), REAL_CONST(0.000041447223339), REAL_CONST(0.000043338975956), REAL_CONST(0.000043854910473), REAL_CONST(0.000044026888645), REAL_CONST(0.000044026888645) }, | ||
838 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001375860506), REAL_CONST(0.000004471542070), REAL_CONST(0.000011006847672), REAL_CONST(0.000017542124624), REAL_CONST(0.000020637769921), REAL_CONST(0.000021669651687), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670), REAL_CONST(0.000022013611670) }, | ||
839 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000687930424), REAL_CONST(0.000002235772627), REAL_CONST(0.000005503434295), REAL_CONST(0.000008771088687), REAL_CONST(0.000010318922250), REAL_CONST(0.000010834866771), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672), REAL_CONST(0.000011006847672) }, | ||
840 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000001031895522), REAL_CONST(0.000002751719876), REAL_CONST(0.000004471542070), REAL_CONST(0.000005159470220), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295), REAL_CONST(0.000005503434295) }, | ||
841 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000515947875), REAL_CONST(0.000001375860506), REAL_CONST(0.000002235772627), REAL_CONST(0.000002579737384), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876), REAL_CONST(0.000002751719876) }, | ||
842 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000343965269), REAL_CONST(0.000000687930424), REAL_CONST(0.000001031895522), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506), REAL_CONST(0.000001375860506) }, | ||
843 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000515947875), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424), REAL_CONST(0.000000687930424) }, | ||
844 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269), REAL_CONST(0.000000343965269) }, | ||
845 | { REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000000000000), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634), REAL_CONST(0.000000171982634) } | ||
846 | }; | ||
847 | |||
848 | static const real_t log_Qplus1[31] = { | ||
849 | REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339), | ||
850 | REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156), | ||
851 | REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), | ||
852 | REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453), | ||
853 | REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), | ||
854 | REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), | ||
855 | REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122), | ||
856 | REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667), | ||
857 | REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551), | ||
858 | REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641), | ||
859 | REAL_CONST(0.000000000000000) | ||
860 | }; | ||
861 | |||
862 | static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch) | ||
863 | { | ||
864 | /* check for coupled energy/noise data */ | ||
865 | if (sbr->bs_coupling == 1) | ||
866 | { | ||
867 | if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) && | ||
868 | (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24)) | ||
869 | { | ||
870 | if (ch == 0) | ||
871 | { | ||
872 | return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]); | ||
873 | } else { | ||
874 | return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]); | ||
875 | } | ||
876 | } else { | ||
877 | return 0; | ||
878 | } | ||
879 | } else { | ||
880 | if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30) | ||
881 | { | ||
882 | return QUANTISE2REAL(log_Qplus1[sbr->Q[ch][k][l]]); | ||
883 | } else { | ||
884 | return 0; | ||
885 | } | ||
886 | } | ||
887 | } | ||
888 | |||
889 | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | ||
890 | { | ||
891 | /* log2 values of limiter gains */ | ||
892 | static real_t limGain[] = { -1.0, 0.0, 1.0, 33.219 }; | ||
893 | uint8_t m, l, k; | ||
894 | |||
895 | uint8_t current_t_noise_band = 0; | ||
896 | uint8_t S_mapped; | ||
897 | |||
898 | ALIGN real_t Q_M_lim[MAX_M]; | ||
899 | ALIGN real_t G_lim[MAX_M]; | ||
900 | ALIGN real_t G_boost; | ||
901 | ALIGN real_t S_M[MAX_M]; | ||
902 | |||
903 | |||
904 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
905 | { | ||
906 | uint8_t current_f_noise_band = 0; | ||
907 | uint8_t current_res_band = 0; | ||
908 | uint8_t current_res_band2 = 0; | ||
909 | uint8_t current_hi_res_band = 0; | ||
910 | |||
911 | real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; | ||
912 | |||
913 | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); | ||
914 | |||
915 | if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) | ||
916 | { | ||
917 | current_t_noise_band++; | ||
918 | } | ||
919 | |||
920 | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | ||
921 | { | ||
922 | real_t Q_M = 0; | ||
923 | real_t G_max; | ||
924 | real_t den = 0; | ||
925 | real_t acc1 = 0; | ||
926 | real_t acc2 = 0; | ||
927 | uint8_t current_res_band_size = 0; | ||
928 | uint8_t Q_M_size = 0; | ||
929 | |||
930 | uint8_t ml1, ml2; | ||
931 | |||
932 | /* bounds of current limiter bands */ | ||
933 | ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | ||
934 | ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; | ||
935 | |||
936 | |||
937 | /* calculate the accumulated E_orig and E_curr over the limiter band */ | ||
938 | for (m = ml1; m < ml2; m++) | ||
939 | { | ||
940 | if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) | ||
941 | { | ||
942 | current_res_band_size++; | ||
943 | } else { | ||
944 | acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch))); | ||
945 | |||
946 | current_res_band++; | ||
947 | current_res_band_size = 1; | ||
948 | } | ||
949 | |||
950 | acc2 += QUANTISE2INT(sbr->E_curr[ch][m][l]/1024.0); | ||
951 | } | ||
952 | acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch))); | ||
953 | |||
954 | acc1 = QUANTISE2REAL( log2(EPS + acc1) ); | ||
955 | |||
956 | |||
957 | /* calculate the maximum gain */ | ||
958 | /* ratio of the energy of the original signal and the energy | ||
959 | * of the HF generated signal | ||
960 | */ | ||
961 | G_max = acc1 - QUANTISE2REAL(log2(EPS + acc2)) + QUANTISE2REAL(limGain[sbr->bs_limiter_gains]); | ||
962 | G_max = min(G_max, QUANTISE2REAL(limGain[3])); | ||
963 | |||
964 | |||
965 | for (m = ml1; m < ml2; m++) | ||
966 | { | ||
967 | real_t G; | ||
968 | real_t E_curr, E_orig; | ||
969 | real_t Q_orig, Q_orig_plus1; | ||
970 | uint8_t S_index_mapped; | ||
971 | |||
972 | |||
973 | /* check if m is on a noise band border */ | ||
974 | if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) | ||
975 | { | ||
976 | /* step to next noise band */ | ||
977 | current_f_noise_band++; | ||
978 | } | ||
979 | |||
980 | |||
981 | /* check if m is on a resolution band border */ | ||
982 | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) | ||
983 | { | ||
984 | /* accumulate a whole range of equal Q_Ms */ | ||
985 | if (Q_M_size > 0) | ||
986 | den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M)); | ||
987 | Q_M_size = 0; | ||
988 | |||
989 | /* step to next resolution band */ | ||
990 | current_res_band2++; | ||
991 | |||
992 | /* if we move to a new resolution band, we should check if we are | ||
993 | * going to add a sinusoid in this band | ||
994 | */ | ||
995 | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); | ||
996 | } | ||
997 | |||
998 | |||
999 | /* check if m is on a HI_RES band border */ | ||
1000 | if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) | ||
1001 | { | ||
1002 | /* step to next HI_RES band */ | ||
1003 | current_hi_res_band++; | ||
1004 | } | ||
1005 | |||
1006 | |||
1007 | /* find S_index_mapped | ||
1008 | * S_index_mapped can only be 1 for the m in the middle of the | ||
1009 | * current HI_RES band | ||
1010 | */ | ||
1011 | S_index_mapped = 0; | ||
1012 | if ((l >= sbr->l_A[ch]) || | ||
1013 | (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) | ||
1014 | { | ||
1015 | /* find the middle subband of the HI_RES frequency band */ | ||
1016 | if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) | ||
1017 | S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | /* find bitstream parameters */ | ||
1022 | if (sbr->E_curr[ch][m][l] == 0) | ||
1023 | E_curr = LOG2_MIN_INF; | ||
1024 | else | ||
1025 | E_curr = -10 + log2(sbr->E_curr[ch][m][l]); | ||
1026 | E_orig = -10 + find_log2_E(sbr, current_res_band2, l, ch); | ||
1027 | |||
1028 | Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch); | ||
1029 | Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch); | ||
1030 | |||
1031 | |||
1032 | /* Q_M only depends on E_orig and Q_div2: | ||
1033 | * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on | ||
1034 | * a change of current res band (HI or LO) | ||
1035 | */ | ||
1036 | Q_M = E_orig + Q_orig - Q_orig_plus1; | ||
1037 | |||
1038 | |||
1039 | /* S_M only depends on E_orig, Q_div and S_index_mapped: | ||
1040 | * S_index_mapped can only be non-zero once per HI_RES band | ||
1041 | */ | ||
1042 | if (S_index_mapped == 0) | ||
1043 | { | ||
1044 | S_M[m] = LOG2_MIN_INF; /* -inf */ | ||
1045 | } else { | ||
1046 | S_M[m] = E_orig - Q_orig_plus1; | ||
1047 | |||
1048 | /* accumulate sinusoid part of the total energy */ | ||
1049 | den += pow2(S_M[m]); | ||
1050 | } | ||
1051 | |||
1052 | |||
1053 | /* calculate gain */ | ||
1054 | /* ratio of the energy of the original signal and the energy | ||
1055 | * of the HF generated signal | ||
1056 | */ | ||
1057 | /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */ | ||
1058 | /* scaled by -10 */ | ||
1059 | G = E_orig - max(-10, E_curr); | ||
1060 | if ((S_mapped == 0) && (delta == 1)) | ||
1061 | { | ||
1062 | /* G = G * 1/(1+Q) */ | ||
1063 | G -= Q_orig_plus1; | ||
1064 | } else if (S_mapped == 1) { | ||
1065 | /* G = G * Q/(1+Q) */ | ||
1066 | G += Q_orig - Q_orig_plus1; | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | /* limit the additional noise energy level */ | ||
1071 | /* and apply the limiter */ | ||
1072 | if (G_max > G) | ||
1073 | { | ||
1074 | Q_M_lim[m] = QUANTISE2REAL(Q_M); | ||
1075 | G_lim[m] = QUANTISE2REAL(G); | ||
1076 | |||
1077 | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) | ||
1078 | { | ||
1079 | Q_M_size++; | ||
1080 | } | ||
1081 | } else { | ||
1082 | /* G > G_max */ | ||
1083 | Q_M_lim[m] = QUANTISE2REAL(Q_M) + G_max - QUANTISE2REAL(G); | ||
1084 | G_lim[m] = G_max; | ||
1085 | |||
1086 | /* accumulate limited Q_M */ | ||
1087 | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) | ||
1088 | { | ||
1089 | den += QUANTISE2INT(pow2(Q_M_lim[m])); | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | |||
1094 | /* accumulate the total energy */ | ||
1095 | /* E_curr changes for every m so we do need to accumulate every m */ | ||
1096 | den += QUANTISE2INT(pow2(E_curr + G_lim[m])); | ||
1097 | } | ||
1098 | |||
1099 | /* accumulate last range of equal Q_Ms */ | ||
1100 | if (Q_M_size > 0) | ||
1101 | { | ||
1102 | den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M)); | ||
1103 | } | ||
1104 | |||
1105 | |||
1106 | /* calculate the final gain */ | ||
1107 | /* G_boost: [0..2.51188643] */ | ||
1108 | G_boost = acc1 - QUANTISE2REAL(log2(den + EPS)); | ||
1109 | G_boost = min(G_boost, QUANTISE2REAL(1.328771237) /* log2(1.584893192 ^ 2) */); | ||
1110 | |||
1111 | |||
1112 | for (m = ml1; m < ml2; m++) | ||
1113 | { | ||
1114 | /* apply compensation to gain, noise floor sf's and sinusoid levels */ | ||
1115 | #ifndef SBR_LOW_POWER | ||
1116 | adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2((G_lim[m] + G_boost) / 2.0)); | ||
1117 | #else | ||
1118 | /* sqrt() will be done after the aliasing reduction to save a | ||
1119 | * few multiplies | ||
1120 | */ | ||
1121 | adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2(G_lim[m] + G_boost)); | ||
1122 | #endif | ||
1123 | adj->Q_M_lim_boost[l][m] = QUANTISE2REAL(pow2((Q_M_lim[m] + 10 + G_boost) / 2.0)); | ||
1124 | |||
1125 | if (S_M[m] != LOG2_MIN_INF) | ||
1126 | { | ||
1127 | adj->S_M_boost[l][m] = QUANTISE2REAL(pow2((S_M[m] + 10 + G_boost) / 2.0)); | ||
1128 | } else { | ||
1129 | adj->S_M_boost[l][m] = 0; | ||
1130 | } | ||
1131 | } | ||
1132 | } | ||
1133 | } | ||
1134 | } | ||
1135 | |||
1136 | #else | ||
1137 | |||
1138 | static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | ||
1139 | { | ||
1140 | static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 }; | ||
1141 | uint8_t m, l, k; | ||
1142 | |||
1143 | uint8_t current_t_noise_band = 0; | ||
1144 | uint8_t S_mapped; | ||
1145 | |||
1146 | ALIGN real_t Q_M_lim[MAX_M]; | ||
1147 | ALIGN real_t G_lim[MAX_M]; | ||
1148 | ALIGN real_t G_boost; | ||
1149 | ALIGN real_t S_M[MAX_M]; | ||
1150 | |||
1151 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
1152 | { | ||
1153 | uint8_t current_f_noise_band = 0; | ||
1154 | uint8_t current_res_band = 0; | ||
1155 | uint8_t current_res_band2 = 0; | ||
1156 | uint8_t current_hi_res_band = 0; | ||
1157 | |||
1158 | real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; | ||
1159 | |||
1160 | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); | ||
1161 | |||
1162 | if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1]) | ||
1163 | { | ||
1164 | current_t_noise_band++; | ||
1165 | } | ||
1166 | |||
1167 | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | ||
1168 | { | ||
1169 | real_t G_max; | ||
1170 | real_t den = 0; | ||
1171 | real_t acc1 = 0; | ||
1172 | real_t acc2 = 0; | ||
1173 | uint8_t current_res_band_size = 0; | ||
1174 | |||
1175 | uint8_t ml1, ml2; | ||
1176 | |||
1177 | ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | ||
1178 | ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; | ||
1179 | |||
1180 | |||
1181 | /* calculate the accumulated E_orig and E_curr over the limiter band */ | ||
1182 | for (m = ml1; m < ml2; m++) | ||
1183 | { | ||
1184 | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1]) | ||
1185 | { | ||
1186 | current_res_band++; | ||
1187 | } | ||
1188 | acc1 += sbr->E_orig[ch][current_res_band][l]; | ||
1189 | acc2 += sbr->E_curr[ch][m][l]; | ||
1190 | } | ||
1191 | |||
1192 | |||
1193 | /* calculate the maximum gain */ | ||
1194 | /* ratio of the energy of the original signal and the energy | ||
1195 | * of the HF generated signal | ||
1196 | */ | ||
1197 | G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains]; | ||
1198 | G_max = min(G_max, 1e10); | ||
1199 | |||
1200 | |||
1201 | for (m = ml1; m < ml2; m++) | ||
1202 | { | ||
1203 | real_t Q_M, G; | ||
1204 | real_t Q_div, Q_div2; | ||
1205 | uint8_t S_index_mapped; | ||
1206 | |||
1207 | |||
1208 | /* check if m is on a noise band border */ | ||
1209 | if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1]) | ||
1210 | { | ||
1211 | /* step to next noise band */ | ||
1212 | current_f_noise_band++; | ||
1213 | } | ||
1214 | |||
1215 | |||
1216 | /* check if m is on a resolution band border */ | ||
1217 | if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1]) | ||
1218 | { | ||
1219 | /* step to next resolution band */ | ||
1220 | current_res_band2++; | ||
1221 | |||
1222 | /* if we move to a new resolution band, we should check if we are | ||
1223 | * going to add a sinusoid in this band | ||
1224 | */ | ||
1225 | S_mapped = get_S_mapped(sbr, ch, l, current_res_band2); | ||
1226 | } | ||
1227 | |||
1228 | |||
1229 | /* check if m is on a HI_RES band border */ | ||
1230 | if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1]) | ||
1231 | { | ||
1232 | /* step to next HI_RES band */ | ||
1233 | current_hi_res_band++; | ||
1234 | } | ||
1235 | |||
1236 | |||
1237 | /* find S_index_mapped | ||
1238 | * S_index_mapped can only be 1 for the m in the middle of the | ||
1239 | * current HI_RES band | ||
1240 | */ | ||
1241 | S_index_mapped = 0; | ||
1242 | if ((l >= sbr->l_A[ch]) || | ||
1243 | (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch])) | ||
1244 | { | ||
1245 | /* find the middle subband of the HI_RES frequency band */ | ||
1246 | if ((m + sbr->kx) == (sbr->f_table_res[HI_RES][current_hi_res_band+1] + sbr->f_table_res[HI_RES][current_hi_res_band]) >> 1) | ||
1247 | S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band]; | ||
1248 | } | ||
1249 | |||
1250 | |||
1251 | /* Q_div: [0..1] (1/(1+Q_mapped)) */ | ||
1252 | Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band]; | ||
1253 | |||
1254 | |||
1255 | /* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */ | ||
1256 | Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band]; | ||
1257 | |||
1258 | |||
1259 | /* Q_M only depends on E_orig and Q_div2: | ||
1260 | * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on | ||
1261 | * a change of current noise band | ||
1262 | */ | ||
1263 | Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2; | ||
1264 | |||
1265 | |||
1266 | /* S_M only depends on E_orig, Q_div and S_index_mapped: | ||
1267 | * S_index_mapped can only be non-zero once per HI_RES band | ||
1268 | */ | ||
1269 | if (S_index_mapped == 0) | ||
1270 | { | ||
1271 | S_M[m] = 0; | ||
1272 | } else { | ||
1273 | S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div; | ||
1274 | |||
1275 | /* accumulate sinusoid part of the total energy */ | ||
1276 | den += S_M[m]; | ||
1277 | } | ||
1278 | |||
1279 | |||
1280 | /* calculate gain */ | ||
1281 | /* ratio of the energy of the original signal and the energy | ||
1282 | * of the HF generated signal | ||
1283 | */ | ||
1284 | G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]); | ||
1285 | if ((S_mapped == 0) && (delta == 1)) | ||
1286 | G *= Q_div; | ||
1287 | else if (S_mapped == 1) | ||
1288 | G *= Q_div2; | ||
1289 | |||
1290 | |||
1291 | /* limit the additional noise energy level */ | ||
1292 | /* and apply the limiter */ | ||
1293 | if (G_max > G) | ||
1294 | { | ||
1295 | Q_M_lim[m] = Q_M; | ||
1296 | G_lim[m] = G; | ||
1297 | } else { | ||
1298 | Q_M_lim[m] = Q_M * G_max / G; | ||
1299 | G_lim[m] = G_max; | ||
1300 | } | ||
1301 | |||
1302 | |||
1303 | /* accumulate the total energy */ | ||
1304 | den += sbr->E_curr[ch][m][l] * G_lim[m]; | ||
1305 | if ((S_index_mapped == 0) && (l != sbr->l_A[ch])) | ||
1306 | den += Q_M_lim[m]; | ||
1307 | } | ||
1308 | |||
1309 | /* G_boost: [0..2.51188643] */ | ||
1310 | G_boost = (acc1 + EPS) / (den + EPS); | ||
1311 | G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */); | ||
1312 | |||
1313 | for (m = ml1; m < ml2; m++) | ||
1314 | { | ||
1315 | /* apply compensation to gain, noise floor sf's and sinusoid levels */ | ||
1316 | #ifndef SBR_LOW_POWER | ||
1317 | adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost); | ||
1318 | #else | ||
1319 | /* sqrt() will be done after the aliasing reduction to save a | ||
1320 | * few multiplies | ||
1321 | */ | ||
1322 | adj->G_lim_boost[l][m] = G_lim[m] * G_boost; | ||
1323 | #endif | ||
1324 | adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost); | ||
1325 | |||
1326 | if (S_M[m] != 0) | ||
1327 | { | ||
1328 | adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost); | ||
1329 | } else { | ||
1330 | adj->S_M_boost[l][m] = 0; | ||
1331 | } | ||
1332 | } | ||
1333 | } | ||
1334 | } | ||
1335 | } | ||
1336 | #endif // log2_test | ||
1337 | |||
1338 | #endif | ||
1339 | |||
1340 | #ifdef SBR_LOW_POWER | ||
1341 | static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) | ||
1342 | { | ||
1343 | uint8_t l, k, i; | ||
1344 | uint8_t grouping; | ||
1345 | |||
1346 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
1347 | { | ||
1348 | i = 0; | ||
1349 | grouping = 0; | ||
1350 | |||
1351 | for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++) | ||
1352 | { | ||
1353 | if (deg[k + 1] && adj->S_mapped[l][k-sbr->kx] == 0) | ||
1354 | { | ||
1355 | if (grouping == 0) | ||
1356 | { | ||
1357 | sbr->f_group[l][i] = k; | ||
1358 | grouping = 1; | ||
1359 | i++; | ||
1360 | } | ||
1361 | } else { | ||
1362 | if (grouping) | ||
1363 | { | ||
1364 | if (adj->S_mapped[l][k-sbr->kx]) | ||
1365 | { | ||
1366 | sbr->f_group[l][i] = k; | ||
1367 | } else { | ||
1368 | sbr->f_group[l][i] = k + 1; | ||
1369 | } | ||
1370 | grouping = 0; | ||
1371 | i++; | ||
1372 | } | ||
1373 | } | ||
1374 | } | ||
1375 | |||
1376 | if (grouping) | ||
1377 | { | ||
1378 | sbr->f_group[l][i] = sbr->kx + sbr->M; | ||
1379 | i++; | ||
1380 | } | ||
1381 | |||
1382 | sbr->N_G[l] = (uint8_t)(i >> 1); | ||
1383 | } | ||
1384 | } | ||
1385 | |||
1386 | static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) | ||
1387 | { | ||
1388 | uint8_t l, k, m; | ||
1389 | real_t E_total, E_total_est, G_target, acc; | ||
1390 | |||
1391 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
1392 | { | ||
1393 | for (k = 0; k < sbr->N_G[l]; k++) | ||
1394 | { | ||
1395 | E_total_est = E_total = 0; | ||
1396 | |||
1397 | for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++) | ||
1398 | { | ||
1399 | /* E_curr: integer */ | ||
1400 | /* G_lim_boost: fixed point */ | ||
1401 | /* E_total_est: integer */ | ||
1402 | /* E_total: integer */ | ||
1403 | E_total_est += sbr->E_curr[ch][m-sbr->kx][l]; | ||
1404 | #ifdef FIXED_POINT | ||
1405 | E_total += MUL_Q2(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]); | ||
1406 | #else | ||
1407 | E_total += sbr->E_curr[ch][m-sbr->kx][l] * adj->G_lim_boost[l][m-sbr->kx]; | ||
1408 | #endif | ||
1409 | } | ||
1410 | |||
1411 | /* G_target: fixed point */ | ||
1412 | if ((E_total_est + EPS) == 0) | ||
1413 | { | ||
1414 | G_target = 0; | ||
1415 | } else { | ||
1416 | #ifdef FIXED_POINT | ||
1417 | G_target = (((int64_t)(E_total))<<Q2_BITS)/(E_total_est + EPS); | ||
1418 | #else | ||
1419 | G_target = E_total / (E_total_est + EPS); | ||
1420 | #endif | ||
1421 | } | ||
1422 | acc = 0; | ||
1423 | |||
1424 | for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) | ||
1425 | { | ||
1426 | real_t alpha; | ||
1427 | |||
1428 | /* alpha: (COEF) fixed point */ | ||
1429 | if (m < sbr->kx + sbr->M - 1) | ||
1430 | { | ||
1431 | alpha = max(deg[m], deg[m + 1]); | ||
1432 | } else { | ||
1433 | alpha = deg[m]; | ||
1434 | } | ||
1435 | |||
1436 | adj->G_lim_boost[l][m-sbr->kx] = MUL_C(alpha, G_target) + | ||
1437 | MUL_C((COEF_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]); | ||
1438 | |||
1439 | /* acc: integer */ | ||
1440 | #ifdef FIXED_POINT | ||
1441 | acc += MUL_Q2(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]); | ||
1442 | #else | ||
1443 | acc += adj->G_lim_boost[l][m-sbr->kx] * sbr->E_curr[ch][m-sbr->kx][l]; | ||
1444 | #endif | ||
1445 | } | ||
1446 | |||
1447 | /* acc: fixed point */ | ||
1448 | if (acc + EPS == 0) | ||
1449 | { | ||
1450 | acc = 0; | ||
1451 | } else { | ||
1452 | #ifdef FIXED_POINT | ||
1453 | acc = (((int64_t)(E_total))<<Q2_BITS)/(acc + EPS); | ||
1454 | #else | ||
1455 | acc = E_total / (acc + EPS); | ||
1456 | #endif | ||
1457 | } | ||
1458 | for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) | ||
1459 | { | ||
1460 | #ifdef FIXED_POINT | ||
1461 | adj->G_lim_boost[l][m-sbr->kx] = MUL_Q2(acc, adj->G_lim_boost[l][m-sbr->kx]); | ||
1462 | #else | ||
1463 | adj->G_lim_boost[l][m-sbr->kx] = acc * adj->G_lim_boost[l][m-sbr->kx]; | ||
1464 | #endif | ||
1465 | } | ||
1466 | } | ||
1467 | } | ||
1468 | |||
1469 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
1470 | { | ||
1471 | for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | ||
1472 | { | ||
1473 | for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | ||
1474 | m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | ||
1475 | { | ||
1476 | #ifdef FIXED_POINT | ||
1477 | adj->G_lim_boost[l][m] = SBR_SQRT_Q2(adj->G_lim_boost[l][m]); | ||
1478 | #else | ||
1479 | adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]); | ||
1480 | #endif | ||
1481 | } | ||
1482 | } | ||
1483 | } | ||
1484 | } | ||
1485 | #endif | ||
1486 | |||
1487 | static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, | ||
1488 | qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) | ||
1489 | { | ||
1490 | static real_t h_smooth[] = { | ||
1491 | FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084), | ||
1492 | FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582), | ||
1493 | FRAC_CONST(0.33333333333333) | ||
1494 | }; | ||
1495 | static int8_t phi_re[] = { 1, 0, -1, 0 }; | ||
1496 | static int8_t phi_im[] = { 0, 1, 0, -1 }; | ||
1497 | |||
1498 | uint8_t m, l, i, n; | ||
1499 | uint16_t fIndexNoise = 0; | ||
1500 | uint8_t fIndexSine = 0; | ||
1501 | uint8_t assembly_reset = 0; | ||
1502 | |||
1503 | real_t G_filt, Q_filt; | ||
1504 | |||
1505 | uint8_t h_SL; | ||
1506 | |||
1507 | |||
1508 | if (sbr->Reset == 1) | ||
1509 | { | ||
1510 | assembly_reset = 1; | ||
1511 | fIndexNoise = 0; | ||
1512 | } else { | ||
1513 | fIndexNoise = sbr->index_noise_prev[ch]; | ||
1514 | } | ||
1515 | fIndexSine = sbr->psi_is_prev[ch]; | ||
1516 | |||
1517 | |||
1518 | for (l = 0; l < sbr->L_E[ch]; l++) | ||
1519 | { | ||
1520 | uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; | ||
1521 | |||
1522 | #ifdef SBR_LOW_POWER | ||
1523 | h_SL = 0; | ||
1524 | #else | ||
1525 | h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; | ||
1526 | h_SL = (no_noise ? 0 : h_SL); | ||
1527 | #endif | ||
1528 | |||
1529 | if (assembly_reset) | ||
1530 | { | ||
1531 | for (n = 0; n < 4; n++) | ||
1532 | { | ||
1533 | memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | ||
1534 | memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | ||
1535 | } | ||
1536 | /* reset ringbuffer index */ | ||
1537 | sbr->GQ_ringbuf_index[ch] = 4; | ||
1538 | assembly_reset = 0; | ||
1539 | } | ||
1540 | |||
1541 | for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) | ||
1542 | { | ||
1543 | #ifdef SBR_LOW_POWER | ||
1544 | uint8_t i_min1, i_plus1; | ||
1545 | uint8_t sinusoids = 0; | ||
1546 | #endif | ||
1547 | |||
1548 | /* load new values into ringbuffer */ | ||
1549 | memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | ||
1550 | memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | ||
1551 | |||
1552 | for (m = 0; m < sbr->M; m++) | ||
1553 | { | ||
1554 | qmf_t psi; | ||
1555 | |||
1556 | G_filt = 0; | ||
1557 | Q_filt = 0; | ||
1558 | |||
1559 | #ifndef SBR_LOW_POWER | ||
1560 | if (h_SL != 0) | ||
1561 | { | ||
1562 | uint8_t ri = sbr->GQ_ringbuf_index[ch]; | ||
1563 | for (n = 0; n <= 4; n++) | ||
1564 | { | ||
1565 | real_t curr_h_smooth = h_smooth[n]; | ||
1566 | ri++; | ||
1567 | if (ri >= 5) | ||
1568 | ri -= 5; | ||
1569 | G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth); | ||
1570 | Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth); | ||
1571 | } | ||
1572 | } else { | ||
1573 | #endif | ||
1574 | G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; | ||
1575 | Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m]; | ||
1576 | #ifndef SBR_LOW_POWER | ||
1577 | } | ||
1578 | #endif | ||
1579 | |||
1580 | Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt; | ||
1581 | |||
1582 | /* add noise to the output */ | ||
1583 | fIndexNoise = (fIndexNoise + 1) & 511; | ||
1584 | |||
1585 | /* the smoothed gain values are applied to Xsbr */ | ||
1586 | /* V is defined, not calculated */ | ||
1587 | #ifndef FIXED_POINT | ||
1588 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) | ||
1589 | + MUL_F(Q_filt, RE(V[fIndexNoise])); | ||
1590 | #else | ||
1591 | //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | ||
1592 | // + MUL_F(Q_filt, RE(V[fIndexNoise])); | ||
1593 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | ||
1594 | + MUL_F(Q_filt, RE(V[fIndexNoise])); | ||
1595 | #endif | ||
1596 | if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) | ||
1597 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; | ||
1598 | #ifndef SBR_LOW_POWER | ||
1599 | #ifndef FIXED_POINT | ||
1600 | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) | ||
1601 | + MUL_F(Q_filt, IM(V[fIndexNoise])); | ||
1602 | #else | ||
1603 | //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | ||
1604 | // + MUL_F(Q_filt, IM(V[fIndexNoise])); | ||
1605 | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) | ||
1606 | + MUL_F(Q_filt, IM(V[fIndexNoise])); | ||
1607 | #endif | ||
1608 | #endif | ||
1609 | |||
1610 | { | ||
1611 | int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); | ||
1612 | QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine]; | ||
1613 | #ifdef FIXED_POINT | ||
1614 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_RE(psi) << REAL_BITS); | ||
1615 | #else | ||
1616 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); | ||
1617 | #endif | ||
1618 | |||
1619 | #ifndef SBR_LOW_POWER | ||
1620 | QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine]; | ||
1621 | #ifdef FIXED_POINT | ||
1622 | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_IM(psi) << REAL_BITS); | ||
1623 | #else | ||
1624 | QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); | ||
1625 | #endif | ||
1626 | #else | ||
1627 | |||
1628 | i_min1 = (fIndexSine - 1) & 3; | ||
1629 | i_plus1 = (fIndexSine + 1) & 3; | ||
1630 | |||
1631 | #ifndef FIXED_POINT | ||
1632 | if ((m == 0) && (phi_re[i_plus1] != 0)) | ||
1633 | { | ||
1634 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += | ||
1635 | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815))); | ||
1636 | if (sbr->M != 0) | ||
1637 | { | ||
1638 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1639 | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815))); | ||
1640 | } | ||
1641 | } | ||
1642 | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | ||
1643 | { | ||
1644 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1645 | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); | ||
1646 | } | ||
1647 | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) | ||
1648 | { | ||
1649 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1650 | (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815))); | ||
1651 | } | ||
1652 | if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | ||
1653 | { | ||
1654 | if (m > 0) | ||
1655 | { | ||
1656 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1657 | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815))); | ||
1658 | } | ||
1659 | if (m + sbr->kx < 64) | ||
1660 | { | ||
1661 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += | ||
1662 | (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815))); | ||
1663 | } | ||
1664 | } | ||
1665 | #else | ||
1666 | if ((m == 0) && (phi_re[i_plus1] != 0)) | ||
1667 | { | ||
1668 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) += | ||
1669 | (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][0]<<REAL_BITS), FRAC_CONST(0.00815))); | ||
1670 | if (sbr->M != 0) | ||
1671 | { | ||
1672 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1673 | (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][1]<<REAL_BITS), FRAC_CONST(0.00815))); | ||
1674 | } | ||
1675 | } | ||
1676 | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | ||
1677 | { | ||
1678 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1679 | (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815))); | ||
1680 | } | ||
1681 | if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0)) | ||
1682 | { | ||
1683 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1684 | (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][m + 1]<<REAL_BITS), FRAC_CONST(0.00815))); | ||
1685 | } | ||
1686 | if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0)) | ||
1687 | { | ||
1688 | if (m > 0) | ||
1689 | { | ||
1690 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | ||
1691 | (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815))); | ||
1692 | } | ||
1693 | if (m + sbr->kx < 64) | ||
1694 | { | ||
1695 | QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) += | ||
1696 | (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m]<<REAL_BITS), FRAC_CONST(0.00815))); | ||
1697 | } | ||
1698 | } | ||
1699 | #endif | ||
1700 | |||
1701 | if (adj->S_M_boost[l][m] != 0) | ||
1702 | sinusoids++; | ||
1703 | #endif | ||
1704 | } | ||
1705 | } | ||
1706 | |||
1707 | fIndexSine = (fIndexSine + 1) & 3; | ||
1708 | |||
1709 | /* update the ringbuffer index used for filtering G and Q with h_smooth */ | ||
1710 | sbr->GQ_ringbuf_index[ch]++; | ||
1711 | if (sbr->GQ_ringbuf_index[ch] >= 5) | ||
1712 | sbr->GQ_ringbuf_index[ch] = 0; | ||
1713 | } | ||
1714 | } | ||
1715 | |||
1716 | sbr->index_noise_prev[ch] = fIndexNoise; | ||
1717 | sbr->psi_is_prev[ch] = fIndexSine; | ||
1718 | } | ||
1719 | |||
1720 | #endif | ||