Mercurial > mplayer.hg
annotate libfaad2/sbr_hfadj.c @ 13153:4fd062533921
fixed the removal of French maintainer of the Doc Nicolas Le Gaillart
author | gpoirier |
---|---|
date | Thu, 26 Aug 2004 13:32:36 +0000 |
parents | d81145997036 |
children | 6d50ef45a058 |
rev | line source |
---|---|
10725 | 1 /* |
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding | |
12527 | 3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com |
10725 | 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 ** | |
12625
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
25 ** Initially modified for use with MPlayer by Arpad Gereöffy on 2003/08/30 |
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
26 ** $Id: sbr_hfadj.c,v 1.3 2004/06/02 22:59:03 diego Exp $ |
d81145997036
More information about modifications to comply more closely with GPL 2a.
diego
parents:
12527
diff
changeset
|
27 ** detailed CVS changelog at http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/ |
10725 | 28 **/ |
29 | |
30 /* High Frequency adjustment */ | |
31 | |
32 #include "common.h" | |
33 #include "structs.h" | |
34 | |
35 #ifdef SBR_DEC | |
36 | |
37 #include "sbr_syntax.h" | |
38 #include "sbr_hfadj.h" | |
39 | |
40 #include "sbr_noise.h" | |
41 | |
12527 | 42 |
43 /* static function delcarations */ | |
44 static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch); | |
45 static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch); | |
46 static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, | |
47 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); | |
48 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch); | |
49 #ifdef SBR_LOW_POWER | |
50 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); | |
51 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch); | |
52 #endif | |
53 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch); | |
54 | |
55 | |
56 void hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64] | |
10725 | 57 #ifdef SBR_LOW_POWER |
58 ,real_t *deg /* aliasing degree */ | |
59 #endif | |
60 ,uint8_t ch) | |
61 { | |
12527 | 62 ALIGN sbr_hfadj_info adj = {{{0}}}; |
10725 | 63 |
64 map_noise_data(sbr, &adj, ch); | |
65 map_sinusoids(sbr, &adj, ch); | |
66 | |
67 estimate_current_envelope(sbr, &adj, Xsbr, ch); | |
68 | |
69 calculate_gain(sbr, &adj, ch); | |
70 | |
71 #ifdef SBR_LOW_POWER | |
72 calc_gain_groups(sbr, &adj, deg, ch); | |
73 aliasing_reduction(sbr, &adj, deg, ch); | |
74 #endif | |
75 | |
76 hf_assembly(sbr, &adj, Xsbr, ch); | |
77 } | |
78 | |
79 static void map_noise_data(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
80 { | |
81 uint8_t l, i; | |
82 uint32_t m; | |
83 | |
84 for (l = 0; l < sbr->L_E[ch]; l++) | |
85 { | |
86 for (i = 0; i < sbr->N_Q; i++) | |
87 { | |
88 for (m = sbr->f_table_noise[i]; m < sbr->f_table_noise[i+1]; m++) | |
89 { | |
90 uint8_t k; | |
91 | |
92 adj->Q_mapped[m - sbr->kx][l] = 0; | |
93 | |
94 for (k = 0; k < 2; k++) | |
95 { | |
96 if ((sbr->t_E[ch][l] >= sbr->t_Q[ch][k]) && | |
97 (sbr->t_E[ch][l+1] <= sbr->t_Q[ch][k+1])) | |
98 { | |
99 adj->Q_mapped[m - sbr->kx][l] = | |
100 sbr->Q_orig[ch][i][k]; | |
101 } | |
102 } | |
103 } | |
104 } | |
105 } | |
106 } | |
107 | |
108 static void map_sinusoids(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
109 { | |
110 uint8_t l, i, m, k, k1, k2, delta_S, l_i, u_i; | |
111 | |
112 if (sbr->bs_frame_class[ch] == FIXFIX) | |
113 { | |
114 sbr->l_A[ch] = -1; | |
115 } else if (sbr->bs_frame_class[ch] == VARFIX) { | |
116 if (sbr->bs_pointer[ch] > 1) | |
117 sbr->l_A[ch] = -1; | |
118 else | |
119 sbr->l_A[ch] = sbr->bs_pointer[ch] - 1; | |
120 } else { | |
121 if (sbr->bs_pointer[ch] == 0) | |
122 sbr->l_A[ch] = -1; | |
123 else | |
124 sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch]; | |
125 } | |
126 | |
127 for (l = 0; l < 5; l++) | |
128 { | |
129 for (i = 0; i < 64; i++) | |
130 { | |
131 adj->S_index_mapped[i][l] = 0; | |
132 adj->S_mapped[i][l] = 0; | |
133 } | |
134 } | |
135 | |
136 for (l = 0; l < sbr->L_E[ch]; l++) | |
137 { | |
138 for (i = 0; i < sbr->N_high; i++) | |
139 { | |
140 for (m = sbr->f_table_res[HI_RES][i]; m < sbr->f_table_res[HI_RES][i+1]; m++) | |
141 { | |
142 uint8_t delta_step = 0; | |
143 if ((l >= sbr->l_A[ch]) || ((sbr->bs_add_harmonic_prev[ch][i]) && | |
144 (sbr->bs_add_harmonic_flag_prev[ch]))) | |
145 { | |
146 delta_step = 1; | |
147 } | |
148 | |
149 if (m == (int32_t)((real_t)(sbr->f_table_res[HI_RES][i+1]+sbr->f_table_res[HI_RES][i])/2.)) | |
150 { | |
151 adj->S_index_mapped[m - sbr->kx][l] = | |
152 delta_step * sbr->bs_add_harmonic[ch][i]; | |
153 } else { | |
154 adj->S_index_mapped[m - sbr->kx][l] = 0; | |
155 } | |
156 } | |
157 } | |
158 } | |
159 | |
160 for (l = 0; l < sbr->L_E[ch]; l++) | |
161 { | |
162 for (i = 0; i < sbr->N_high; i++) | |
163 { | |
164 if (sbr->f[ch][l] == 1) | |
165 { | |
166 k1 = i; | |
167 k2 = i + 1; | |
168 } else { | |
169 for (k1 = 0; k1 < sbr->N_low; k1++) | |
170 { | |
171 if ((sbr->f_table_res[HI_RES][i] >= sbr->f_table_res[LO_RES][k1]) && | |
172 (sbr->f_table_res[HI_RES][i+1] <= sbr->f_table_res[LO_RES][k1+1])) | |
173 { | |
174 break; | |
175 } | |
176 } | |
177 for (k2 = 0; k2 < sbr->N_low; k2++) | |
178 { | |
179 if ((sbr->f_table_res[HI_RES][i+1] >= sbr->f_table_res[LO_RES][k2]) && | |
180 (sbr->f_table_res[HI_RES][i+2] <= sbr->f_table_res[LO_RES][k2+1])) | |
181 { | |
182 break; | |
183 } | |
184 } | |
185 } | |
186 | |
187 l_i = sbr->f_table_res[sbr->f[ch][l]][k1]; | |
188 u_i = sbr->f_table_res[sbr->f[ch][l]][k2]; | |
189 | |
190 delta_S = 0; | |
191 for (k = l_i; k < u_i; k++) | |
192 { | |
193 if (adj->S_index_mapped[k - sbr->kx][l] == 1) | |
194 delta_S = 1; | |
195 } | |
196 | |
197 for (m = l_i; m < u_i; m++) | |
198 { | |
199 adj->S_mapped[m - sbr->kx][l] = delta_S; | |
200 } | |
201 } | |
202 } | |
203 } | |
204 | |
12527 | 205 static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj, |
206 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) | |
10725 | 207 { |
208 uint8_t m, l, j, k, k_l, k_h, p; | |
209 real_t nrg, div; | |
210 | |
211 if (sbr->bs_interpol_freq == 1) | |
212 { | |
213 for (l = 0; l < sbr->L_E[ch]; l++) | |
214 { | |
215 uint8_t i, l_i, u_i; | |
216 | |
217 l_i = sbr->t_E[ch][l]; | |
218 u_i = sbr->t_E[ch][l+1]; | |
219 | |
220 div = (real_t)(u_i - l_i); | |
221 | |
222 for (m = 0; m < sbr->M; m++) | |
223 { | |
224 nrg = 0; | |
225 | |
10989 | 226 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) |
10725 | 227 { |
12527 | 228 nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx])) |
10725 | 229 #ifndef SBR_LOW_POWER |
12527 | 230 + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx])) |
10725 | 231 #endif |
232 ; | |
233 } | |
234 | |
235 sbr->E_curr[ch][m][l] = nrg / div; | |
236 #ifdef SBR_LOW_POWER | |
237 sbr->E_curr[ch][m][l] *= 2; | |
238 #endif | |
239 } | |
240 } | |
241 } else { | |
242 for (l = 0; l < sbr->L_E[ch]; l++) | |
243 { | |
244 for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++) | |
245 { | |
246 k_l = sbr->f_table_res[sbr->f[ch][l]][p]; | |
247 k_h = sbr->f_table_res[sbr->f[ch][l]][p+1]; | |
248 | |
249 for (k = k_l; k < k_h; k++) | |
250 { | |
251 uint8_t i, l_i, u_i; | |
252 nrg = 0.0; | |
253 | |
254 l_i = sbr->t_E[ch][l]; | |
255 u_i = sbr->t_E[ch][l+1]; | |
256 | |
12527 | 257 div = (real_t)((u_i - l_i)*(k_h - k_l)); |
10725 | 258 |
10989 | 259 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++) |
10725 | 260 { |
261 for (j = k_l; j < k_h; j++) | |
262 { | |
12527 | 263 nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j])) |
10725 | 264 #ifndef SBR_LOW_POWER |
12527 | 265 + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j])) |
10725 | 266 #endif |
267 ; | |
268 } | |
269 } | |
270 | |
271 sbr->E_curr[ch][k - sbr->kx][l] = nrg / div; | |
272 #ifdef SBR_LOW_POWER | |
273 sbr->E_curr[ch][k - sbr->kx][l] *= 2; | |
274 #endif | |
275 } | |
276 } | |
277 } | |
278 } | |
279 } | |
280 | |
12527 | 281 |
10989 | 282 #define EPS (1e-12) |
10725 | 283 |
284 #define ONE (1) | |
285 | |
286 | |
287 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch) | |
288 { | |
289 static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 }; | |
290 uint8_t m, l, k, i; | |
291 | |
12527 | 292 ALIGN real_t Q_M_lim[64]; |
293 ALIGN real_t G_lim[64]; | |
294 ALIGN real_t G_boost; | |
295 ALIGN real_t S_M[64]; | |
296 ALIGN uint8_t table_map_res_to_m[64]; | |
10725 | 297 |
298 | |
299 for (l = 0; l < sbr->L_E[ch]; l++) | |
300 { | |
301 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1; | |
302 | |
303 for (i = 0; i < sbr->n[sbr->f[ch][l]]; i++) | |
304 { | |
305 for (m = sbr->f_table_res[sbr->f[ch][l]][i]; m < sbr->f_table_res[sbr->f[ch][l]][i+1]; m++) | |
306 { | |
307 table_map_res_to_m[m - sbr->kx] = i; | |
308 } | |
309 } | |
310 | |
311 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | |
312 { | |
313 real_t G_max; | |
314 real_t den = 0; | |
315 real_t acc1 = 0; | |
316 real_t acc2 = 0; | |
317 | |
318 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
319 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
320 { | |
321 acc1 += sbr->E_orig[ch][table_map_res_to_m[m]][l]; | |
322 acc2 += sbr->E_curr[ch][m][l]; | |
323 } | |
324 | |
325 G_max = ((EPS + acc1)/(EPS + acc2)) * limGain[sbr->bs_limiter_gains]; | |
326 G_max = min(G_max, 1e10); | |
327 | |
328 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
329 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
330 { | |
331 real_t d, Q_M, G; | |
332 real_t div2; | |
333 | |
334 div2 = adj->Q_mapped[m][l] / (1 + adj->Q_mapped[m][l]); | |
335 Q_M = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div2; | |
336 | |
12527 | 337 /* 12-Nov: Changed S_mapped to S_index_mapped */ |
338 if (adj->S_index_mapped[m][l] == 0) | |
10725 | 339 { |
340 S_M[m] = 0; | |
12527 | 341 } else { |
342 real_t div; | |
10725 | 343 |
12527 | 344 div = adj->S_index_mapped[m][l] / (1. + adj->Q_mapped[m][l]); |
345 S_M[m] = sbr->E_orig[ch][table_map_res_to_m[m]][l] * div; | |
346 } | |
347 | |
348 if (adj->S_mapped[m][l] == 0) | |
349 { | |
10725 | 350 d = (1 + sbr->E_curr[ch][m][l]) * (1 + delta*adj->Q_mapped[m][l]); |
351 G = sbr->E_orig[ch][table_map_res_to_m[m]][l] / d; | |
352 } else { | |
353 G = (sbr->E_orig[ch][table_map_res_to_m[m]][l] / (1. + sbr->E_curr[ch][m][l])) * div2; | |
354 } | |
355 | |
356 /* limit the additional noise energy level */ | |
357 /* and apply the limiter */ | |
358 if (G_max > G) | |
359 { | |
360 Q_M_lim[m] = Q_M; | |
361 G_lim[m] = G; | |
362 } else { | |
363 Q_M_lim[m] = Q_M * G_max / G; | |
364 G_lim[m] = G_max; | |
365 } | |
366 | |
367 den += sbr->E_curr[ch][m][l] * G_lim[m]; | |
368 if (adj->S_index_mapped[m][l]) | |
369 den += S_M[m]; | |
370 else if (l != sbr->l_A[ch]) | |
371 den += Q_M_lim[m]; | |
372 } | |
373 | |
374 G_boost = (acc1 + EPS) / (den + EPS); | |
375 G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */); | |
376 | |
377 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
378 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
379 { | |
380 /* apply compensation to gain, noise floor sf's and sinusoid levels */ | |
381 #ifndef SBR_LOW_POWER | |
382 adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost); | |
383 #else | |
384 /* sqrt() will be done after the aliasing reduction to save a | |
385 * few multiplies | |
386 */ | |
387 adj->G_lim_boost[l][m] = G_lim[m] * G_boost; | |
388 #endif | |
389 adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost); | |
390 | |
391 if (adj->S_index_mapped[m][l]) | |
392 adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost); | |
393 else | |
394 adj->S_M_boost[l][m] = 0; | |
395 } | |
396 } | |
397 } | |
398 } | |
399 | |
400 #ifdef SBR_LOW_POWER | |
401 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) | |
402 { | |
403 uint8_t l, k, i; | |
404 uint8_t grouping; | |
405 | |
406 for (l = 0; l < sbr->L_E[ch]; l++) | |
407 { | |
408 i = 0; | |
409 grouping = 0; | |
410 | |
411 for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++) | |
412 { | |
413 if (deg[k + 1] && adj->S_mapped[k-sbr->kx][l] == 0) | |
414 { | |
415 if (grouping == 0) | |
416 { | |
417 sbr->f_group[l][i] = k; | |
418 grouping = 1; | |
419 i++; | |
420 } | |
421 } else { | |
422 if (grouping) | |
423 { | |
424 if (adj->S_mapped[k-sbr->kx][l]) | |
425 sbr->f_group[l][i] = k; | |
426 else | |
427 sbr->f_group[l][i] = k + 1; | |
428 grouping = 0; | |
429 i++; | |
430 } | |
431 } | |
432 } | |
433 | |
434 if (grouping) | |
435 { | |
436 sbr->f_group[l][i] = sbr->kx + sbr->M; | |
437 i++; | |
438 } | |
439 | |
440 sbr->N_G[l] = (uint8_t)(i >> 1); | |
441 } | |
442 } | |
443 | |
444 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch) | |
445 { | |
446 uint8_t l, k, m; | |
447 real_t E_total, E_total_est, G_target, acc; | |
448 | |
449 for (l = 0; l < sbr->L_E[ch]; l++) | |
450 { | |
451 for (k = 0; k < sbr->N_G[l]; k++) | |
452 { | |
453 E_total_est = E_total = 0; | |
454 | |
455 for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++) | |
456 { | |
457 /* E_curr: integer */ | |
458 /* G_lim_boost: fixed point */ | |
459 /* E_total_est: integer */ | |
460 /* E_total: integer */ | |
461 E_total_est += sbr->E_curr[ch][m-sbr->kx][l]; | |
12527 | 462 E_total += MUL_R(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]); |
10725 | 463 } |
464 | |
465 /* G_target: fixed point */ | |
466 if ((E_total_est + EPS) == 0) | |
467 G_target = 0; | |
468 else | |
469 G_target = E_total / (E_total_est + EPS); | |
470 acc = 0; | |
471 | |
472 for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) | |
473 { | |
474 real_t alpha; | |
475 | |
476 /* alpha: fixed point */ | |
477 if (m < sbr->kx + sbr->M - 1) | |
478 { | |
479 alpha = max(deg[m], deg[m + 1]); | |
480 } else { | |
481 alpha = deg[m]; | |
482 } | |
483 | |
12527 | 484 adj->G_lim_boost[l][m-sbr->kx] = MUL_R(alpha, G_target) + |
485 MUL_R((REAL_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]); | |
10725 | 486 |
487 /* acc: integer */ | |
12527 | 488 acc += MUL_R(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]); |
10725 | 489 } |
490 | |
491 /* acc: fixed point */ | |
492 if (acc + EPS == 0) | |
493 acc = 0; | |
494 else | |
495 acc = E_total / (acc + EPS); | |
496 for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++) | |
497 { | |
12527 | 498 adj->G_lim_boost[l][m-sbr->kx] = MUL_R(acc, adj->G_lim_boost[l][m-sbr->kx]); |
10725 | 499 } |
500 } | |
501 } | |
502 | |
503 for (l = 0; l < sbr->L_E[ch]; l++) | |
504 { | |
505 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++) | |
506 { | |
507 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k]; | |
508 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++) | |
509 { | |
510 adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]); | |
511 } | |
512 } | |
513 } | |
514 } | |
515 #endif | |
516 | |
517 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, | |
12527 | 518 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch) |
10725 | 519 { |
520 static real_t h_smooth[] = { | |
521 COEF_CONST(0.03183050093751), COEF_CONST(0.11516383427084), | |
522 COEF_CONST(0.21816949906249), COEF_CONST(0.30150283239582), | |
523 COEF_CONST(0.33333333333333) | |
524 }; | |
525 static int8_t phi_re[] = { 1, 0, -1, 0 }; | |
526 static int8_t phi_im[] = { 0, 1, 0, -1 }; | |
527 | |
528 uint8_t m, l, i, n; | |
529 uint16_t fIndexNoise = 0; | |
530 uint8_t fIndexSine = 0; | |
531 uint8_t assembly_reset = 0; | |
532 real_t *temp; | |
533 | |
534 real_t G_filt, Q_filt; | |
535 | |
536 uint8_t h_SL; | |
537 | |
538 | |
539 if (sbr->Reset == 1) | |
540 { | |
541 assembly_reset = 1; | |
542 fIndexNoise = 0; | |
543 } else { | |
544 fIndexNoise = sbr->index_noise_prev[ch]; | |
545 } | |
546 fIndexSine = sbr->psi_is_prev[ch]; | |
547 | |
548 | |
549 for (l = 0; l < sbr->L_E[ch]; l++) | |
550 { | |
551 uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0; | |
552 | |
553 #ifdef SBR_LOW_POWER | |
554 h_SL = 0; | |
555 #else | |
556 h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4; | |
557 h_SL = (no_noise ? 0 : h_SL); | |
558 #endif | |
559 | |
560 if (assembly_reset) | |
561 { | |
562 for (n = 0; n < 4; n++) | |
563 { | |
564 memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | |
565 memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | |
566 } | |
567 assembly_reset = 0; | |
568 } | |
569 | |
570 for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++) | |
571 { | |
572 #ifdef SBR_LOW_POWER | |
573 uint8_t i_min1, i_plus1; | |
574 uint8_t sinusoids = 0; | |
575 #endif | |
576 | |
577 memcpy(sbr->G_temp_prev[ch][4], adj->G_lim_boost[l], sbr->M*sizeof(real_t)); | |
578 memcpy(sbr->Q_temp_prev[ch][4], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t)); | |
579 | |
580 for (m = 0; m < sbr->M; m++) | |
581 { | |
582 uint8_t j; | |
583 qmf_t psi; | |
584 | |
585 | |
586 G_filt = 0; | |
587 Q_filt = 0; | |
588 j = 0; | |
589 | |
590 if (h_SL != 0) | |
591 { | |
592 for (n = 0; n <= 4; n++) | |
593 { | |
12527 | 594 G_filt += MUL_C(sbr->G_temp_prev[ch][n][m], h_smooth[j]); |
595 Q_filt += MUL_C(sbr->Q_temp_prev[ch][n][m], h_smooth[j]); | |
10725 | 596 j++; |
597 } | |
598 } else { | |
599 G_filt = sbr->G_temp_prev[ch][4][m]; | |
600 Q_filt = sbr->Q_temp_prev[ch][4][m]; | |
601 } | |
602 | |
603 Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt; | |
604 | |
605 /* add noise to the output */ | |
606 fIndexNoise = (fIndexNoise + 1) & 511; | |
607 | |
608 /* the smoothed gain values are applied to Xsbr */ | |
609 /* V is defined, not calculated */ | |
12527 | 610 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) |
611 + MUL_F(Q_filt, RE(V[fIndexNoise])); | |
10725 | 612 if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42) |
12527 | 613 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320; |
10725 | 614 #ifndef SBR_LOW_POWER |
12527 | 615 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])) |
616 + MUL_F(Q_filt, IM(V[fIndexNoise])); | |
10725 | 617 #endif |
618 | |
12527 | 619 //if (adj->S_index_mapped[m][l]) |
10725 | 620 { |
12527 | 621 int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1); |
622 QMF_RE(psi) = MUL_R(adj->S_M_boost[l][m], phi_re[fIndexSine]); | |
623 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi); | |
10725 | 624 |
625 #ifndef SBR_LOW_POWER | |
12527 | 626 QMF_IM(psi) = rev * MUL_R(adj->S_M_boost[l][m], phi_im[fIndexSine]); |
627 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi); | |
10725 | 628 #else |
629 i_min1 = (fIndexSine - 1) & 3; | |
630 i_plus1 = (fIndexSine + 1) & 3; | |
631 | |
632 if (m == 0) | |
633 { | |
12527 | 634 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) -= |
635 (-1*rev * MUL_C(MUL_R(adj->S_M_boost[l][0], phi_re[i_plus1]), COEF_CONST(0.00815))); | |
636 if(m < sbr->M - 1) | |
637 { | |
638 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | |
639 (rev * MUL_C(MUL_R(adj->S_M_boost[l][1], phi_re[i_plus1]), COEF_CONST(0.00815))); | |
640 } | |
10725 | 641 } |
642 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16)) | |
643 { | |
12527 | 644 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= |
645 (rev * MUL_C(MUL_R(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815))); | |
646 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | |
647 (rev * MUL_C(MUL_R(adj->S_M_boost[l][m + 1], phi_re[i_plus1]), COEF_CONST(0.00815))); | |
10725 | 648 } |
12527 | 649 if ((m == sbr->M - 1) && (sinusoids < 16)) |
10725 | 650 { |
12527 | 651 if (m > 0) |
652 { | |
653 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -= | |
654 (rev * MUL_C(MUL_R(adj->S_M_boost[l][m - 1], phi_re[i_min1]), COEF_CONST(0.00815))); | |
655 } | |
656 if (m + sbr->kx < 64) | |
657 { | |
658 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) -= | |
659 (-1*rev * MUL_C(MUL_R(adj->S_M_boost[l][m], phi_re[i_min1]), COEF_CONST(0.00815))); | |
660 } | |
10725 | 661 } |
662 | |
12527 | 663 if (adj->S_M_boost[l][m] != 0) |
664 sinusoids++; | |
10725 | 665 #endif |
666 } | |
667 } | |
668 | |
669 fIndexSine = (fIndexSine + 1) & 3; | |
670 | |
671 | |
672 temp = sbr->G_temp_prev[ch][0]; | |
673 for (n = 0; n < 4; n++) | |
674 sbr->G_temp_prev[ch][n] = sbr->G_temp_prev[ch][n+1]; | |
675 sbr->G_temp_prev[ch][4] = temp; | |
676 | |
677 temp = sbr->Q_temp_prev[ch][0]; | |
678 for (n = 0; n < 4; n++) | |
679 sbr->Q_temp_prev[ch][n] = sbr->Q_temp_prev[ch][n+1]; | |
680 sbr->Q_temp_prev[ch][4] = temp; | |
681 } | |
682 } | |
683 | |
684 sbr->index_noise_prev[ch] = fIndexNoise; | |
685 sbr->psi_is_prev[ch] = fIndexSine; | |
686 } | |
687 | |
688 #endif |