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