lirc anc lircc are MPlayer-only, so add LDFLAGS for MPlayer link only.
[mplayer/glamo.git] / libfaad2 / sbr_hfadj.c
blob5d7a67bfbd51ebb5ec486063f47fb466e8d22955
1 /*
2 ** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
3 ** Copyright (C) 2003-2004 M. Bakker, Ahead Software AG, http://www.nero.com
4 **
5 ** This program is free software; you can redistribute it and/or modify
6 ** it under the terms of the GNU General Public License as published by
7 ** the Free Software Foundation; either version 2 of the License, or
8 ** (at your option) any later version.
9 **
10 ** This program is distributed in the hope that it will be useful,
11 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
12 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 ** GNU General Public License for more details.
14 **
15 ** You should have received a copy of the GNU General Public License
16 ** along with this program; if not, write to the Free Software
17 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 ** Any non-GPL usage of this software or parts of this software is strictly
20 ** forbidden.
22 ** Commercial non-GPL licensing of this software is possible.
23 ** For more info contact Ahead Software through Mpeg4AAClicense@nero.com.
25 ** $Id: sbr_hfadj.c,v 1.18 2004/09/04 14:56:28 menno Exp $
26 **/
28 /* High Frequency adjustment */
30 #include "common.h"
31 #include "structs.h"
33 #ifdef SBR_DEC
35 #include "sbr_syntax.h"
36 #include "sbr_hfadj.h"
38 #include "sbr_noise.h"
41 /* static function declarations */
42 static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
43 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
44 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
45 #ifdef SBR_LOW_POWER
46 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
47 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
48 #endif
49 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
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)
58 ALIGN sbr_hfadj_info adj = {{{0}}};
60 if (sbr->bs_frame_class[ch] == FIXFIX)
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];
75 estimate_current_envelope(sbr, &adj, Xsbr, ch);
77 calculate_gain(sbr, &adj, ch);
79 #ifdef SBR_LOW_POWER
80 calc_gain_groups(sbr, &adj, deg, ch);
81 aliasing_reduction(sbr, &adj, deg, ch);
82 #endif
84 hf_assembly(sbr, &adj, Xsbr, ch);
87 static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band)
89 if (sbr->f[ch][l] == HI_RES)
91 /* in case of using f_table_high we just have 1 to 1 mapping
92 * from bs_add_harmonic[l][k]
94 if ((l >= sbr->l_A[ch]) ||
95 (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch]))
97 return sbr->bs_add_harmonic[ch][current_band];
99 } else {
100 uint8_t b, lb, ub;
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)
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);
113 /* check all HI_RES bands in current LO_RES band for sinusoid */
114 for (b = lb; b < ub; b++)
116 if ((l >= sbr->l_A[ch]) ||
117 (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch]))
119 if (sbr->bs_add_harmonic[ch][b] == 1)
120 return 1;
125 return 0;
128 static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
129 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
131 uint8_t m, l, j, k, k_l, k_h, p;
132 real_t nrg, div;
134 if (sbr->bs_interpol_freq == 1)
136 for (l = 0; l < sbr->L_E[ch]; l++)
138 uint8_t i, l_i, u_i;
140 l_i = sbr->t_E[ch][l];
141 u_i = sbr->t_E[ch][l+1];
143 div = (real_t)(u_i - l_i);
145 for (m = 0; m < sbr->M; m++)
147 nrg = 0;
149 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
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
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
164 #endif
167 sbr->E_curr[ch][m][l] = nrg / div;
168 #ifdef SBR_LOW_POWER
169 #ifdef FIXED_POINT
170 sbr->E_curr[ch][m][l] <<= 1;
171 #else
172 sbr->E_curr[ch][m][l] *= 2;
173 #endif
174 #endif
177 } else {
178 for (l = 0; l < sbr->L_E[ch]; l++)
180 for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++)
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];
185 for (k = k_l; k < k_h; k++)
187 uint8_t i, l_i, u_i;
188 nrg = 0;
190 l_i = sbr->t_E[ch][l];
191 u_i = sbr->t_E[ch][l+1];
193 div = (real_t)((u_i - l_i)*(k_h - k_l));
195 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
197 for (j = k_l; j < k_h; j++)
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
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
212 #endif
216 sbr->E_curr[ch][k - sbr->kx][l] = nrg / div;
217 #ifdef SBR_LOW_POWER
218 #ifdef FIXED_POINT
219 sbr->E_curr[ch][k - sbr->kx][l] <<= 1;
220 #else
221 sbr->E_curr[ch][k - sbr->kx][l] *= 2;
222 #endif
223 #endif
230 #ifdef FIXED_POINT
231 #define EPS (1) /* smallest number available in fixed point */
232 #else
233 #define EPS (1e-12)
234 #endif
238 #ifdef FIXED_POINT
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)
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)
267 static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
269 /* check for coupled energy/noise data */
270 if (sbr->bs_coupling == 1)
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;
277 /* E[1] should always be even so shifting is OK */
278 uint8_t E = sbr->E[1][k][l] >> amp1;
280 if (ch == 0)
282 if (E > 12)
284 /* negative */
285 pan = pan_log2_tab[-12 + E];
286 } else {
287 /* positive */
288 pan = pan_log2_tab[12 - E] + ((12 - E)<<REAL_BITS);
290 } else {
291 if (E < 12)
293 /* negative */
294 pan = pan_log2_tab[-E + 12];
295 } else {
296 /* positive */
297 pan = pan_log2_tab[E - 12] + ((E - 12)<<REAL_BITS);
301 /* tmp / pan in log2 */
302 return tmp - pan;
303 } else {
304 uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1;
306 return (6 << REAL_BITS) + (sbr->E[ch][k][l] << (REAL_BITS-amp));
310 static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
312 /* check for coupled energy/noise data */
313 if (sbr->bs_coupling == 1)
315 real_t tmp = (7 << REAL_BITS) - (sbr->Q[0][k][l] << REAL_BITS);
316 real_t pan;
318 uint8_t Q = sbr->Q[1][k][l];
320 if (ch == 0)
322 if (Q > 12)
324 /* negative */
325 pan = pan_log2_tab[-12 + Q];
326 } else {
327 /* positive */
328 pan = pan_log2_tab[12 - Q] + ((12 - Q)<<REAL_BITS);
330 } else {
331 if (Q < 12)
333 /* negative */
334 pan = pan_log2_tab[-Q + 12];
335 } else {
336 /* positive */
337 pan = pan_log2_tab[Q - 12] + ((Q - 12)<<REAL_BITS);
341 /* tmp / pan in log2 */
342 return tmp - pan;
343 } else {
344 return (6 << REAL_BITS) - (sbr->Q[ch][k][l] << REAL_BITS);
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) }
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)
396 static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
398 /* check for coupled energy/noise data */
399 if (sbr->bs_coupling == 1)
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))
404 if (ch == 0)
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)];
410 } else {
411 return 0;
413 } else {
414 if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30)
416 return log_Qplus1[sbr->Q[ch][k][l]];
417 } else {
418 return 0;
423 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
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)
429 uint8_t m, l, k;
431 uint8_t current_t_noise_band = 0;
432 uint8_t S_mapped;
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];
440 for (l = 0; l < sbr->L_E[ch]; l++)
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;
447 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
449 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
451 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
453 current_t_noise_band++;
456 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
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;
466 uint8_t ml1, ml2;
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];
473 /* calculate the accumulated E_orig and E_curr over the limiter band */
474 for (m = ml1; m < ml2; m++)
476 if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
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));
482 current_res_band++;
483 current_res_band_size = 1;
486 acc2 += sbr->E_curr[ch][m][l];
488 acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch));
491 if (acc1 == 0)
492 acc1 = LOG2_MIN_INF;
493 else
494 acc1 = log2_int(acc1);
497 /* calculate the maximum gain */
498 /* ratio of the energy of the original signal and the energy
499 * of the HF generated signal
501 G_max = acc1 - log2_int(acc2) + limGain[sbr->bs_limiter_gains];
502 G_max = min(G_max, limGain[3]);
505 for (m = ml1; m < ml2; m++)
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;
513 /* check if m is on a noise band border */
514 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
516 /* step to next noise band */
517 current_f_noise_band++;
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])
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;
529 /* step to next resolution band */
530 current_res_band2++;
532 /* if we move to a new resolution band, we should check if we are
533 * going to add a sinusoid in this band
535 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
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])
542 /* step to next HI_RES band */
543 current_hi_res_band++;
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
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]))
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];
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);
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);
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)
577 Q_M = E_orig + Q_orig - Q_orig_plus1;
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
583 if (S_index_mapped == 0)
585 S_M[m] = LOG2_MIN_INF; /* -inf */
586 } else {
587 S_M[m] = E_orig - Q_orig_plus1;
589 /* accumulate sinusoid part of the total energy */
590 den += pow2_int(S_M[m]);
594 /* calculate gain */
595 /* ratio of the energy of the original signal and the energy
596 * of the HF generated signal
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))
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;
611 /* limit the additional noise energy level */
612 /* and apply the limiter */
613 if (G_max > G)
615 Q_M_lim[m] = Q_M;
616 G_lim[m] = G;
618 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
620 Q_M_size++;
622 } else {
623 /* G > G_max */
624 Q_M_lim[m] = Q_M + G_max - G;
625 G_lim[m] = G_max;
627 /* accumulate limited Q_M */
628 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
630 den += pow2_int(Q_M_lim[m]);
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]);
640 /* accumulate last range of equal Q_Ms */
641 if (Q_M_size > 0)
643 den += pow2_int(log2_int_tab[Q_M_size] + Q_M);
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) */);
653 for (m = ml1; m < ml2; m++)
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
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);
666 if (S_M[m] != LOG2_MIN_INF)
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;
677 #else
679 //#define LOG2_TEST
681 #ifdef LOG2_TEST
683 #define LOG2_MIN_INF -100000
685 __inline float pow2(float val)
687 return pow(2.0, val);
689 __inline float log2(float val)
691 return log(val)/log(2.0);
694 #define RB 14
696 float QUANTISE2REAL(float val)
698 __int32 ival = (__int32)(val * (1<<RB));
699 return (float)ival / (float)((1<<RB));
702 float QUANTISE2INT(float val)
704 return floor(val);
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
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
734 static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
736 /* check for coupled energy/noise data */
737 if (sbr->bs_coupling == 1)
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;
744 int E = (int)(sbr->E[1][k][l] * amp1);
746 if (ch == 0)
748 if (E > 12)
750 /* negative */
751 pan = QUANTISE2REAL(pan_log2_tab[-12 + E]);
752 } else {
753 /* positive */
754 pan = QUANTISE2REAL(pan_log2_tab[12 - E] + (12 - E));
756 } else {
757 if (E < 12)
759 /* negative */
760 pan = QUANTISE2REAL(pan_log2_tab[-E + 12]);
761 } else {
762 /* positive */
763 pan = QUANTISE2REAL(pan_log2_tab[E - 12] + (E - 12));
767 /* tmp / pan in log2 */
768 return QUANTISE2REAL(tmp - pan);
769 } else {
770 real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5;
772 return QUANTISE2REAL(6.0 + (real_t)sbr->E[ch][k][l] * amp);
776 static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
778 /* check for coupled energy/noise data */
779 if (sbr->bs_coupling == 1)
781 float tmp = QUANTISE2REAL(7.0 - (real_t)sbr->Q[0][k][l]);
782 float pan;
784 int Q = (int)(sbr->Q[1][k][l]);
786 if (ch == 0)
788 if (Q > 12)
790 /* negative */
791 pan = QUANTISE2REAL(pan_log2_tab[-12 + Q]);
792 } else {
793 /* positive */
794 pan = QUANTISE2REAL(pan_log2_tab[12 - Q] + (12 - Q));
796 } else {
797 if (Q < 12)
799 /* negative */
800 pan = QUANTISE2REAL(pan_log2_tab[-Q + 12]);
801 } else {
802 /* positive */
803 pan = QUANTISE2REAL(pan_log2_tab[Q - 12] + (Q - 12));
807 /* tmp / pan in log2 */
808 return QUANTISE2REAL(tmp - pan);
809 } else {
810 return QUANTISE2REAL(6.0 - (real_t)sbr->Q[ch][k][l]);
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) }
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)
862 static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
864 /* check for coupled energy/noise data */
865 if (sbr->bs_coupling == 1)
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))
870 if (ch == 0)
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)]);
876 } else {
877 return 0;
879 } else {
880 if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30)
882 return QUANTISE2REAL(log_Qplus1[sbr->Q[ch][k][l]]);
883 } else {
884 return 0;
889 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
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;
895 uint8_t current_t_noise_band = 0;
896 uint8_t S_mapped;
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];
904 for (l = 0; l < sbr->L_E[ch]; l++)
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;
911 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
913 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
915 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
917 current_t_noise_band++;
920 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
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;
930 uint8_t ml1, ml2;
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];
937 /* calculate the accumulated E_orig and E_curr over the limiter band */
938 for (m = ml1; m < ml2; m++)
940 if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
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)));
946 current_res_band++;
947 current_res_band_size = 1;
950 acc2 += QUANTISE2INT(sbr->E_curr[ch][m][l]/1024.0);
952 acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)));
954 acc1 = QUANTISE2REAL( log2(EPS + acc1) );
957 /* calculate the maximum gain */
958 /* ratio of the energy of the original signal and the energy
959 * of the HF generated signal
961 G_max = acc1 - QUANTISE2REAL(log2(EPS + acc2)) + QUANTISE2REAL(limGain[sbr->bs_limiter_gains]);
962 G_max = min(G_max, QUANTISE2REAL(limGain[3]));
965 for (m = ml1; m < ml2; m++)
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;
973 /* check if m is on a noise band border */
974 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
976 /* step to next noise band */
977 current_f_noise_band++;
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])
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;
989 /* step to next resolution band */
990 current_res_band2++;
992 /* if we move to a new resolution band, we should check if we are
993 * going to add a sinusoid in this band
995 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
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])
1002 /* step to next HI_RES band */
1003 current_hi_res_band++;
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
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]))
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];
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);
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);
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)
1036 Q_M = E_orig + Q_orig - Q_orig_plus1;
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
1042 if (S_index_mapped == 0)
1044 S_M[m] = LOG2_MIN_INF; /* -inf */
1045 } else {
1046 S_M[m] = E_orig - Q_orig_plus1;
1048 /* accumulate sinusoid part of the total energy */
1049 den += pow2(S_M[m]);
1053 /* calculate gain */
1054 /* ratio of the energy of the original signal and the energy
1055 * of the HF generated signal
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))
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;
1070 /* limit the additional noise energy level */
1071 /* and apply the limiter */
1072 if (G_max > G)
1074 Q_M_lim[m] = QUANTISE2REAL(Q_M);
1075 G_lim[m] = QUANTISE2REAL(G);
1077 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
1079 Q_M_size++;
1081 } else {
1082 /* G > G_max */
1083 Q_M_lim[m] = QUANTISE2REAL(Q_M) + G_max - QUANTISE2REAL(G);
1084 G_lim[m] = G_max;
1086 /* accumulate limited Q_M */
1087 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
1089 den += QUANTISE2INT(pow2(Q_M_lim[m]));
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]));
1099 /* accumulate last range of equal Q_Ms */
1100 if (Q_M_size > 0)
1102 den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M));
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) */);
1112 for (m = ml1; m < ml2; m++)
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
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));
1125 if (S_M[m] != LOG2_MIN_INF)
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;
1136 #else
1138 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
1140 static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 };
1141 uint8_t m, l, k;
1143 uint8_t current_t_noise_band = 0;
1144 uint8_t S_mapped;
1146 ALIGN real_t Q_M_lim[MAX_M];
1147 ALIGN real_t G_lim[MAX_M];
1148 ALIGN real_t G_boost;
1149 ALIGN real_t S_M[MAX_M];
1151 for (l = 0; l < sbr->L_E[ch]; l++)
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;
1158 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
1160 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
1162 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
1164 current_t_noise_band++;
1167 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
1169 real_t G_max;
1170 real_t den = 0;
1171 real_t acc1 = 0;
1172 real_t acc2 = 0;
1173 uint8_t current_res_band_size = 0;
1175 uint8_t ml1, ml2;
1177 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
1178 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
1181 /* calculate the accumulated E_orig and E_curr over the limiter band */
1182 for (m = ml1; m < ml2; m++)
1184 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
1186 current_res_band++;
1188 acc1 += sbr->E_orig[ch][current_res_band][l];
1189 acc2 += sbr->E_curr[ch][m][l];
1193 /* calculate the maximum gain */
1194 /* ratio of the energy of the original signal and the energy
1195 * of the HF generated signal
1197 G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains];
1198 G_max = min(G_max, 1e10);
1201 for (m = ml1; m < ml2; m++)
1203 real_t Q_M, G;
1204 real_t Q_div, Q_div2;
1205 uint8_t S_index_mapped;
1208 /* check if m is on a noise band border */
1209 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
1211 /* step to next noise band */
1212 current_f_noise_band++;
1216 /* check if m is on a resolution band border */
1217 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
1219 /* step to next resolution band */
1220 current_res_band2++;
1222 /* if we move to a new resolution band, we should check if we are
1223 * going to add a sinusoid in this band
1225 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
1229 /* check if m is on a HI_RES band border */
1230 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
1232 /* step to next HI_RES band */
1233 current_hi_res_band++;
1237 /* find S_index_mapped
1238 * S_index_mapped can only be 1 for the m in the middle of the
1239 * current HI_RES band
1241 S_index_mapped = 0;
1242 if ((l >= sbr->l_A[ch]) ||
1243 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
1245 /* find the middle subband of the HI_RES frequency band */
1246 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)
1247 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
1251 /* Q_div: [0..1] (1/(1+Q_mapped)) */
1252 Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band];
1255 /* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */
1256 Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band];
1259 /* Q_M only depends on E_orig and Q_div2:
1260 * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on
1261 * a change of current noise band
1263 Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2;
1266 /* S_M only depends on E_orig, Q_div and S_index_mapped:
1267 * S_index_mapped can only be non-zero once per HI_RES band
1269 if (S_index_mapped == 0)
1271 S_M[m] = 0;
1272 } else {
1273 S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div;
1275 /* accumulate sinusoid part of the total energy */
1276 den += S_M[m];
1280 /* calculate gain */
1281 /* ratio of the energy of the original signal and the energy
1282 * of the HF generated signal
1284 G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]);
1285 if ((S_mapped == 0) && (delta == 1))
1286 G *= Q_div;
1287 else if (S_mapped == 1)
1288 G *= Q_div2;
1291 /* limit the additional noise energy level */
1292 /* and apply the limiter */
1293 if (G_max > G)
1295 Q_M_lim[m] = Q_M;
1296 G_lim[m] = G;
1297 } else {
1298 Q_M_lim[m] = Q_M * G_max / G;
1299 G_lim[m] = G_max;
1303 /* accumulate the total energy */
1304 den += sbr->E_curr[ch][m][l] * G_lim[m];
1305 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
1306 den += Q_M_lim[m];
1309 /* G_boost: [0..2.51188643] */
1310 G_boost = (acc1 + EPS) / (den + EPS);
1311 G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */);
1313 for (m = ml1; m < ml2; m++)
1315 /* apply compensation to gain, noise floor sf's and sinusoid levels */
1316 #ifndef SBR_LOW_POWER
1317 adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost);
1318 #else
1319 /* sqrt() will be done after the aliasing reduction to save a
1320 * few multiplies
1322 adj->G_lim_boost[l][m] = G_lim[m] * G_boost;
1323 #endif
1324 adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost);
1326 if (S_M[m] != 0)
1328 adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost);
1329 } else {
1330 adj->S_M_boost[l][m] = 0;
1336 #endif // log2_test
1338 #endif
1340 #ifdef SBR_LOW_POWER
1341 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
1343 uint8_t l, k, i;
1344 uint8_t grouping;
1346 for (l = 0; l < sbr->L_E[ch]; l++)
1348 i = 0;
1349 grouping = 0;
1351 for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++)
1353 if (deg[k + 1] && adj->S_mapped[l][k-sbr->kx] == 0)
1355 if (grouping == 0)
1357 sbr->f_group[l][i] = k;
1358 grouping = 1;
1359 i++;
1361 } else {
1362 if (grouping)
1364 if (adj->S_mapped[l][k-sbr->kx])
1366 sbr->f_group[l][i] = k;
1367 } else {
1368 sbr->f_group[l][i] = k + 1;
1370 grouping = 0;
1371 i++;
1376 if (grouping)
1378 sbr->f_group[l][i] = sbr->kx + sbr->M;
1379 i++;
1382 sbr->N_G[l] = (uint8_t)(i >> 1);
1386 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
1388 uint8_t l, k, m;
1389 real_t E_total, E_total_est, G_target, acc;
1391 for (l = 0; l < sbr->L_E[ch]; l++)
1393 for (k = 0; k < sbr->N_G[l]; k++)
1395 E_total_est = E_total = 0;
1397 for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++)
1399 /* E_curr: integer */
1400 /* G_lim_boost: fixed point */
1401 /* E_total_est: integer */
1402 /* E_total: integer */
1403 E_total_est += sbr->E_curr[ch][m-sbr->kx][l];
1404 #ifdef FIXED_POINT
1405 E_total += MUL_Q2(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]);
1406 #else
1407 E_total += sbr->E_curr[ch][m-sbr->kx][l] * adj->G_lim_boost[l][m-sbr->kx];
1408 #endif
1411 /* G_target: fixed point */
1412 if ((E_total_est + EPS) == 0)
1414 G_target = 0;
1415 } else {
1416 #ifdef FIXED_POINT
1417 G_target = (((int64_t)(E_total))<<Q2_BITS)/(E_total_est + EPS);
1418 #else
1419 G_target = E_total / (E_total_est + EPS);
1420 #endif
1422 acc = 0;
1424 for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
1426 real_t alpha;
1428 /* alpha: (COEF) fixed point */
1429 if (m < sbr->kx + sbr->M - 1)
1431 alpha = max(deg[m], deg[m + 1]);
1432 } else {
1433 alpha = deg[m];
1436 adj->G_lim_boost[l][m-sbr->kx] = MUL_C(alpha, G_target) +
1437 MUL_C((COEF_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]);
1439 /* acc: integer */
1440 #ifdef FIXED_POINT
1441 acc += MUL_Q2(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]);
1442 #else
1443 acc += adj->G_lim_boost[l][m-sbr->kx] * sbr->E_curr[ch][m-sbr->kx][l];
1444 #endif
1447 /* acc: fixed point */
1448 if (acc + EPS == 0)
1450 acc = 0;
1451 } else {
1452 #ifdef FIXED_POINT
1453 acc = (((int64_t)(E_total))<<Q2_BITS)/(acc + EPS);
1454 #else
1455 acc = E_total / (acc + EPS);
1456 #endif
1458 for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
1460 #ifdef FIXED_POINT
1461 adj->G_lim_boost[l][m-sbr->kx] = MUL_Q2(acc, adj->G_lim_boost[l][m-sbr->kx]);
1462 #else
1463 adj->G_lim_boost[l][m-sbr->kx] = acc * adj->G_lim_boost[l][m-sbr->kx];
1464 #endif
1469 for (l = 0; l < sbr->L_E[ch]; l++)
1471 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
1473 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
1474 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
1476 #ifdef FIXED_POINT
1477 adj->G_lim_boost[l][m] = SBR_SQRT_Q2(adj->G_lim_boost[l][m]);
1478 #else
1479 adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]);
1480 #endif
1485 #endif
1487 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
1488 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
1490 static real_t h_smooth[] = {
1491 FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084),
1492 FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582),
1493 FRAC_CONST(0.33333333333333)
1495 static int8_t phi_re[] = { 1, 0, -1, 0 };
1496 static int8_t phi_im[] = { 0, 1, 0, -1 };
1498 uint8_t m, l, i, n;
1499 uint16_t fIndexNoise = 0;
1500 uint8_t fIndexSine = 0;
1501 uint8_t assembly_reset = 0;
1503 real_t G_filt, Q_filt;
1505 uint8_t h_SL;
1508 if (sbr->Reset == 1)
1510 assembly_reset = 1;
1511 fIndexNoise = 0;
1512 } else {
1513 fIndexNoise = sbr->index_noise_prev[ch];
1515 fIndexSine = sbr->psi_is_prev[ch];
1518 for (l = 0; l < sbr->L_E[ch]; l++)
1520 uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0;
1522 #ifdef SBR_LOW_POWER
1523 h_SL = 0;
1524 #else
1525 h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4;
1526 h_SL = (no_noise ? 0 : h_SL);
1527 #endif
1529 if (assembly_reset)
1531 for (n = 0; n < 4; n++)
1533 memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
1534 memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
1536 /* reset ringbuffer index */
1537 sbr->GQ_ringbuf_index[ch] = 4;
1538 assembly_reset = 0;
1541 for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++)
1543 #ifdef SBR_LOW_POWER
1544 uint8_t i_min1, i_plus1;
1545 uint8_t sinusoids = 0;
1546 #endif
1548 /* load new values into ringbuffer */
1549 memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
1550 memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
1552 for (m = 0; m < sbr->M; m++)
1554 qmf_t psi;
1556 G_filt = 0;
1557 Q_filt = 0;
1559 #ifndef SBR_LOW_POWER
1560 if (h_SL != 0)
1562 uint8_t ri = sbr->GQ_ringbuf_index[ch];
1563 for (n = 0; n <= 4; n++)
1565 real_t curr_h_smooth = h_smooth[n];
1566 ri++;
1567 if (ri >= 5)
1568 ri -= 5;
1569 G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth);
1570 Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth);
1572 } else {
1573 #endif
1574 G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
1575 Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
1576 #ifndef SBR_LOW_POWER
1578 #endif
1580 Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt;
1582 /* add noise to the output */
1583 fIndexNoise = (fIndexNoise + 1) & 511;
1585 /* the smoothed gain values are applied to Xsbr */
1586 /* V is defined, not calculated */
1587 #ifndef FIXED_POINT
1588 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])
1589 + MUL_F(Q_filt, RE(V[fIndexNoise]));
1590 #else
1591 //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1592 // + MUL_F(Q_filt, RE(V[fIndexNoise]));
1593 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1594 + MUL_F(Q_filt, RE(V[fIndexNoise]));
1595 #endif
1596 if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42)
1597 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320;
1598 #ifndef SBR_LOW_POWER
1599 #ifndef FIXED_POINT
1600 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])
1601 + MUL_F(Q_filt, IM(V[fIndexNoise]));
1602 #else
1603 //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1604 // + MUL_F(Q_filt, IM(V[fIndexNoise]));
1605 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1606 + MUL_F(Q_filt, IM(V[fIndexNoise]));
1607 #endif
1608 #endif
1611 int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1);
1612 QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine];
1613 #ifdef FIXED_POINT
1614 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_RE(psi) << REAL_BITS);
1615 #else
1616 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi);
1617 #endif
1619 #ifndef SBR_LOW_POWER
1620 QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine];
1621 #ifdef FIXED_POINT
1622 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_IM(psi) << REAL_BITS);
1623 #else
1624 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi);
1625 #endif
1626 #else
1628 i_min1 = (fIndexSine - 1) & 3;
1629 i_plus1 = (fIndexSine + 1) & 3;
1631 #ifndef FIXED_POINT
1632 if ((m == 0) && (phi_re[i_plus1] != 0))
1634 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) +=
1635 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815)));
1636 if (sbr->M != 0)
1638 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1639 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815)));
1642 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1644 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1645 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815)));
1647 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0))
1649 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1650 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815)));
1652 if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1654 if (m > 0)
1656 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1657 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815)));
1659 if (m + sbr->kx < 64)
1661 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) +=
1662 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815)));
1665 #else
1666 if ((m == 0) && (phi_re[i_plus1] != 0))
1668 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) +=
1669 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][0]<<REAL_BITS), FRAC_CONST(0.00815)));
1670 if (sbr->M != 0)
1672 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1673 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][1]<<REAL_BITS), FRAC_CONST(0.00815)));
1676 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1678 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1679 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815)));
1681 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0))
1683 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1684 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][m + 1]<<REAL_BITS), FRAC_CONST(0.00815)));
1686 if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1688 if (m > 0)
1690 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1691 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815)));
1693 if (m + sbr->kx < 64)
1695 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) +=
1696 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m]<<REAL_BITS), FRAC_CONST(0.00815)));
1699 #endif
1701 if (adj->S_M_boost[l][m] != 0)
1702 sinusoids++;
1703 #endif
1707 fIndexSine = (fIndexSine + 1) & 3;
1709 /* update the ringbuffer index used for filtering G and Q with h_smooth */
1710 sbr->GQ_ringbuf_index[ch]++;
1711 if (sbr->GQ_ringbuf_index[ch] >= 5)
1712 sbr->GQ_ringbuf_index[ch] = 0;
1716 sbr->index_noise_prev[ch] = fIndexNoise;
1717 sbr->psi_is_prev[ch] = fIndexSine;
1720 #endif