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