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