Mercurial > mplayer.hg
comparison libfaad2/sbr_hfadj.c @ 10725:e989150f8216
libfaad2 v2.0rc1 imported
author | arpi |
---|---|
date | Sat, 30 Aug 2003 22:30:28 +0000 |
parents | |
children | 3185f64f6350 |
comparison
equal
deleted
inserted
replaced
10724:adf5697b9d83 | 10725:e989150f8216 |
---|---|
1 /* | |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
3 ** Copyright (C) 2003 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: sbr_hfadj.c,v 1.1 2003/07/29 08:20:13 menno Exp $ | |
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 void hf_adjustment(sbr_info *sbr, qmf_t *Xsbr | |
41 #ifdef SBR_LOW_POWER | |
42 ,real_t *deg /* aliasing degree */ | |
43 #endif | |
44 ,uint8_t ch) | |
45 { | |
46 sbr_hfadj_info adj; | |
47 | |
48 memset(&adj, 0, sizeof(sbr_hfadj_info)); | |
49 | |
50 map_noise_data(sbr, &adj, ch); | |
51 map_sinusoids(sbr, &adj, ch); | |
52 | |
53 estimate_current_envelope(sbr, &adj, Xsbr, ch); | |
54 | |
55 calculate_gain(sbr, &adj, ch); | |
56 | |
57 #if 1 | |
58 | |
59 #ifdef SBR_LOW_POWER | |
60 calc_gain_groups(sbr, &adj, deg, ch); | |
61 aliasing_reduction(sbr, &adj, deg, ch); | |
62 #endif | |
63 | |
64 hf_assembly(sbr, &adj, Xsbr, ch); | |
65 | |
66 #endif | |
67 } | |
68 | |
69 static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
70 { | |
71 uint8_t l, i; | |
72 uint32_t m; | |
73 | |
74 for (l = 0; l < sbr->L_E[ch]; l++) | |
75 { | |
76 for (i = 0; i < sbr->N_Q; i++) | |
77 { | |
78 for (m = sbr->f_table_noise[i]; m < sbr->f_table_noise[i+1]; m++) | |
79 { | |
80 uint8_t k; | |
81 | |
82 adj->Q_mapped[m - sbr->kx][l] = 0; | |
83 | |
84 for (k = 0; k < 2; k++) | |
85 { | |
86 if ((sbr->t_E[ch][l] >= sbr->t_Q[ch][k]) && | |
87 (sbr->t_E[ch][l+1] <= sbr->t_Q[ch][k+1])) | |
88 { | |
89 adj->Q_mapped[m - sbr->kx][l] = | |
90 sbr->Q_orig[ch][i][k]; | |
91 } | |
92 } | |
93 } | |
94 } | |
95 } | |
96 } | |
97 | |
98 static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
99 { | |
100 uint8_t l, i, m, k, k1, k2, delta_S, l_i, u_i; | |
101 | |
102 if (sbr->bs_frame_class[ch] == FIXFIX) | |
103 { | |
104 sbr->l_A[ch] = -1; | |
105 } else if (sbr->bs_frame_class[ch] == VARFIX) { | |
106 if (sbr->bs_pointer[ch] > 1) | |
107 sbr->l_A[ch] = -1; | |
108 else | |
109 sbr->l_A[ch] = sbr->bs_pointer[ch] - 1; | |
110 } else { | |
111 if (sbr->bs_pointer[ch] == 0) | |
112 sbr->l_A[ch] = -1; | |
113 else | |
114 sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; | |
115 } | |
116 | |
117 for (l = 0; l < 5; l++) | |
118 { | |
119 for (i = 0; i < 64; i++) | |
120 { | |
121 adj->S_index_mapped[i][l] = 0; | |
122 adj->S_mapped[i][l] = 0; | |
123 } | |
124 } | |
125 | |
126 for (l = 0; l < sbr->L_E[ch]; l++) | |
127 { | |
128 for (i = 0; i < sbr->N_high; i++) | |
129 { | |
130 for (m = sbr->f_table_res[HI_RES][i]; m < sbr->f_table_res[HI_RES][i+1]; m++) | |
131 { | |
132 uint8_t delta_step = 0; | |
133 if ((l >= sbr->l_A[ch]) || ((sbr->bs_add_harmonic_prev[ch][i]) && | |
134 (sbr->bs_add_harmonic_flag_prev[ch]))) | |
135 { | |
136 delta_step = 1; | |
137 } | |
138 | |
139 if (m == (int32_t)((real_t)(sbr->f_table_res[HI_RES][i+1]+sbr->f_table_res[HI_RES][i])/2.)) | |
140 { | |
141 adj->S_index_mapped[m - sbr->kx][l] = | |
142 delta_step * sbr->bs_add_harmonic[ch][i]; | |
143 } else { | |
144 adj->S_index_mapped[m - sbr->kx][l] = 0; | |
145 } | |
146 | |
147 #if 0 | |
148 if (sbr->frame == 95) | |
149 { | |
150 printf("%d %d %d %d %d\n", adj->S_index_mapped[m - sbr->kx][l], | |
151 sbr->bs_add_harmonic[ch][i], sbr->bs_add_harmonic_prev[ch][i], | |
152 l, sbr->l_A[ch]); | |
153 } | |
154 #endif | |
155 } | |
156 } | |
157 } | |
158 | |
159 for (l = 0; l < sbr->L_E[ch]; l++) | |
160 { | |
161 for (i = 0; i < sbr->N_high; i++) | |
162 { | |
163 if (sbr->f[ch][l] == 1) | |
164 { | |
165 k1 = i; | |
166 k2 = i + 1; | |
167 } else { | |
168 for (k1 = 0; k1 < sbr->N_low; k1++) | |
169 { | |
170 if ((sbr->f_table_res[HI_RES][i] >= sbr->f_table_res[LO_RES][k1]) && | |
171 (sbr->f_table_res[HI_RES][i+1] <= sbr->f_table_res[LO_RES][k1+1])) | |
172 { | |
173 break; | |
174 } | |
175 } | |
176 for (k2 = 0; k2 < sbr->N_low; k2++) | |
177 { | |
178 if ((sbr->f_table_res[HI_RES][i+1] >= sbr->f_table_res[LO_RES][k2]) && | |
179 (sbr->f_table_res[HI_RES][i+2] <= sbr->f_table_res[LO_RES][k2+1])) | |
180 { | |
181 break; | |
182 } | |
183 } | |
184 } | |
185 | |
186 l_i = sbr->f_table_res[sbr->f[ch][l]][k1]; | |
187 u_i = sbr->f_table_res[sbr->f[ch][l]][k2]; | |
188 | |
189 delta_S = 0; | |
190 for (k = l_i; k < u_i; k++) | |
191 { | |
192 if (adj->S_index_mapped[k - sbr->kx][l] == 1) | |
193 delta_S = 1; | |
194 } | |
195 | |
196 for (m = l_i; m < u_i; m++) | |
197 { | |
198 adj->S_mapped[m - sbr->kx][l] = delta_S; | |
199 } | |
200 } | |
201 } | |
202 } | |
203 | |
204 static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t *Xsbr, | |
205 uint8_t ch) | |
206 { | |
207 uint8_t m, l, j, k, k_l, k_h, p; | |
208 real_t nrg, div; | |
209 | |
210 if (sbr->bs_interpol_freq == 1) | |
211 { | |
212 for (l = 0; l < sbr->L_E[ch]; l++) | |
213 { | |
214 uint8_t i, l_i, u_i; | |
215 | |
216 l_i = sbr->t_E[ch][l]; | |
217 u_i = sbr->t_E[ch][l+1]; | |
218 | |
219 div = (real_t)(u_i - l_i); | |
220 | |
221 for (m = 0; m < sbr->M; m++) | |
222 { | |
223 nrg = 0; | |
224 | |
225 for (i = l_i + tHFAdj; i < u_i + tHFAdj; i++) | |
226 { | |
227 #ifdef FIXED_POINT | |
228 nrg += ((QMF_RE(Xsbr[(i<<6) + m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[(i<<6) + m + sbr->kx])+(1<<(REAL_BITS-1)))>>REAL_BITS); | |
229 #else | |
230 nrg += MUL(QMF_RE(Xsbr[(i<<6) + m + sbr->kx]), QMF_RE(Xsbr[(i<<6) + m + sbr->kx])) | |
231 #ifndef SBR_LOW_POWER | |
232 + MUL(QMF_IM(Xsbr[(i<<6) + m + sbr->kx]), QMF_IM(Xsbr[(i<<6) + m + sbr->kx])) | |
233 #endif | |
234 ; | |
235 #endif | |
236 } | |
237 | |
238 sbr->E_curr[ch][m][l] = nrg / div; | |
239 #ifdef SBR_LOW_POWER | |
240 #ifdef FIXED_POINT | |
241 sbr->E_curr[ch][m][l] <<= 1; | |
242 #else | |
243 sbr->E_curr[ch][m][l] *= 2; | |
244 #endif | |
245 #endif | |
246 } | |
247 } | |
248 } else { | |
249 for (l = 0; l < sbr->L_E[ch]; l++) | |
250 { | |
251 for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) | |
252 { | |
253 k_l = sbr->f_table_res[sbr->f[ch][l]][p]; | |
254 k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; | |
255 | |
256 for (k = k_l; k < k_h; k++) | |
257 { | |
258 uint8_t i, l_i, u_i; | |
259 nrg = 0.0; | |
260 | |
261 l_i = sbr->t_E[ch][l]; | |
262 u_i = sbr->t_E[ch][l+1]; | |
263 | |
264 div = (real_t)((u_i - l_i)*(k_h - k_l + 1)); | |
265 | |
266 for (i = l_i + tHFAdj; i < u_i + tHFAdj; i++) | |
267 { | |
268 for (j = k_l; j < k_h; j++) | |
269 { | |
270 #ifdef FIXED_POINT | |
271 nrg += ((QMF_RE(Xsbr[(i<<6) + j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[(i<<6) + j])+(1<<(REAL_BITS-1)))>>REAL_BITS); | |
272 #else | |
273 nrg += MUL(QMF_RE(Xsbr[(i<<6) + j]), QMF_RE(Xsbr[(i<<6) + j])) | |
274 #ifndef SBR_LOW_POWER | |
275 + MUL(QMF_IM(Xsbr[(i<<6) + j]), QMF_IM(Xsbr[(i<<6) + j])) | |
276 #endif | |
277 ; | |
278 #endif | |
279 } | |
280 } | |
281 | |
282 sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; | |
283 #ifdef SBR_LOW_POWER | |
284 #ifdef FIXED_POINT | |
285 sbr->E_curr[ch][k - sbr->kx][l] <<= 1; | |
286 #else | |
287 sbr->E_curr[ch][k - sbr->kx][l] *= 2; | |
288 #endif | |
289 #endif | |
290 } | |
291 } | |
292 } | |
293 } | |
294 } | |
295 | |
296 #ifdef FIXED_POINT | |
297 #define step(shift) \ | |
298 if ((0x40000000l >> shift) + root <= value) \ | |
299 { \ | |
300 value -= (0x40000000l >> shift) + root; \ | |
301 root = (root >> 1) | (0x40000000l >> shift); \ | |
302 } else { \ | |
303 root = root >> 1; \ | |
304 } | |
305 | |
306 /* fixed point square root approximation */ | |
307 real_t sbr_sqrt(real_t value) | |
308 { | |
309 real_t root = 0; | |
310 | |
311 step( 0); step( 2); step( 4); step( 6); | |
312 step( 8); step(10); step(12); step(14); | |
313 step(16); step(18); step(20); step(22); | |
314 step(24); step(26); step(28); step(30); | |
315 | |
316 if (root < value) | |
317 ++root; | |
318 | |
319 root <<= (REAL_BITS/2); | |
320 | |
321 return root; | |
322 } | |
323 real_t sbr_sqrt_int(real_t value) | |
324 { | |
325 real_t root = 0; | |
326 | |
327 step( 0); step( 2); step( 4); step( 6); | |
328 step( 8); step(10); step(12); step(14); | |
329 step(16); step(18); step(20); step(22); | |
330 step(24); step(26); step(28); step(30); | |
331 | |
332 if (root < value) | |
333 ++root; | |
334 | |
335 return root; | |
336 } | |
337 #define SBR_SQRT_FIX(A) sbr_sqrt(A) | |
338 #define SBR_SQRT_INT(A) sbr_sqrt_int(A) | |
339 #endif | |
340 | |
341 #ifdef FIXED_POINT | |
342 #define EPS (1) /* smallest number available in fixed point */ | |
343 #else | |
344 #define EPS (1e-12) | |
345 #endif | |
346 | |
347 #ifdef FIXED_POINT | |
348 #define ONE (REAL_CONST(1)>>10) | |
349 #else | |
350 #define ONE (1) | |
351 #endif | |
352 | |
353 | |
354 #ifdef FIXED_POINT | |
355 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
356 { | |
357 uint8_t m, l, k, i; | |
358 | |
359 real_t Q_M_lim[64]; | |
360 real_t G_lim[64]; | |
361 real_t G_boost; | |
362 real_t S_M[64]; | |
363 uint8_t table_map_res_to_m[64]; | |
364 | |
365 | |
366 for (l = 0; l < sbr->L_E[ch]; l++) | |
367 { | |
368 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; | |
369 | |
370 for (i = 0; i < sbr->n[sbr->f[ch][l]]; i++) | |
371 { | |
372 for (m = sbr->f_table_res[sbr->f[ch][l]][i]; m < sbr->f_table_res[sbr->f[ch][l]][i+1]; m++) | |
373 { | |
374 table_map_res_to_m[m - sbr->kx] = i; | |
375 } | |
376 } | |
377 | |
378 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | |
379 { | |
380 real_t G_max; | |
381 real_t den = 0; | |
382 real_t acc1 = 0; | |
383 real_t acc2 = 0; | |
384 | |
385 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
386 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
387 { | |
388 /* E_orig: integer */ | |
389 acc1 += sbr->E_orig[ch][table_map_res_to_m[m]][l]; | |
390 /* E_curr: integer */ | |
391 acc2 += sbr->E_curr[ch][m][l]; | |
392 } | |
393 | |
394 /* G_max: fixed point */ | |
395 if (acc2 == 0) | |
396 { | |
397 G_max = 0xFFF; | |
398 } else { | |
399 G_max = (((int64_t)acc1)<<REAL_BITS) / acc2; | |
400 switch (sbr->bs_limiter_gains) | |
401 { | |
402 case 0: G_max >>= 1; break; | |
403 case 2: G_max <<= 1; break; | |
404 default: break; | |
405 } | |
406 } | |
407 | |
408 //printf("%f %d %d\n", G_max /(float)(1<<REAL_BITS), acc1, acc2); | |
409 | |
410 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
411 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
412 { | |
413 real_t d, Q_M, G; | |
414 real_t div2; | |
415 | |
416 /* Q_mapped: fixed point */ | |
417 /* div2: fixed point COEF */ | |
418 real_t tmp2 = adj->Q_mapped[m][l] << (COEF_BITS-REAL_BITS); | |
419 real_t tmp = COEF_CONST(1) + tmp2; | |
420 if (tmp == 0) | |
421 div2 = COEF_CONST(1); | |
422 else | |
423 div2 = (((int64_t)tmp2 << COEF_BITS)/tmp); | |
424 | |
425 //printf("%f\n", div2 / (float)(1<<COEF_BITS)); | |
426 | |
427 /* Q_M: integer */ | |
428 Q_M = MUL_R_C(sbr->E_orig[ch][table_map_res_to_m[m]][l], div2); | |
429 | |
430 //printf("%d\n", Q_M /* / (float)(1<<REAL_BITS)*/); | |
431 | |
432 if (adj->S_mapped[m][l] == 0) | |
433 { | |
434 real_t tmp, tmp2; | |
435 | |
436 S_M[m] = 0; | |
437 | |
438 /* d: fixed point */ | |
439 tmp2 = adj->Q_mapped[m][l] /* << (COEF_BITS-REAL_BITS)*/; | |
440 tmp = REAL_CONST(1) + delta*tmp2; | |
441 d = (((int64_t)REAL_CONST(1))<<REAL_BITS) / (tmp); | |
442 | |
443 /* G: fixed point */ | |
444 G = (((int64_t)sbr->E_orig[ch][table_map_res_to_m[m]][l])<<REAL_BITS) / (1 + sbr->E_curr[ch][m][l]); | |
445 G = MUL(G, d); | |
446 | |
447 //printf("%f\n", G/(float)(1<<REAL_BITS)); | |
448 | |
449 } else { | |
450 | |
451 real_t div; | |
452 | |
453 /* div: fixed point COEF */ | |
454 real_t tmp = COEF_CONST(1.0) + (adj->Q_mapped[m][l] << (COEF_BITS-REAL_BITS)); | |
455 real_t tmp2 = COEF_CONST(adj->S_mapped[m][l]); | |
456 if (tmp == 0) | |
457 div = COEF_CONST(1); | |
458 else | |
459 div = (((int64_t)tmp2 << COEF_BITS)/tmp); | |
460 | |
461 //printf("%f\n", div/(float)(1<<COEF_BITS)); | |
462 | |
463 /* S_M: integer */ | |
464 S_M[m] = MUL_R_C(sbr->E_orig[ch][table_map_res_to_m[m]][l], div); | |
465 | |
466 //printf("%d\n", S_M[m]); | |
467 | |
468 /* G: fixed_point */ | |
469 if ((ONE + sbr->E_curr[ch][m][l]) == 0) | |
470 G = 0xFFF; // uhm??? | |
471 else { | |
472 real_t tmp = ONE + sbr->E_curr[ch][m][l]; | |
473 /* tmp2: fixed point */ | |
474 real_t tmp2 = (((int64_t)(sbr->E_orig[ch][table_map_res_to_m[m]][l]))<<REAL_BITS)/(tmp); | |
475 G = MUL_R_C(tmp2, div2); | |
476 } | |
477 | |
478 //printf("%f\n", G/(float)(1<<REAL_BITS)); | |
479 } | |
480 | |
481 /* limit the additional noise energy level */ | |
482 /* and apply the limiter */ | |
483 | |
484 /* G_lim: fixed point */ | |
485 /* Q_M_lim: integer */ | |
486 if (G_max > G) | |
487 { | |
488 Q_M_lim[m] = Q_M; | |
489 G_lim[m] = G; | |
490 } else { | |
491 real_t tmp; | |
492 if (G == 0) | |
493 tmp = 0xFFF; | |
494 else | |
495 tmp = SBR_DIV(G_max, G); | |
496 Q_M_lim[m] = MUL(Q_M, tmp); | |
497 G_lim[m] = G_max; | |
498 } | |
499 | |
500 /* E_curr: integer, using MUL() is NOT OK */ | |
501 den += MUL(sbr->E_curr[ch][m][l], G_lim[m]); | |
502 if (adj->S_index_mapped[m][l]) | |
503 den += S_M[m]; | |
504 else if (l != sbr->l_A[ch]) | |
505 den += Q_M_lim[m]; | |
506 } | |
507 | |
508 //printf("%d\n", den); | |
509 | |
510 /* G_boost: fixed point */ | |
511 if ((den + EPS) == 0) | |
512 G_boost = REAL_CONST(2.51188643); | |
513 else | |
514 G_boost = (((int64_t)(acc1 + EPS))<<REAL_BITS)/(den + EPS); | |
515 G_boost = min(G_boost, REAL_CONST(2.51188643) /* 1.584893192 ^ 2 */); | |
516 | |
517 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
518 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
519 { | |
520 /* apply compensation to gain, noise floor sf's and sinusoid levels */ | |
521 #ifndef SBR_LOW_POWER | |
522 /* G_lim_boost: fixed point */ | |
523 adj->G_lim_boost[l][m] = SBR_SQRT_FIX(MUL(G_lim[m], G_boost)); | |
524 #else | |
525 /* sqrt() will be done after the aliasing reduction to save a | |
526 * few multiplies | |
527 */ | |
528 /* G_lim_boost: fixed point */ | |
529 adj->G_lim_boost[l][m] = MUL(G_lim[m], G_boost); | |
530 #endif | |
531 /* Q_M_lim_boost: integer */ | |
532 adj->Q_M_lim_boost[l][m] = SBR_SQRT_INT(MUL(Q_M_lim[m], G_boost)); | |
533 | |
534 /* S_M_boost: integer */ | |
535 if (adj->S_index_mapped[m][l]) | |
536 adj->S_M_boost[l][m] = SBR_SQRT_INT(MUL(S_M[m], G_boost)); | |
537 else | |
538 adj->S_M_boost[l][m] = 0; | |
539 } | |
540 } | |
541 } | |
542 } | |
543 #else | |
544 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
545 { | |
546 static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 }; | |
547 uint8_t m, l, k, i; | |
548 | |
549 real_t Q_M_lim[64]; | |
550 real_t G_lim[64]; | |
551 real_t G_boost; | |
552 real_t S_M[64]; | |
553 uint8_t table_map_res_to_m[64]; | |
554 | |
555 | |
556 for (l = 0; l < sbr->L_E[ch]; l++) | |
557 { | |
558 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; | |
559 | |
560 for (i = 0; i < sbr->n[sbr->f[ch][l]]; i++) | |
561 { | |
562 for (m = sbr->f_table_res[sbr->f[ch][l]][i]; m < sbr->f_table_res[sbr->f[ch][l]][i+1]; m++) | |
563 { | |
564 table_map_res_to_m[m - sbr->kx] = i; | |
565 } | |
566 } | |
567 | |
568 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | |
569 { | |
570 real_t G_max; | |
571 real_t den = 0; | |
572 real_t acc1 = 0; | |
573 real_t acc2 = 0; | |
574 | |
575 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
576 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
577 { | |
578 acc1 += sbr->E_orig[ch][table_map_res_to_m[m]][l]; | |
579 acc2 += sbr->E_curr[ch][m][l]; | |
580 } | |
581 | |
582 G_max = ((EPS + acc1)/(EPS + acc2)) * limGain[sbr->bs_limiter_gains]; | |
583 G_max = min(G_max, 1e10); | |
584 | |
585 //printf("%f %d %d\n", G_max, (int)floor((acc1+EPS)/1024.), (int)floor((acc2+EPS)/1024.)); | |
586 | |
587 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
588 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
589 { | |
590 real_t d, Q_M, G; | |
591 real_t div2; | |
592 | |
593 div2 = adj->Q_mapped[m][l] / (1 + adj->Q_mapped[m][l]); | |
594 | |
595 //printf("%f\n", div2); | |
596 | |
597 Q_M = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div2; | |
598 | |
599 //printf("%f\n", Q_M/1024.); | |
600 | |
601 if (adj->S_mapped[m][l] == 0) | |
602 { | |
603 S_M[m] = 0; | |
604 | |
605 /* fixed point: delta* can stay since it's either 1 or 0 */ | |
606 d = (1 + sbr->E_curr[ch][m][l]) * (1 + delta*adj->Q_mapped[m][l]); | |
607 | |
608 //printf("%f\n", d/1024.); | |
609 | |
610 G = sbr->E_orig[ch][table_map_res_to_m[m]][l] / d; | |
611 | |
612 //printf("%f\n", G); | |
613 | |
614 } else { | |
615 real_t div; | |
616 | |
617 div = adj->S_mapped[m][l] / (1. + adj->Q_mapped[m][l]); | |
618 | |
619 //printf("%f\n", div); | |
620 | |
621 S_M[m] = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div; | |
622 | |
623 //printf("%f\n", S_M[m]/1024.); | |
624 | |
625 G = (sbr->E_orig[ch][table_map_res_to_m[m]][l] / (1. + sbr->E_curr[ch][m][l])) * div2; | |
626 | |
627 //printf("%f\n", G); | |
628 } | |
629 | |
630 /* limit the additional noise energy level */ | |
631 /* and apply the limiter */ | |
632 if (G_max > G) | |
633 { | |
634 Q_M_lim[m] = Q_M; | |
635 G_lim[m] = G; | |
636 } else { | |
637 Q_M_lim[m] = Q_M * G_max / G; | |
638 G_lim[m] = G_max; | |
639 | |
640 //printf("%f\n", Q_M_lim[m] / 1024.); | |
641 } | |
642 | |
643 den += sbr->E_curr[ch][m][l] * G_lim[m]; | |
644 if (adj->S_index_mapped[m][l]) | |
645 den += S_M[m]; | |
646 else if (l != sbr->l_A[ch]) | |
647 den += Q_M_lim[m]; | |
648 } | |
649 | |
650 //printf("%f\n", den/1024.); | |
651 | |
652 G_boost = (acc1 + EPS) / (den + EPS); | |
653 G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */); | |
654 | |
655 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
656 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
657 { | |
658 /* apply compensation to gain, noise floor sf's and sinusoid levels */ | |
659 #ifndef SBR_LOW_POWER | |
660 adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost); | |
661 #else | |
662 /* sqrt() will be done after the aliasing reduction to save a | |
663 * few multiplies | |
664 */ | |
665 adj->G_lim_boost[l][m] = G_lim[m] * G_boost; | |
666 #endif | |
667 adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost); | |
668 | |
669 if (adj->S_index_mapped[m][l]) | |
670 adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost); | |
671 else | |
672 adj->S_M_boost[l][m] = 0; | |
673 } | |
674 } | |
675 } | |
676 } | |
677 #endif | |
678 | |
679 #ifdef SBR_LOW_POWER | |
680 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) | |
681 { | |
682 uint8_t l, k, i; | |
683 uint8_t grouping; | |
684 | |
685 for (l = 0; l < sbr->L_E[ch]; l++) | |
686 { | |
687 i = 0; | |
688 grouping = 0; | |
689 | |
690 for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++) | |
691 { | |
692 if (deg[k + 1] && adj->S_mapped[k-sbr->kx][l] == 0) | |
693 { | |
694 if (grouping == 0) | |
695 { | |
696 sbr->f_group[l][i] = k; | |
697 grouping = 1; | |
698 i++; | |
699 } | |
700 } else { | |
701 if (grouping) | |
702 { | |
703 if (adj->S_mapped[k-sbr->kx][l]) | |
704 sbr->f_group[l][i] = k; | |
705 else | |
706 sbr->f_group[l][i] = k + 1; | |
707 grouping = 0; | |
708 i++; | |
709 } | |
710 } | |
711 } | |
712 | |
713 if (grouping) | |
714 { | |
715 sbr->f_group[l][i] = sbr->kx + sbr->M; | |
716 i++; | |
717 } | |
718 | |
719 sbr->N_G[l] = (uint8_t)(i >> 1); | |
720 } | |
721 } | |
722 | |
723 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) | |
724 { | |
725 uint8_t l, k, m; | |
726 real_t E_total, E_total_est, G_target, acc; | |
727 | |
728 for (l = 0; l < sbr->L_E[ch]; l++) | |
729 { | |
730 for (k = 0; k < sbr->N_G[l]; k++) | |
731 { | |
732 E_total_est = E_total = 0; | |
733 | |
734 for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++) | |
735 { | |
736 /* E_curr: integer */ | |
737 /* G_lim_boost: fixed point */ | |
738 /* E_total_est: integer */ | |
739 /* E_total: integer */ | |
740 E_total_est += sbr->E_curr[ch][m-sbr->kx][l]; | |
741 E_total += MUL(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]); | |
742 } | |
743 | |
744 /* G_target: fixed point */ | |
745 if ((E_total_est + EPS) == 0) | |
746 G_target = 0; | |
747 else | |
748 #ifdef FIXED_POINT | |
749 G_target = (((int64_t)(E_total))<<REAL_BITS)/(E_total_est + EPS); | |
750 #else | |
751 G_target = E_total / (E_total_est + EPS); | |
752 #endif | |
753 acc = 0; | |
754 | |
755 for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) | |
756 { | |
757 real_t alpha; | |
758 | |
759 /* alpha: fixed point */ | |
760 if (m < sbr->kx + sbr->M - 1) | |
761 { | |
762 alpha = max(deg[m], deg[m + 1]); | |
763 } else { | |
764 alpha = deg[m]; | |
765 } | |
766 | |
767 adj->G_lim_boost[l][m-sbr->kx] = MUL(alpha, G_target) + | |
768 MUL((REAL_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]); | |
769 | |
770 /* acc: integer */ | |
771 acc += MUL(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]); | |
772 } | |
773 | |
774 /* acc: fixed point */ | |
775 if (acc + EPS == 0) | |
776 acc = 0; | |
777 else | |
778 #ifdef FIXED_POINT | |
779 acc = (((int64_t)(E_total))<<REAL_BITS)/(acc + EPS); | |
780 #else | |
781 acc = E_total / (acc + EPS); | |
782 #endif | |
783 for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) | |
784 { | |
785 adj->G_lim_boost[l][m-sbr->kx] = MUL(acc, adj->G_lim_boost[l][m-sbr->kx]); | |
786 } | |
787 } | |
788 } | |
789 | |
790 for (l = 0; l < sbr->L_E[ch]; l++) | |
791 { | |
792 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | |
793 { | |
794 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
795 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
796 { | |
797 #ifdef FIXED_POINT | |
798 adj->G_lim_boost[l][m] = SBR_SQRT_FIX(adj->G_lim_boost[l][m]); | |
799 #else | |
800 adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]); | |
801 #endif | |
802 } | |
803 } | |
804 } | |
805 } | |
806 #endif | |
807 | |
808 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, | |
809 qmf_t *Xsbr, uint8_t ch) | |
810 { | |
811 static real_t h_smooth[] = { | |
812 COEF_CONST(0.03183050093751), COEF_CONST(0.11516383427084), | |
813 COEF_CONST(0.21816949906249), COEF_CONST(0.30150283239582), | |
814 COEF_CONST(0.33333333333333) | |
815 }; | |
816 static int8_t phi_re[] = { 1, 0, -1, 0 }; | |
817 static int8_t phi_im[] = { 0, 1, 0, -1 }; | |
818 | |
819 uint8_t m, l, i, n; | |
820 uint16_t fIndexNoise = 0; | |
821 uint8_t fIndexSine = 0; | |
822 uint8_t assembly_reset = 0; | |
823 real_t *temp; | |
824 | |
825 real_t G_filt, Q_filt; | |
826 | |
827 uint8_t h_SL; | |
828 | |
829 | |
830 if (sbr->Reset == 1) | |
831 { | |
832 assembly_reset = 1; | |
833 fIndexNoise = 0; | |
834 } else { | |
835 fIndexNoise = sbr->index_noise_prev[ch]; | |
836 } | |
837 fIndexSine = sbr->psi_is_prev[ch]; | |
838 | |
839 | |
840 for (l = 0; l < sbr->L_E[ch]; l++) | |
841 { | |
842 uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; | |
843 | |
844 #ifdef SBR_LOW_POWER | |
845 h_SL = 0; | |
846 #else | |
847 h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; | |
848 h_SL = (no_noise ? 0 : h_SL); | |
849 #endif | |
850 | |
851 if (assembly_reset) | |
852 { | |
853 for (n = 0; n < 4; n++) | |
854 { | |
855 memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | |
856 memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | |
857 } | |
858 assembly_reset = 0; | |
859 } | |
860 | |
861 | |
862 for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) | |
863 { | |
864 #ifdef SBR_LOW_POWER | |
865 uint8_t i_min1, i_plus1; | |
866 uint8_t sinusoids = 0; | |
867 #endif | |
868 | |
869 memcpy(sbr->G_temp_prev[ch][4], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | |
870 memcpy(sbr->Q_temp_prev[ch][4], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | |
871 | |
872 for (m = 0; m < sbr->M; m++) | |
873 { | |
874 uint8_t j; | |
875 qmf_t psi; | |
876 | |
877 | |
878 G_filt = 0; | |
879 Q_filt = 0; | |
880 j = 0; | |
881 | |
882 if (h_SL != 0) | |
883 { | |
884 for (n = 0; n <= 4; n++) | |
885 { | |
886 G_filt += MUL_R_C(sbr->G_temp_prev[ch][n][m], h_smooth[j]); | |
887 Q_filt += MUL_R_C(sbr->Q_temp_prev[ch][n][m], h_smooth[j]); | |
888 j++; | |
889 } | |
890 } else { | |
891 G_filt = sbr->G_temp_prev[ch][4][m]; | |
892 Q_filt = sbr->Q_temp_prev[ch][4][m]; | |
893 } | |
894 | |
895 Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt; | |
896 | |
897 #if 0 | |
898 if (sbr->frame == 155) | |
899 { | |
900 printf("%f\n", G_filt); | |
901 } | |
902 #endif | |
903 | |
904 /* add noise to the output */ | |
905 fIndexNoise = (fIndexNoise + 1) & 511; | |
906 | |
907 #if 0 | |
908 printf("%d %f\n", Q_filt, RE(V[fIndexNoise])/(float)(1<<COEF_BITS)); | |
909 #endif | |
910 | |
911 /* the smoothed gain values are applied to Xsbr */ | |
912 /* V is defined, not calculated */ | |
913 #ifdef FIXED_POINT | |
914 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx])) | |
915 + MUL_R_C((Q_filt<<REAL_BITS), RE(V[fIndexNoise])); | |
916 #else | |
917 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx])) | |
918 + MUL_R_C(Q_filt, RE(V[fIndexNoise])); | |
919 #endif | |
920 if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) | |
921 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = 16428320; | |
922 #ifndef SBR_LOW_POWER | |
923 QMF_IM(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) = MUL(G_filt, QMF_IM(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx])) | |
924 + MUL_R_C(Q_filt, IM(V[fIndexNoise])); | |
925 #endif | |
926 | |
927 | |
928 if (adj->S_index_mapped[m][l]) | |
929 { | |
930 int8_t rev = ((m + sbr->kx) & 1) ? -1 : 1; | |
931 QMF_RE(psi) = MUL(adj->S_M_boost[l][m], phi_re[fIndexSine]); | |
932 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) += QMF_RE(psi); | |
933 | |
934 #ifndef SBR_LOW_POWER | |
935 QMF_IM(psi) = rev * MUL(adj->S_M_boost[l][m], phi_im[fIndexSine]); | |
936 QMF_IM(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) += QMF_IM(psi); | |
937 #else | |
938 i_min1 = (fIndexSine - 1) & 3; | |
939 i_plus1 = (fIndexSine + 1) & 3; | |
940 | |
941 if (m == 0) | |
942 { | |
943 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx - 1]) -= | |
944 (rev * MUL_R_C(MUL(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815))); | |
945 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -= | |
946 (rev * MUL_R_C(MUL(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815))); | |
947 } | |
948 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16)) | |
949 { | |
950 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -= | |
951 (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815))); | |
952 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -= | |
953 (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815))); | |
954 } | |
955 if ((m == sbr->M - 1) && (sinusoids < 16) && (m + sbr->kx + 1 < 63)) | |
956 { | |
957 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx]) -= | |
958 (rev * MUL_R_C(MUL(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815))); | |
959 QMF_RE(Xsbr[((i + tHFAdj)<<6) + m+sbr->kx + 1]) -= | |
960 (rev * MUL_R_C(MUL(adj->S_M_boost[l][m + 1], phi_re[i_min1]), COEF_CONST(0.00815))); | |
961 } | |
962 | |
963 sinusoids++; | |
964 #endif | |
965 } | |
966 } | |
967 | |
968 fIndexSine = (fIndexSine + 1) & 3; | |
969 | |
970 | |
971 temp = sbr->G_temp_prev[ch][0]; | |
972 for (n = 0; n < 4; n++) | |
973 sbr->G_temp_prev[ch][n] = sbr->G_temp_prev[ch][n+1]; | |
974 sbr->G_temp_prev[ch][4] = temp; | |
975 | |
976 temp = sbr->Q_temp_prev[ch][0]; | |
977 for (n = 0; n < 4; n++) | |
978 sbr->Q_temp_prev[ch][n] = sbr->Q_temp_prev[ch][n+1]; | |
979 sbr->Q_temp_prev[ch][4] = temp; | |
980 } | |
981 } | |
982 | |
983 sbr->index_noise_prev[ch] = fIndexNoise; | |
984 sbr->psi_is_prev[ch] = fIndexSine; | |
985 } | |
986 | |
987 #endif |