Remove all tabs within codec path.
[kugel-rb.git] / apps / codecs / libfaad / sbr_hfadj.c
blob453180d544be23705e8c1bc96e36daa87e92454a
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$
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;
60 memset(&adj,0,sizeof(adj));
61 if (sbr->bs_frame_class[ch] == FIXFIX)
63 sbr->l_A[ch] = -1;
64 } else if (sbr->bs_frame_class[ch] == VARFIX) {
65 if (sbr->bs_pointer[ch] > 1)
66 sbr->l_A[ch] = -1;
67 else
68 sbr->l_A[ch] = sbr->bs_pointer[ch] - 1;
69 } else {
70 if (sbr->bs_pointer[ch] == 0)
71 sbr->l_A[ch] = -1;
72 else
73 sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch];
76 estimate_current_envelope(sbr, &adj, Xsbr, ch);
78 calculate_gain(sbr, &adj, ch);
80 #ifdef SBR_LOW_POWER
81 calc_gain_groups(sbr, &adj, deg, ch);
82 aliasing_reduction(sbr, &adj, deg, ch);
83 #endif
85 hf_assembly(sbr, &adj, Xsbr, ch);
88 static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band)
90 if (sbr->f[ch][l] == HI_RES)
92 /* in case of using f_table_high we just have 1 to 1 mapping
93 * from bs_add_harmonic[l][k]
95 if ((l >= sbr->l_A[ch]) ||
96 (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch]))
98 return sbr->bs_add_harmonic[ch][current_band];
100 } else {
101 uint8_t b, lb, ub;
103 /* in case of f_table_low we check if any of the HI_RES bands
104 * within this LO_RES band has bs_add_harmonic[l][k] turned on
105 * (note that borders in the LO_RES table are also present in
106 * the HI_RES table)
109 /* find first HI_RES band in current LO_RES band */
110 lb = 2*current_band - ((sbr->N_high & 1) ? 1 : 0);
111 /* find first HI_RES band in next LO_RES band */
112 ub = 2*(current_band+1) - ((sbr->N_high & 1) ? 1 : 0);
114 /* check all HI_RES bands in current LO_RES band for sinusoid */
115 for (b = lb; b < ub; b++)
117 if ((l >= sbr->l_A[ch]) ||
118 (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch]))
120 if (sbr->bs_add_harmonic[ch][b] == 1)
121 return 1;
126 return 0;
129 static void estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
130 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
132 uint8_t m, l, j, k, k_l, k_h, p;
133 real_t nrg, div;
135 (void)adj;
136 if (sbr->bs_interpol_freq == 1)
138 for (l = 0; l < sbr->L_E[ch]; l++)
140 uint8_t i, l_i, u_i;
142 l_i = sbr->t_E[ch][l];
143 u_i = sbr->t_E[ch][l+1];
145 div = (real_t)(u_i - l_i);
147 for (m = 0; m < sbr->M; m++)
149 nrg = 0;
151 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
153 #ifdef FIXED_POINT
154 #ifdef SBR_LOW_POWER
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 #else
157 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) +
158 ((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);
159 #endif
160 #else
161 nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx]))
162 #ifndef SBR_LOW_POWER
163 + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx]))
164 #endif
166 #endif
169 sbr->E_curr[ch][m][l] = nrg / div;
170 #ifdef SBR_LOW_POWER
171 #ifdef FIXED_POINT
172 sbr->E_curr[ch][m][l] <<= 1;
173 #else
174 sbr->E_curr[ch][m][l] *= 2;
175 #endif
176 #endif
179 } else {
180 for (l = 0; l < sbr->L_E[ch]; l++)
182 for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++)
184 k_l = sbr->f_table_res[sbr->f[ch][l]][p];
185 k_h = sbr->f_table_res[sbr->f[ch][l]][p+1];
187 for (k = k_l; k < k_h; k++)
189 uint8_t i, l_i, u_i;
190 nrg = 0;
192 l_i = sbr->t_E[ch][l];
193 u_i = sbr->t_E[ch][l+1];
195 div = (real_t)((u_i - l_i)*(k_h - k_l));
197 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
199 for (j = k_l; j < k_h; j++)
201 #ifdef FIXED_POINT
202 #ifdef SBR_LOW_POWER
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 #else
205 nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS) +
206 ((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS);
207 #endif
208 #else
209 nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j]))
210 #ifndef SBR_LOW_POWER
211 + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j]))
212 #endif
214 #endif
218 sbr->E_curr[ch][k - sbr->kx][l] = nrg / div;
219 #ifdef SBR_LOW_POWER
220 #ifdef FIXED_POINT
221 sbr->E_curr[ch][k - sbr->kx][l] <<= 1;
222 #else
223 sbr->E_curr[ch][k - sbr->kx][l] *= 2;
224 #endif
225 #endif
232 #ifdef FIXED_POINT
233 #define EPS (1) /* smallest number available in fixed point */
234 #else
235 #define EPS (1e-12)
236 #endif
240 #ifdef FIXED_POINT
242 /* log2 values of [0..63] */
243 static const real_t log2_int_tab[] = {
244 LOG2_MIN_INF, REAL_CONST(0.000000000000000), REAL_CONST(1.000000000000000), REAL_CONST(1.584962500721156),
245 REAL_CONST(2.000000000000000), REAL_CONST(2.321928094887362), REAL_CONST(2.584962500721156), REAL_CONST(2.807354922057604),
246 REAL_CONST(3.000000000000000), REAL_CONST(3.169925001442313), REAL_CONST(3.321928094887363), REAL_CONST(3.459431618637297),
247 REAL_CONST(3.584962500721156), REAL_CONST(3.700439718141092), REAL_CONST(3.807354922057604), REAL_CONST(3.906890595608519),
248 REAL_CONST(4.000000000000000), REAL_CONST(4.087462841250339), REAL_CONST(4.169925001442312), REAL_CONST(4.247927513443585),
249 REAL_CONST(4.321928094887362), REAL_CONST(4.392317422778761), REAL_CONST(4.459431618637297), REAL_CONST(4.523561956057013),
250 REAL_CONST(4.584962500721156), REAL_CONST(4.643856189774724), REAL_CONST(4.700439718141093), REAL_CONST(4.754887502163468),
251 REAL_CONST(4.807354922057604), REAL_CONST(4.857980995127572), REAL_CONST(4.906890595608519), REAL_CONST(4.954196310386875),
252 REAL_CONST(5.000000000000000), REAL_CONST(5.044394119358453), REAL_CONST(5.087462841250340), REAL_CONST(5.129283016944966),
253 REAL_CONST(5.169925001442312), REAL_CONST(5.209453365628949), REAL_CONST(5.247927513443585), REAL_CONST(5.285402218862248),
254 REAL_CONST(5.321928094887363), REAL_CONST(5.357552004618084), REAL_CONST(5.392317422778761), REAL_CONST(5.426264754702098),
255 REAL_CONST(5.459431618637297), REAL_CONST(5.491853096329675), REAL_CONST(5.523561956057013), REAL_CONST(5.554588851677637),
256 REAL_CONST(5.584962500721156), REAL_CONST(5.614709844115208), REAL_CONST(5.643856189774724), REAL_CONST(5.672425341971495),
257 REAL_CONST(5.700439718141093), REAL_CONST(5.727920454563200), REAL_CONST(5.754887502163469), REAL_CONST(5.781359713524660),
258 REAL_CONST(5.807354922057605), REAL_CONST(5.832890014164742), REAL_CONST(5.857980995127572), REAL_CONST(5.882643049361842),
259 REAL_CONST(5.906890595608518), REAL_CONST(5.930737337562887), REAL_CONST(5.954196310386876), REAL_CONST(5.977279923499916)
262 static const real_t pan_log2_tab[] = {
263 REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339),
264 REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054),
265 REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122),
266 REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667)
269 static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
271 /* check for coupled energy/noise data */
272 if (sbr->bs_coupling == 1)
274 uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1;
275 uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1;
276 real_t tmp = (7 << REAL_BITS) + (sbr->E[0][k][l] << (REAL_BITS-amp0));
277 real_t pan;
279 /* E[1] should always be even so shifting is OK */
280 uint8_t E = sbr->E[1][k][l] >> amp1;
282 if (ch == 0)
284 if (E > 12)
286 /* negative */
287 pan = pan_log2_tab[-12 + E];
288 } else {
289 /* positive */
290 pan = pan_log2_tab[12 - E] + ((12 - E)<<REAL_BITS);
292 } else {
293 if (E < 12)
295 /* negative */
296 pan = pan_log2_tab[-E + 12];
297 } else {
298 /* positive */
299 pan = pan_log2_tab[E - 12] + ((E - 12)<<REAL_BITS);
303 /* tmp / pan in log2 */
304 return tmp - pan;
305 } else {
306 uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1;
308 return (6 << REAL_BITS) + (sbr->E[ch][k][l] << (REAL_BITS-amp));
312 static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
314 /* check for coupled energy/noise data */
315 if (sbr->bs_coupling == 1)
317 real_t tmp = (7 << REAL_BITS) - (sbr->Q[0][k][l] << REAL_BITS);
318 real_t pan;
320 uint8_t Q = sbr->Q[1][k][l];
322 if (ch == 0)
324 if (Q > 12)
326 /* negative */
327 pan = pan_log2_tab[-12 + Q];
328 } else {
329 /* positive */
330 pan = pan_log2_tab[12 - Q] + ((12 - Q)<<REAL_BITS);
332 } else {
333 if (Q < 12)
335 /* negative */
336 pan = pan_log2_tab[-Q + 12];
337 } else {
338 /* positive */
339 pan = pan_log2_tab[Q - 12] + ((Q - 12)<<REAL_BITS);
343 /* tmp / pan in log2 */
344 return tmp - pan;
345 } else {
346 return (6 << REAL_BITS) - (sbr->Q[ch][k][l] << REAL_BITS);
350 static const real_t log_Qplus1_pan[31][13] = {
351 { 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) },
352 { 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) },
353 { 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) },
354 { 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) },
355 { 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) },
356 { 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) },
357 { 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) },
358 { 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) },
359 { 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) },
360 { 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) },
361 { 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) },
362 { 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) },
363 { 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) },
364 { 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) },
365 { 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) },
366 { 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) },
367 { 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) },
368 { 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) },
369 { 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) },
370 { 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) },
371 { 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) },
372 { 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) },
373 { 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) },
374 { 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) },
375 { 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) },
376 { 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) },
377 { 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) },
378 { 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) },
379 { 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) },
380 { 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) },
381 { 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) }
384 static const real_t log_Qplus1[31] = {
385 REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339),
386 REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156),
387 REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362),
388 REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453),
389 REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878),
390 REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247),
391 REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122),
392 REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667),
393 REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551),
394 REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641),
395 REAL_CONST(0.000000000000000)
398 static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
400 /* check for coupled energy/noise data */
401 if (sbr->bs_coupling == 1)
403 if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) &&
404 (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24))
406 if (ch == 0)
408 return log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1];
409 } else {
410 return log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)];
412 } else {
413 return 0;
415 } else {
416 if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30)
418 return log_Qplus1[sbr->Q[ch][k][l]];
419 } else {
420 return 0;
425 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
427 /* log2 values of limiter gains */
428 static real_t limGain[] = {
429 REAL_CONST(-1.0), REAL_CONST(0.0), REAL_CONST(1.0), REAL_CONST(33.219)
431 uint8_t m, l, k;
433 uint8_t current_t_noise_band = 0;
434 uint8_t S_mapped;
436 ALIGN real_t Q_M_lim[MAX_M];
437 ALIGN real_t G_lim[MAX_M];
438 ALIGN real_t G_boost;
439 ALIGN real_t S_M[MAX_M];
442 for (l = 0; l < sbr->L_E[ch]; l++)
444 uint8_t current_f_noise_band = 0;
445 uint8_t current_res_band = 0;
446 uint8_t current_res_band2 = 0;
447 uint8_t current_hi_res_band = 0;
449 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
451 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
453 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
455 current_t_noise_band++;
458 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
460 real_t Q_M = 0;
461 real_t G_max;
462 real_t den = 0;
463 real_t acc1 = 0;
464 real_t acc2 = 0;
465 uint8_t current_res_band_size = 0;
466 uint8_t Q_M_size = 0;
468 uint8_t ml1, ml2;
470 /* bounds of current limiter bands */
471 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
472 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
475 /* calculate the accumulated E_orig and E_curr over the limiter band */
476 for (m = ml1; m < ml2; m++)
478 if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
480 current_res_band_size++;
481 } else {
482 acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch));
484 current_res_band++;
485 current_res_band_size = 1;
488 acc2 += sbr->E_curr[ch][m][l];
490 acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch));
493 if (acc1 == 0)
494 acc1 = LOG2_MIN_INF;
495 else
496 acc1 = log2_int(acc1);
499 /* calculate the maximum gain */
500 /* ratio of the energy of the original signal and the energy
501 * of the HF generated signal
503 G_max = acc1 - log2_int(acc2) + limGain[sbr->bs_limiter_gains];
504 G_max = min(G_max, limGain[3]);
507 for (m = ml1; m < ml2; m++)
509 real_t G;
510 real_t E_curr, E_orig;
511 real_t Q_orig, Q_orig_plus1;
512 uint8_t S_index_mapped;
515 /* check if m is on a noise band border */
516 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
518 /* step to next noise band */
519 current_f_noise_band++;
523 /* check if m is on a resolution band border */
524 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
526 /* accumulate a whole range of equal Q_Ms */
527 if (Q_M_size > 0)
528 den += pow2_int(log2_int_tab[Q_M_size] + Q_M);
529 Q_M_size = 0;
531 /* step to next resolution band */
532 current_res_band2++;
534 /* if we move to a new resolution band, we should check if we are
535 * going to add a sinusoid in this band
537 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
541 /* check if m is on a HI_RES band border */
542 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
544 /* step to next HI_RES band */
545 current_hi_res_band++;
549 /* find S_index_mapped
550 * S_index_mapped can only be 1 for the m in the middle of the
551 * current HI_RES band
553 S_index_mapped = 0;
554 if ((l >= sbr->l_A[ch]) ||
555 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
557 /* find the middle subband of the HI_RES frequency band */
558 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)
559 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
563 /* find bitstream parameters */
564 if (sbr->E_curr[ch][m][l] == 0)
565 E_curr = LOG2_MIN_INF;
566 else
567 E_curr = log2_int(sbr->E_curr[ch][m][l]);
568 E_orig = -REAL_CONST(10) + find_log2_E(sbr, current_res_band2, l, ch);
571 Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch);
572 Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch);
575 /* Q_M only depends on E_orig and Q_div2:
576 * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on
577 * a change of current res band (HI or LO)
579 Q_M = E_orig + Q_orig - Q_orig_plus1;
582 /* S_M only depends on E_orig, Q_div and S_index_mapped:
583 * S_index_mapped can only be non-zero once per HI_RES band
585 if (S_index_mapped == 0)
587 S_M[m] = LOG2_MIN_INF; /* -inf */
588 } else {
589 S_M[m] = E_orig - Q_orig_plus1;
591 /* accumulate sinusoid part of the total energy */
592 den += pow2_int(S_M[m]);
596 /* calculate gain */
597 /* ratio of the energy of the original signal and the energy
598 * of the HF generated signal
600 /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */
601 /* scaled by -10 */
602 G = E_orig - max(-REAL_CONST(10), E_curr);
603 if ((S_mapped == 0) && (delta == 1))
605 /* G = G * 1/(1+Q) */
606 G -= Q_orig_plus1;
607 } else if (S_mapped == 1) {
608 /* G = G * Q/(1+Q) */
609 G += Q_orig - Q_orig_plus1;
613 /* limit the additional noise energy level */
614 /* and apply the limiter */
615 if (G_max > G)
617 Q_M_lim[m] = Q_M;
618 G_lim[m] = G;
620 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
622 Q_M_size++;
624 } else {
625 /* G > G_max */
626 Q_M_lim[m] = Q_M + G_max - G;
627 G_lim[m] = G_max;
629 /* accumulate limited Q_M */
630 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
632 den += pow2_int(Q_M_lim[m]);
637 /* accumulate the total energy */
638 /* E_curr changes for every m so we do need to accumulate every m */
639 den += pow2_int(E_curr + G_lim[m]);
642 /* accumulate last range of equal Q_Ms */
643 if (Q_M_size > 0)
645 den += pow2_int(log2_int_tab[Q_M_size] + Q_M);
649 /* calculate the final gain */
650 /* G_boost: [0..2.51188643] */
651 G_boost = acc1 - log2_int(den /*+ EPS*/);
652 G_boost = min(G_boost, REAL_CONST(1.328771237) /* log2(1.584893192 ^ 2) */);
655 for (m = ml1; m < ml2; m++)
657 /* apply compensation to gain, noise floor sf's and sinusoid levels */
658 #ifndef SBR_LOW_POWER
659 adj->G_lim_boost[l][m] = pow2_fix((G_lim[m] + G_boost) >> 1);
660 #else
661 /* sqrt() will be done after the aliasing reduction to save a
662 * few multiplies
664 adj->G_lim_boost[l][m] = pow2_fix(G_lim[m] + G_boost);
665 #endif
666 adj->Q_M_lim_boost[l][m] = pow2_fix((Q_M_lim[m] + G_boost) >> 1);
668 if (S_M[m] != LOG2_MIN_INF)
670 adj->S_M_boost[l][m] = pow2_int((S_M[m] + G_boost) >> 1);
671 } else {
672 adj->S_M_boost[l][m] = 0;
679 #else
681 //#define LOG2_TEST
683 #ifdef LOG2_TEST
685 #define LOG2_MIN_INF -100000
687 __inline float pow2(float val)
689 return pow(2.0, val);
691 __inline float log2(float val)
693 return log(val)/log(2.0);
696 #define RB 14
698 float QUANTISE2REAL(float val)
700 __int32 ival = (__int32)(val * (1<<RB));
701 return (float)ival / (float)((1<<RB));
704 float QUANTISE2INT(float val)
706 return floor(val);
709 /* log2 values of [0..63] */
710 static const real_t log2_int_tab[] = {
711 LOG2_MIN_INF, 0.000000000000000, 1.000000000000000, 1.584962500721156,
712 2.000000000000000, 2.321928094887362, 2.584962500721156, 2.807354922057604,
713 3.000000000000000, 3.169925001442313, 3.321928094887363, 3.459431618637297,
714 3.584962500721156, 3.700439718141092, 3.807354922057604, 3.906890595608519,
715 4.000000000000000, 4.087462841250339, 4.169925001442312, 4.247927513443585,
716 4.321928094887362, 4.392317422778761, 4.459431618637297, 4.523561956057013,
717 4.584962500721156, 4.643856189774724, 4.700439718141093, 4.754887502163468,
718 4.807354922057604, 4.857980995127572, 4.906890595608519, 4.954196310386875,
719 5.000000000000000, 5.044394119358453, 5.087462841250340, 5.129283016944966,
720 5.169925001442312, 5.209453365628949, 5.247927513443585, 5.285402218862248,
721 5.321928094887363, 5.357552004618084, 5.392317422778761, 5.426264754702098,
722 5.459431618637297, 5.491853096329675, 5.523561956057013, 5.554588851677637,
723 5.584962500721156, 5.614709844115208, 5.643856189774724, 5.672425341971495,
724 5.700439718141093, 5.727920454563200, 5.754887502163469, 5.781359713524660,
725 5.807354922057605, 5.832890014164742, 5.857980995127572, 5.882643049361842,
726 5.906890595608518, 5.930737337562887, 5.954196310386876, 5.977279923499916
729 static const real_t pan_log2_tab[] = {
730 1.000000000000000, 0.584962500721156, 0.321928094887362, 0.169925001442312, 0.087462841250339,
731 0.044394119358453, 0.022367813028455, 0.011227255423254, 0.005624549193878, 0.002815015607054,
732 0.001408194392808, 0.000704269011247, 0.000352177480301, 0.000176099486443, 0.000088052430122,
733 0.000044026886827, 0.000022013611360, 0.000011006847667
736 static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
738 /* check for coupled energy/noise data */
739 if (sbr->bs_coupling == 1)
741 real_t amp0 = (sbr->amp_res[0]) ? 1.0 : 0.5;
742 real_t amp1 = (sbr->amp_res[1]) ? 1.0 : 0.5;
743 float tmp = QUANTISE2REAL(7.0 + (real_t)sbr->E[0][k][l] * amp0);
744 float pan;
746 int E = (int)(sbr->E[1][k][l] * amp1);
748 if (ch == 0)
750 if (E > 12)
752 /* negative */
753 pan = QUANTISE2REAL(pan_log2_tab[-12 + E]);
754 } else {
755 /* positive */
756 pan = QUANTISE2REAL(pan_log2_tab[12 - E] + (12 - E));
758 } else {
759 if (E < 12)
761 /* negative */
762 pan = QUANTISE2REAL(pan_log2_tab[-E + 12]);
763 } else {
764 /* positive */
765 pan = QUANTISE2REAL(pan_log2_tab[E - 12] + (E - 12));
769 /* tmp / pan in log2 */
770 return QUANTISE2REAL(tmp - pan);
771 } else {
772 real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5;
774 return QUANTISE2REAL(6.0 + (real_t)sbr->E[ch][k][l] * amp);
778 static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
780 /* check for coupled energy/noise data */
781 if (sbr->bs_coupling == 1)
783 float tmp = QUANTISE2REAL(7.0 - (real_t)sbr->Q[0][k][l]);
784 float pan;
786 int Q = (int)(sbr->Q[1][k][l]);
788 if (ch == 0)
790 if (Q > 12)
792 /* negative */
793 pan = QUANTISE2REAL(pan_log2_tab[-12 + Q]);
794 } else {
795 /* positive */
796 pan = QUANTISE2REAL(pan_log2_tab[12 - Q] + (12 - Q));
798 } else {
799 if (Q < 12)
801 /* negative */
802 pan = QUANTISE2REAL(pan_log2_tab[-Q + 12]);
803 } else {
804 /* positive */
805 pan = QUANTISE2REAL(pan_log2_tab[Q - 12] + (Q - 12));
809 /* tmp / pan in log2 */
810 return QUANTISE2REAL(tmp - pan);
811 } else {
812 return QUANTISE2REAL(6.0 - (real_t)sbr->Q[ch][k][l]);
816 static const real_t log_Qplus1_pan[31][13] = {
817 { 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) },
818 { 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) },
819 { 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) },
820 { 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) },
821 { 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) },
822 { 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) },
823 { 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) },
824 { 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) },
825 { 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) },
826 { 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) },
827 { 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) },
828 { 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) },
829 { 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) },
830 { 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) },
831 { 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) },
832 { 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) },
833 { 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) },
834 { 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) },
835 { 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) },
836 { 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) },
837 { 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) },
838 { 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) },
839 { 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) },
840 { 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) },
841 { 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) },
842 { 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) },
843 { 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) },
844 { 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) },
845 { 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) },
846 { 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) },
847 { 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) }
850 static const real_t log_Qplus1[31] = {
851 REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339),
852 REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156),
853 REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362),
854 REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453),
855 REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878),
856 REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247),
857 REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122),
858 REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667),
859 REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551),
860 REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641),
861 REAL_CONST(0.000000000000000)
864 static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
866 /* check for coupled energy/noise data */
867 if (sbr->bs_coupling == 1)
869 if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) &&
870 (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24))
872 if (ch == 0)
874 return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]);
875 } else {
876 return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]);
878 } else {
879 return 0;
881 } else {
882 if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30)
884 return QUANTISE2REAL(log_Qplus1[sbr->Q[ch][k][l]]);
885 } else {
886 return 0;
891 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
893 /* log2 values of limiter gains */
894 static real_t limGain[] = { -1.0, 0.0, 1.0, 33.219 };
895 uint8_t m, l, k;
897 uint8_t current_t_noise_band = 0;
898 uint8_t S_mapped;
900 ALIGN real_t Q_M_lim[MAX_M];
901 ALIGN real_t G_lim[MAX_M];
902 ALIGN real_t G_boost;
903 ALIGN real_t S_M[MAX_M];
906 for (l = 0; l < sbr->L_E[ch]; l++)
908 uint8_t current_f_noise_band = 0;
909 uint8_t current_res_band = 0;
910 uint8_t current_res_band2 = 0;
911 uint8_t current_hi_res_band = 0;
913 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
915 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
917 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
919 current_t_noise_band++;
922 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
924 real_t Q_M = 0;
925 real_t G_max;
926 real_t den = 0;
927 real_t acc1 = 0;
928 real_t acc2 = 0;
929 uint8_t current_res_band_size = 0;
930 uint8_t Q_M_size = 0;
932 uint8_t ml1, ml2;
934 /* bounds of current limiter bands */
935 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
936 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
939 /* calculate the accumulated E_orig and E_curr over the limiter band */
940 for (m = ml1; m < ml2; m++)
942 if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
944 current_res_band_size++;
945 } else {
946 acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)));
948 current_res_band++;
949 current_res_band_size = 1;
952 acc2 += QUANTISE2INT(sbr->E_curr[ch][m][l]/1024.0);
954 acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)));
956 acc1 = QUANTISE2REAL( log2(EPS + acc1) );
959 /* calculate the maximum gain */
960 /* ratio of the energy of the original signal and the energy
961 * of the HF generated signal
963 G_max = acc1 - QUANTISE2REAL(log2(EPS + acc2)) + QUANTISE2REAL(limGain[sbr->bs_limiter_gains]);
964 G_max = min(G_max, QUANTISE2REAL(limGain[3]));
967 for (m = ml1; m < ml2; m++)
969 real_t G;
970 real_t E_curr, E_orig;
971 real_t Q_orig, Q_orig_plus1;
972 uint8_t S_index_mapped;
975 /* check if m is on a noise band border */
976 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
978 /* step to next noise band */
979 current_f_noise_band++;
983 /* check if m is on a resolution band border */
984 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
986 /* accumulate a whole range of equal Q_Ms */
987 if (Q_M_size > 0)
988 den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M));
989 Q_M_size = 0;
991 /* step to next resolution band */
992 current_res_band2++;
994 /* if we move to a new resolution band, we should check if we are
995 * going to add a sinusoid in this band
997 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
1001 /* check if m is on a HI_RES band border */
1002 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
1004 /* step to next HI_RES band */
1005 current_hi_res_band++;
1009 /* find S_index_mapped
1010 * S_index_mapped can only be 1 for the m in the middle of the
1011 * current HI_RES band
1013 S_index_mapped = 0;
1014 if ((l >= sbr->l_A[ch]) ||
1015 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
1017 /* find the middle subband of the HI_RES frequency band */
1018 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)
1019 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
1023 /* find bitstream parameters */
1024 if (sbr->E_curr[ch][m][l] == 0)
1025 E_curr = LOG2_MIN_INF;
1026 else
1027 E_curr = -10 + log2(sbr->E_curr[ch][m][l]);
1028 E_orig = -10 + find_log2_E(sbr, current_res_band2, l, ch);
1030 Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch);
1031 Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch);
1034 /* Q_M only depends on E_orig and Q_div2:
1035 * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on
1036 * a change of current res band (HI or LO)
1038 Q_M = E_orig + Q_orig - Q_orig_plus1;
1041 /* S_M only depends on E_orig, Q_div and S_index_mapped:
1042 * S_index_mapped can only be non-zero once per HI_RES band
1044 if (S_index_mapped == 0)
1046 S_M[m] = LOG2_MIN_INF; /* -inf */
1047 } else {
1048 S_M[m] = E_orig - Q_orig_plus1;
1050 /* accumulate sinusoid part of the total energy */
1051 den += pow2(S_M[m]);
1055 /* calculate gain */
1056 /* ratio of the energy of the original signal and the energy
1057 * of the HF generated signal
1059 /* E_curr here is officially E_curr+1 so the log2() of that can never be < 0 */
1060 /* scaled by -10 */
1061 G = E_orig - max(-10, E_curr);
1062 if ((S_mapped == 0) && (delta == 1))
1064 /* G = G * 1/(1+Q) */
1065 G -= Q_orig_plus1;
1066 } else if (S_mapped == 1) {
1067 /* G = G * Q/(1+Q) */
1068 G += Q_orig - Q_orig_plus1;
1072 /* limit the additional noise energy level */
1073 /* and apply the limiter */
1074 if (G_max > G)
1076 Q_M_lim[m] = QUANTISE2REAL(Q_M);
1077 G_lim[m] = QUANTISE2REAL(G);
1079 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
1081 Q_M_size++;
1083 } else {
1084 /* G > G_max */
1085 Q_M_lim[m] = QUANTISE2REAL(Q_M) + G_max - QUANTISE2REAL(G);
1086 G_lim[m] = G_max;
1088 /* accumulate limited Q_M */
1089 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
1091 den += QUANTISE2INT(pow2(Q_M_lim[m]));
1096 /* accumulate the total energy */
1097 /* E_curr changes for every m so we do need to accumulate every m */
1098 den += QUANTISE2INT(pow2(E_curr + G_lim[m]));
1101 /* accumulate last range of equal Q_Ms */
1102 if (Q_M_size > 0)
1104 den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M));
1108 /* calculate the final gain */
1109 /* G_boost: [0..2.51188643] */
1110 G_boost = acc1 - QUANTISE2REAL(log2(den + EPS));
1111 G_boost = min(G_boost, QUANTISE2REAL(1.328771237) /* log2(1.584893192 ^ 2) */);
1114 for (m = ml1; m < ml2; m++)
1116 /* apply compensation to gain, noise floor sf's and sinusoid levels */
1117 #ifndef SBR_LOW_POWER
1118 adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2((G_lim[m] + G_boost) / 2.0));
1119 #else
1120 /* sqrt() will be done after the aliasing reduction to save a
1121 * few multiplies
1123 adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2(G_lim[m] + G_boost));
1124 #endif
1125 adj->Q_M_lim_boost[l][m] = QUANTISE2REAL(pow2((Q_M_lim[m] + 10 + G_boost) / 2.0));
1127 if (S_M[m] != LOG2_MIN_INF)
1129 adj->S_M_boost[l][m] = QUANTISE2REAL(pow2((S_M[m] + 10 + G_boost) / 2.0));
1130 } else {
1131 adj->S_M_boost[l][m] = 0;
1138 #else
1140 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
1142 static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 };
1143 uint8_t m, l, k;
1145 uint8_t current_t_noise_band = 0;
1146 uint8_t S_mapped;
1148 ALIGN real_t Q_M_lim[MAX_M];
1149 ALIGN real_t G_lim[MAX_M];
1150 ALIGN real_t G_boost;
1151 ALIGN real_t S_M[MAX_M];
1153 for (l = 0; l < sbr->L_E[ch]; l++)
1155 uint8_t current_f_noise_band = 0;
1156 uint8_t current_res_band = 0;
1157 uint8_t current_res_band2 = 0;
1158 uint8_t current_hi_res_band = 0;
1160 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
1162 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
1164 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
1166 current_t_noise_band++;
1169 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
1171 real_t G_max;
1172 real_t den = 0;
1173 real_t acc1 = 0;
1174 real_t acc2 = 0;
1175 uint8_t current_res_band_size = 0;
1177 uint8_t ml1, ml2;
1179 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
1180 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
1183 /* calculate the accumulated E_orig and E_curr over the limiter band */
1184 for (m = ml1; m < ml2; m++)
1186 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
1188 current_res_band++;
1190 acc1 += sbr->E_orig[ch][current_res_band][l];
1191 acc2 += sbr->E_curr[ch][m][l];
1195 /* calculate the maximum gain */
1196 /* ratio of the energy of the original signal and the energy
1197 * of the HF generated signal
1199 G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains];
1200 G_max = min(G_max, 1e10);
1203 for (m = ml1; m < ml2; m++)
1205 real_t Q_M, G;
1206 real_t Q_div, Q_div2;
1207 uint8_t S_index_mapped;
1210 /* check if m is on a noise band border */
1211 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
1213 /* step to next noise band */
1214 current_f_noise_band++;
1218 /* check if m is on a resolution band border */
1219 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
1221 /* step to next resolution band */
1222 current_res_band2++;
1224 /* if we move to a new resolution band, we should check if we are
1225 * going to add a sinusoid in this band
1227 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
1231 /* check if m is on a HI_RES band border */
1232 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
1234 /* step to next HI_RES band */
1235 current_hi_res_band++;
1239 /* find S_index_mapped
1240 * S_index_mapped can only be 1 for the m in the middle of the
1241 * current HI_RES band
1243 S_index_mapped = 0;
1244 if ((l >= sbr->l_A[ch]) ||
1245 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
1247 /* find the middle subband of the HI_RES frequency band */
1248 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)
1249 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
1253 /* Q_div: [0..1] (1/(1+Q_mapped)) */
1254 Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band];
1257 /* Q_div2: [0..1] (Q_mapped/(1+Q_mapped)) */
1258 Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band];
1261 /* Q_M only depends on E_orig and Q_div2:
1262 * since N_Q <= N_Low <= N_High we only need to recalculate Q_M on
1263 * a change of current noise band
1265 Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2;
1268 /* S_M only depends on E_orig, Q_div and S_index_mapped:
1269 * S_index_mapped can only be non-zero once per HI_RES band
1271 if (S_index_mapped == 0)
1273 S_M[m] = 0;
1274 } else {
1275 S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div;
1277 /* accumulate sinusoid part of the total energy */
1278 den += S_M[m];
1282 /* calculate gain */
1283 /* ratio of the energy of the original signal and the energy
1284 * of the HF generated signal
1286 G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]);
1287 if ((S_mapped == 0) && (delta == 1))
1288 G *= Q_div;
1289 else if (S_mapped == 1)
1290 G *= Q_div2;
1293 /* limit the additional noise energy level */
1294 /* and apply the limiter */
1295 if (G_max > G)
1297 Q_M_lim[m] = Q_M;
1298 G_lim[m] = G;
1299 } else {
1300 Q_M_lim[m] = Q_M * G_max / G;
1301 G_lim[m] = G_max;
1305 /* accumulate the total energy */
1306 den += sbr->E_curr[ch][m][l] * G_lim[m];
1307 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
1308 den += Q_M_lim[m];
1311 /* G_boost: [0..2.51188643] */
1312 G_boost = (acc1 + EPS) / (den + EPS);
1313 G_boost = min(G_boost, 2.51188643 /* 1.584893192 ^ 2 */);
1315 for (m = ml1; m < ml2; m++)
1317 /* apply compensation to gain, noise floor sf's and sinusoid levels */
1318 #ifndef SBR_LOW_POWER
1319 adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost);
1320 #else
1321 /* sqrt() will be done after the aliasing reduction to save a
1322 * few multiplies
1324 adj->G_lim_boost[l][m] = G_lim[m] * G_boost;
1325 #endif
1326 adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost);
1328 if (S_M[m] != 0)
1330 adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost);
1331 } else {
1332 adj->S_M_boost[l][m] = 0;
1338 #endif // log2_test
1340 #endif
1342 #ifdef SBR_LOW_POWER
1343 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
1345 uint8_t l, k, i;
1346 uint8_t grouping;
1348 for (l = 0; l < sbr->L_E[ch]; l++)
1350 i = 0;
1351 grouping = 0;
1353 for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++)
1355 if (deg[k + 1] && adj->S_mapped[l][k-sbr->kx] == 0)
1357 if (grouping == 0)
1359 sbr->f_group[l][i] = k;
1360 grouping = 1;
1361 i++;
1363 } else {
1364 if (grouping)
1366 if (adj->S_mapped[l][k-sbr->kx])
1368 sbr->f_group[l][i] = k;
1369 } else {
1370 sbr->f_group[l][i] = k + 1;
1372 grouping = 0;
1373 i++;
1378 if (grouping)
1380 sbr->f_group[l][i] = sbr->kx + sbr->M;
1381 i++;
1384 sbr->N_G[l] = (uint8_t)(i >> 1);
1388 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
1390 uint8_t l, k, m;
1391 real_t E_total, E_total_est, G_target, acc;
1393 for (l = 0; l < sbr->L_E[ch]; l++)
1395 for (k = 0; k < sbr->N_G[l]; k++)
1397 E_total_est = E_total = 0;
1399 for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++)
1401 /* E_curr: integer */
1402 /* G_lim_boost: fixed point */
1403 /* E_total_est: integer */
1404 /* E_total: integer */
1405 E_total_est += sbr->E_curr[ch][m-sbr->kx][l];
1406 #ifdef FIXED_POINT
1407 E_total += MUL_Q2(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]);
1408 #else
1409 E_total += sbr->E_curr[ch][m-sbr->kx][l] * adj->G_lim_boost[l][m-sbr->kx];
1410 #endif
1413 /* G_target: fixed point */
1414 if ((E_total_est + EPS) == 0)
1416 G_target = 0;
1417 } else {
1418 #ifdef FIXED_POINT
1419 G_target = (((int64_t)(E_total))<<Q2_BITS)/(E_total_est + EPS);
1420 #else
1421 G_target = E_total / (E_total_est + EPS);
1422 #endif
1424 acc = 0;
1426 for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
1428 real_t alpha;
1430 /* alpha: (COEF) fixed point */
1431 if (m < sbr->kx + sbr->M - 1)
1433 alpha = max(deg[m], deg[m + 1]);
1434 } else {
1435 alpha = deg[m];
1438 adj->G_lim_boost[l][m-sbr->kx] = MUL_C(alpha, G_target) +
1439 MUL_C((COEF_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]);
1441 /* acc: integer */
1442 #ifdef FIXED_POINT
1443 acc += MUL_Q2(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]);
1444 #else
1445 acc += adj->G_lim_boost[l][m-sbr->kx] * sbr->E_curr[ch][m-sbr->kx][l];
1446 #endif
1449 /* acc: fixed point */
1450 if (acc + EPS == 0)
1452 acc = 0;
1453 } else {
1454 #ifdef FIXED_POINT
1455 acc = (((int64_t)(E_total))<<Q2_BITS)/(acc + EPS);
1456 #else
1457 acc = E_total / (acc + EPS);
1458 #endif
1460 for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
1462 #ifdef FIXED_POINT
1463 adj->G_lim_boost[l][m-sbr->kx] = MUL_Q2(acc, adj->G_lim_boost[l][m-sbr->kx]);
1464 #else
1465 adj->G_lim_boost[l][m-sbr->kx] = acc * adj->G_lim_boost[l][m-sbr->kx];
1466 #endif
1471 for (l = 0; l < sbr->L_E[ch]; l++)
1473 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
1475 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
1476 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
1478 #ifdef FIXED_POINT
1479 adj->G_lim_boost[l][m] = SBR_SQRT_Q2(adj->G_lim_boost[l][m]);
1480 #else
1481 adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]);
1482 #endif
1487 #endif
1489 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
1490 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
1492 static real_t h_smooth[] = {
1493 FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084),
1494 FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582),
1495 FRAC_CONST(0.33333333333333)
1497 static int8_t phi_re[] = { 1, 0, -1, 0 };
1498 static int8_t phi_im[] = { 0, 1, 0, -1 };
1500 uint8_t m, l, i, n;
1501 uint16_t fIndexNoise = 0;
1502 uint8_t fIndexSine = 0;
1503 uint8_t assembly_reset = 0;
1505 real_t G_filt, Q_filt;
1507 uint8_t h_SL;
1510 if (sbr->Reset == 1)
1512 assembly_reset = 1;
1513 fIndexNoise = 0;
1514 } else {
1515 fIndexNoise = sbr->index_noise_prev[ch];
1517 fIndexSine = sbr->psi_is_prev[ch];
1520 for (l = 0; l < sbr->L_E[ch]; l++)
1522 uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0;
1524 #ifdef SBR_LOW_POWER
1525 h_SL = 0;
1526 #else
1527 h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4;
1528 h_SL = (no_noise ? 0 : h_SL);
1529 #endif
1531 if (assembly_reset)
1533 for (n = 0; n < 4; n++)
1535 memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
1536 memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
1538 /* reset ringbuffer index */
1539 sbr->GQ_ringbuf_index[ch] = 4;
1540 assembly_reset = 0;
1543 for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++)
1545 #ifdef SBR_LOW_POWER
1546 uint8_t i_min1, i_plus1;
1547 uint8_t sinusoids = 0;
1548 #endif
1550 /* load new values into ringbuffer */
1551 memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
1552 memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
1554 for (m = 0; m < sbr->M; m++)
1556 qmf_t psi;
1558 G_filt = 0;
1559 Q_filt = 0;
1561 #ifndef SBR_LOW_POWER
1562 if (h_SL != 0)
1564 uint8_t ri = sbr->GQ_ringbuf_index[ch];
1565 for (n = 0; n <= 4; n++)
1567 real_t curr_h_smooth = h_smooth[n];
1568 ri++;
1569 if (ri >= 5)
1570 ri -= 5;
1571 G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth);
1572 Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth);
1574 } else {
1575 #endif
1576 G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
1577 Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
1578 #ifndef SBR_LOW_POWER
1580 #endif
1582 Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt;
1584 /* add noise to the output */
1585 fIndexNoise = (fIndexNoise + 1) & 511;
1587 /* the smoothed gain values are applied to Xsbr */
1588 /* V is defined, not calculated */
1589 #ifndef FIXED_POINT
1590 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])
1591 + MUL_F(Q_filt, RE(V[fIndexNoise]));
1592 #else
1593 //QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1594 // + MUL_F(Q_filt, RE(V[fIndexNoise]));
1595 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1596 + MUL_F(Q_filt, RE(V[fIndexNoise]));
1597 #endif
1598 if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42)
1599 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320;
1600 #ifndef SBR_LOW_POWER
1601 #ifndef FIXED_POINT
1602 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])
1603 + MUL_F(Q_filt, IM(V[fIndexNoise]));
1604 #else
1605 //QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_Q2(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1606 // + MUL_F(Q_filt, IM(V[fIndexNoise]));
1607 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
1608 + MUL_F(Q_filt, IM(V[fIndexNoise]));
1609 #endif
1610 #endif
1613 int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1);
1614 QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine];
1615 #ifdef FIXED_POINT
1616 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_RE(psi) << REAL_BITS);
1617 #else
1618 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi);
1619 #endif
1621 #ifndef SBR_LOW_POWER
1622 QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine];
1623 #ifdef FIXED_POINT
1624 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_IM(psi) << REAL_BITS);
1625 #else
1626 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi);
1627 #endif
1628 #else
1630 i_min1 = (fIndexSine - 1) & 3;
1631 i_plus1 = (fIndexSine + 1) & 3;
1633 #ifndef FIXED_POINT
1634 if ((m == 0) && (phi_re[i_plus1] != 0))
1636 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) +=
1637 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815)));
1638 if (sbr->M != 0)
1640 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1641 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815)));
1644 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1646 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1647 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815)));
1649 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0))
1651 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1652 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815)));
1654 if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1656 if (m > 0)
1658 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1659 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815)));
1661 if (m + sbr->kx < 64)
1663 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) +=
1664 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815)));
1667 #else
1668 if ((m == 0) && (phi_re[i_plus1] != 0))
1670 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) +=
1671 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][0]<<REAL_BITS), FRAC_CONST(0.00815)));
1672 if (sbr->M != 0)
1674 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1675 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][1]<<REAL_BITS), FRAC_CONST(0.00815)));
1678 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1680 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1681 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815)));
1683 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0))
1685 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1686 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][m + 1]<<REAL_BITS), FRAC_CONST(0.00815)));
1688 if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
1690 if (m > 0)
1692 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
1693 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815)));
1695 if (m + sbr->kx < 64)
1697 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) +=
1698 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m]<<REAL_BITS), FRAC_CONST(0.00815)));
1701 #endif
1703 if (adj->S_M_boost[l][m] != 0)
1704 sinusoids++;
1705 #endif
1709 fIndexSine = (fIndexSine + 1) & 3;
1711 /* update the ringbuffer index used for filtering G and Q with h_smooth */
1712 sbr->GQ_ringbuf_index[ch]++;
1713 if (sbr->GQ_ringbuf_index[ch] >= 5)
1714 sbr->GQ_ringbuf_index[ch] = 0;
1718 sbr->index_noise_prev[ch] = fIndexNoise;
1719 sbr->psi_is_prev[ch] = fIndexSine;
1722 #endif