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