00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "common.h"
00036 #include "structs.h"
00037
00038 #ifdef SBR_DEC
00039
00040 #include "sbr_syntax.h"
00041 #include "sbr_hfadj.h"
00042
00043 #include "sbr_noise.h"
00044
00045
00046
00047 static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
00048 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
00049 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch);
00050 #ifdef SBR_LOW_POWER
00051 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
00052 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch);
00053 #endif
00054 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj, qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch);
00055
00056
00057 uint8_t hf_adjustment(sbr_info *sbr, qmf_t Xsbr[MAX_NTSRHFG][64]
00058 #ifdef SBR_LOW_POWER
00059 ,real_t *deg
00060 #endif
00061 ,uint8_t ch)
00062 {
00063 ALIGN sbr_hfadj_info adj = {{{0}}};
00064 uint8_t ret = 0;
00065
00066 if (sbr->bs_frame_class[ch] == FIXFIX)
00067 {
00068 sbr->l_A[ch] = -1;
00069 } else if (sbr->bs_frame_class[ch] == VARFIX) {
00070 if (sbr->bs_pointer[ch] > 1)
00071 sbr->l_A[ch] = -1;
00072 else
00073 sbr->l_A[ch] = sbr->bs_pointer[ch] - 1;
00074 } else {
00075 if (sbr->bs_pointer[ch] == 0)
00076 sbr->l_A[ch] = -1;
00077 else
00078 sbr->l_A[ch] = sbr->L_E[ch] + 1 - sbr->bs_pointer[ch];
00079 }
00080
00081 ret = estimate_current_envelope(sbr, &adj, Xsbr, ch);
00082 if (ret > 0)
00083 return 1;
00084
00085 calculate_gain(sbr, &adj, ch);
00086
00087 #ifdef SBR_LOW_POWER
00088 calc_gain_groups(sbr, &adj, deg, ch);
00089 aliasing_reduction(sbr, &adj, deg, ch);
00090 #endif
00091
00092 hf_assembly(sbr, &adj, Xsbr, ch);
00093
00094 return 0;
00095 }
00096
00097 static uint8_t get_S_mapped(sbr_info *sbr, uint8_t ch, uint8_t l, uint8_t current_band)
00098 {
00099 if (sbr->f[ch][l] == HI_RES)
00100 {
00101
00102
00103
00104 if ((l >= sbr->l_A[ch]) ||
00105 (sbr->bs_add_harmonic_prev[ch][current_band] && sbr->bs_add_harmonic_flag_prev[ch]))
00106 {
00107 return sbr->bs_add_harmonic[ch][current_band];
00108 }
00109 } else {
00110 uint8_t b, lb, ub;
00111
00112
00113
00114
00115
00116
00117
00118
00119 lb = 2*current_band - ((sbr->N_high & 1) ? 1 : 0);
00120
00121 ub = 2*(current_band+1) - ((sbr->N_high & 1) ? 1 : 0);
00122
00123
00124 for (b = lb; b < ub; b++)
00125 {
00126 if ((l >= sbr->l_A[ch]) ||
00127 (sbr->bs_add_harmonic_prev[ch][b] && sbr->bs_add_harmonic_flag_prev[ch]))
00128 {
00129 if (sbr->bs_add_harmonic[ch][b] == 1)
00130 return 1;
00131 }
00132 }
00133 }
00134
00135 return 0;
00136 }
00137
00138 static uint8_t estimate_current_envelope(sbr_info *sbr, sbr_hfadj_info *adj,
00139 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
00140 {
00141 uint8_t m, l, j, k, k_l, k_h, p;
00142 real_t nrg, div;
00143
00144 if (sbr->bs_interpol_freq == 1)
00145 {
00146 for (l = 0; l < sbr->L_E[ch]; l++)
00147 {
00148 uint8_t i, l_i, u_i;
00149
00150 l_i = sbr->t_E[ch][l];
00151 u_i = sbr->t_E[ch][l+1];
00152
00153 div = (real_t)(u_i - l_i);
00154
00155 if (div == 0)
00156 div = 1;
00157
00158 for (m = 0; m < sbr->M; m++)
00159 {
00160 nrg = 0;
00161
00162 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
00163 {
00164 #ifdef FIXED_POINT
00165 #ifdef SBR_LOW_POWER
00166 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);
00167 #else
00168 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) +
00169 ((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);
00170 #endif
00171 #else
00172 nrg += MUL_R(QMF_RE(Xsbr[i][m + sbr->kx]), QMF_RE(Xsbr[i][m + sbr->kx]))
00173 #ifndef SBR_LOW_POWER
00174 + MUL_R(QMF_IM(Xsbr[i][m + sbr->kx]), QMF_IM(Xsbr[i][m + sbr->kx]))
00175 #endif
00176 ;
00177 #endif
00178 }
00179
00180 sbr->E_curr[ch][m][l] = nrg / div;
00181 #ifdef SBR_LOW_POWER
00182 #ifdef FIXED_POINT
00183 sbr->E_curr[ch][m][l] <<= 1;
00184 #else
00185 sbr->E_curr[ch][m][l] *= 2;
00186 #endif
00187 #endif
00188 }
00189 }
00190 } else {
00191 for (l = 0; l < sbr->L_E[ch]; l++)
00192 {
00193 for (p = 0; p < sbr->n[sbr->f[ch][l]]; p++)
00194 {
00195 k_l = sbr->f_table_res[sbr->f[ch][l]][p];
00196 k_h = sbr->f_table_res[sbr->f[ch][l]][p+1];
00197
00198 for (k = k_l; k < k_h; k++)
00199 {
00200 uint8_t i, l_i, u_i;
00201 nrg = 0;
00202
00203 l_i = sbr->t_E[ch][l];
00204 u_i = sbr->t_E[ch][l+1];
00205
00206 div = (real_t)((u_i - l_i)*(k_h - k_l));
00207
00208 if (div == 0)
00209 div = 1;
00210
00211 for (i = l_i + sbr->tHFAdj; i < u_i + sbr->tHFAdj; i++)
00212 {
00213 for (j = k_l; j < k_h; j++)
00214 {
00215 #ifdef FIXED_POINT
00216 #ifdef SBR_LOW_POWER
00217 nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS);
00218 #else
00219 nrg += ((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_RE(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS) +
00220 ((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS)*((QMF_IM(Xsbr[i][j])+(1<<(REAL_BITS-1)))>>REAL_BITS);
00221 #endif
00222 #else
00223 nrg += MUL_R(QMF_RE(Xsbr[i][j]), QMF_RE(Xsbr[i][j]))
00224 #ifndef SBR_LOW_POWER
00225 + MUL_R(QMF_IM(Xsbr[i][j]), QMF_IM(Xsbr[i][j]))
00226 #endif
00227 ;
00228 #endif
00229 }
00230 }
00231
00232 sbr->E_curr[ch][k - sbr->kx][l] = nrg / div;
00233 #ifdef SBR_LOW_POWER
00234 #ifdef FIXED_POINT
00235 sbr->E_curr[ch][k - sbr->kx][l] <<= 1;
00236 #else
00237 sbr->E_curr[ch][k - sbr->kx][l] *= 2;
00238 #endif
00239 #endif
00240 }
00241 }
00242 }
00243 }
00244
00245 return 0;
00246 }
00247
00248 #ifdef FIXED_POINT
00249 #define EPS (1)
00250 #else
00251 #define EPS (1e-12)
00252 #endif
00253
00254
00255
00256 #ifdef FIXED_POINT
00257
00258
00259 static const real_t log2_int_tab[] = {
00260 LOG2_MIN_INF, REAL_CONST(0.000000000000000), REAL_CONST(1.000000000000000), REAL_CONST(1.584962500721156),
00261 REAL_CONST(2.000000000000000), REAL_CONST(2.321928094887362), REAL_CONST(2.584962500721156), REAL_CONST(2.807354922057604),
00262 REAL_CONST(3.000000000000000), REAL_CONST(3.169925001442313), REAL_CONST(3.321928094887363), REAL_CONST(3.459431618637297),
00263 REAL_CONST(3.584962500721156), REAL_CONST(3.700439718141092), REAL_CONST(3.807354922057604), REAL_CONST(3.906890595608519),
00264 REAL_CONST(4.000000000000000), REAL_CONST(4.087462841250339), REAL_CONST(4.169925001442312), REAL_CONST(4.247927513443585),
00265 REAL_CONST(4.321928094887362), REAL_CONST(4.392317422778761), REAL_CONST(4.459431618637297), REAL_CONST(4.523561956057013),
00266 REAL_CONST(4.584962500721156), REAL_CONST(4.643856189774724), REAL_CONST(4.700439718141093), REAL_CONST(4.754887502163468),
00267 REAL_CONST(4.807354922057604), REAL_CONST(4.857980995127572), REAL_CONST(4.906890595608519), REAL_CONST(4.954196310386875),
00268 REAL_CONST(5.000000000000000), REAL_CONST(5.044394119358453), REAL_CONST(5.087462841250340), REAL_CONST(5.129283016944966),
00269 REAL_CONST(5.169925001442312), REAL_CONST(5.209453365628949), REAL_CONST(5.247927513443585), REAL_CONST(5.285402218862248),
00270 REAL_CONST(5.321928094887363), REAL_CONST(5.357552004618084), REAL_CONST(5.392317422778761), REAL_CONST(5.426264754702098),
00271 REAL_CONST(5.459431618637297), REAL_CONST(5.491853096329675), REAL_CONST(5.523561956057013), REAL_CONST(5.554588851677637),
00272 REAL_CONST(5.584962500721156), REAL_CONST(5.614709844115208), REAL_CONST(5.643856189774724), REAL_CONST(5.672425341971495),
00273 REAL_CONST(5.700439718141093), REAL_CONST(5.727920454563200), REAL_CONST(5.754887502163469), REAL_CONST(5.781359713524660),
00274 REAL_CONST(5.807354922057605), REAL_CONST(5.832890014164742), REAL_CONST(5.857980995127572), REAL_CONST(5.882643049361842),
00275 REAL_CONST(5.906890595608518), REAL_CONST(5.930737337562887), REAL_CONST(5.954196310386876), REAL_CONST(5.977279923499916)
00276 };
00277
00278 static const real_t pan_log2_tab[] = {
00279 REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362), REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339),
00280 REAL_CONST(0.044394119358453), REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878), REAL_CONST(0.002815015607054),
00281 REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247), REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122),
00282 REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667)
00283 };
00284
00285 static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
00286 {
00287
00288 if (sbr->bs_coupling == 1)
00289 {
00290 uint8_t amp0 = (sbr->amp_res[0]) ? 0 : 1;
00291 uint8_t amp1 = (sbr->amp_res[1]) ? 0 : 1;
00292 real_t tmp = (7 << REAL_BITS) + (sbr->E[0][k][l] << (REAL_BITS-amp0));
00293 real_t pan;
00294
00295
00296 uint8_t E = sbr->E[1][k][l] >> amp1;
00297
00298 if (ch == 0)
00299 {
00300 if (E > 12)
00301 {
00302
00303 pan = pan_log2_tab[-12 + E];
00304 } else {
00305
00306 pan = pan_log2_tab[12 - E] + ((12 - E)<<REAL_BITS);
00307 }
00308 } else {
00309 if (E < 12)
00310 {
00311
00312 pan = pan_log2_tab[-E + 12];
00313 } else {
00314
00315 pan = pan_log2_tab[E - 12] + ((E - 12)<<REAL_BITS);
00316 }
00317 }
00318
00319
00320 return tmp - pan;
00321 } else {
00322 uint8_t amp = (sbr->amp_res[ch]) ? 0 : 1;
00323
00324 return (6 << REAL_BITS) + (sbr->E[ch][k][l] << (REAL_BITS-amp));
00325 }
00326 }
00327
00328 static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
00329 {
00330
00331 if (sbr->bs_coupling == 1)
00332 {
00333 real_t tmp = (7 << REAL_BITS) - (sbr->Q[0][k][l] << REAL_BITS);
00334 real_t pan;
00335
00336 uint8_t Q = sbr->Q[1][k][l];
00337
00338 if (ch == 0)
00339 {
00340 if (Q > 12)
00341 {
00342
00343 pan = pan_log2_tab[-12 + Q];
00344 } else {
00345
00346 pan = pan_log2_tab[12 - Q] + ((12 - Q)<<REAL_BITS);
00347 }
00348 } else {
00349 if (Q < 12)
00350 {
00351
00352 pan = pan_log2_tab[-Q + 12];
00353 } else {
00354
00355 pan = pan_log2_tab[Q - 12] + ((Q - 12)<<REAL_BITS);
00356 }
00357 }
00358
00359
00360 return tmp - pan;
00361 } else {
00362 return (6 << REAL_BITS) - (sbr->Q[ch][k][l] << REAL_BITS);
00363 }
00364 }
00365
00366 static const real_t log_Qplus1_pan[31][13] = {
00367 { 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) },
00368 { 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) },
00369 { 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) },
00370 { 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) },
00371 { 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) },
00372 { 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) },
00373 { 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) },
00374 { 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) },
00375 { 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) },
00376 { 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) },
00377 { 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) },
00378 { 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) },
00379 { 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) },
00380 { 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) },
00381 { 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) },
00382 { 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) },
00383 { 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) },
00384 { 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) },
00385 { 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) },
00386 { 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) },
00387 { 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) },
00388 { 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) },
00389 { 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) },
00390 { 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) },
00391 { 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) },
00392 { 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) },
00393 { 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) },
00394 { 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) },
00395 { 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) },
00396 { 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) },
00397 { 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) }
00398 };
00399
00400 static const real_t log_Qplus1[31] = {
00401 REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339),
00402 REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156),
00403 REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362),
00404 REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453),
00405 REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878),
00406 REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247),
00407 REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122),
00408 REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667),
00409 REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551),
00410 REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641),
00411 REAL_CONST(0.000000000000000)
00412 };
00413
00414 static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
00415 {
00416
00417 if (sbr->bs_coupling == 1)
00418 {
00419 if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) &&
00420 (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24))
00421 {
00422 if (ch == 0)
00423 {
00424 return log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1];
00425 } else {
00426 return log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)];
00427 }
00428 } else {
00429 return 0;
00430 }
00431 } else {
00432 if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30)
00433 {
00434 return log_Qplus1[sbr->Q[ch][k][l]];
00435 } else {
00436 return 0;
00437 }
00438 }
00439 }
00440
00441 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
00442 {
00443
00444 static real_t limGain[] = {
00445 REAL_CONST(-1.0), REAL_CONST(0.0), REAL_CONST(1.0), REAL_CONST(33.219)
00446 };
00447 uint8_t m, l, k;
00448
00449 uint8_t current_t_noise_band = 0;
00450 uint8_t S_mapped;
00451
00452 ALIGN real_t Q_M_lim[MAX_M];
00453 ALIGN real_t G_lim[MAX_M];
00454 ALIGN real_t G_boost;
00455 ALIGN real_t S_M[MAX_M];
00456
00457
00458 for (l = 0; l < sbr->L_E[ch]; l++)
00459 {
00460 uint8_t current_f_noise_band = 0;
00461 uint8_t current_res_band = 0;
00462 uint8_t current_res_band2 = 0;
00463 uint8_t current_hi_res_band = 0;
00464
00465 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
00466
00467 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
00468
00469 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
00470 {
00471 current_t_noise_band++;
00472 }
00473
00474 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
00475 {
00476 real_t Q_M = 0;
00477 real_t G_max;
00478 real_t den = 0;
00479 real_t acc1 = 0;
00480 real_t acc2 = 0;
00481 uint8_t current_res_band_size = 0;
00482 uint8_t Q_M_size = 0;
00483
00484 uint8_t ml1, ml2;
00485
00486
00487 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
00488 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
00489
00490
00491
00492 for (m = ml1; m < ml2; m++)
00493 {
00494 if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
00495 {
00496 current_res_band_size++;
00497 } else {
00498 acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch));
00499
00500 current_res_band++;
00501 current_res_band_size = 1;
00502 }
00503
00504 acc2 += sbr->E_curr[ch][m][l];
00505 }
00506 acc1 += pow2_int(-REAL_CONST(10) + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch));
00507
00508
00509 if (acc1 == 0)
00510 acc1 = LOG2_MIN_INF;
00511 else
00512 acc1 = log2_int(acc1);
00513
00514
00515
00516
00517
00518
00519 G_max = acc1 - log2_int(acc2) + limGain[sbr->bs_limiter_gains];
00520 G_max = min(G_max, limGain[3]);
00521
00522
00523 for (m = ml1; m < ml2; m++)
00524 {
00525 real_t G;
00526 real_t E_curr, E_orig;
00527 real_t Q_orig, Q_orig_plus1;
00528 uint8_t S_index_mapped;
00529
00530
00531
00532 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
00533 {
00534
00535 current_f_noise_band++;
00536 }
00537
00538
00539
00540 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
00541 {
00542
00543 if (Q_M_size > 0)
00544 den += pow2_int(log2_int_tab[Q_M_size] + Q_M);
00545 Q_M_size = 0;
00546
00547
00548 current_res_band2++;
00549
00550
00551
00552
00553 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
00554 }
00555
00556
00557
00558 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
00559 {
00560
00561 current_hi_res_band++;
00562 }
00563
00564
00565
00566
00567
00568
00569 S_index_mapped = 0;
00570 if ((l >= sbr->l_A[ch]) ||
00571 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
00572 {
00573
00574 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)
00575 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
00576 }
00577
00578
00579
00580 if (sbr->E_curr[ch][m][l] == 0)
00581 E_curr = LOG2_MIN_INF;
00582 else
00583 E_curr = log2_int(sbr->E_curr[ch][m][l]);
00584 E_orig = -REAL_CONST(10) + find_log2_E(sbr, current_res_band2, l, ch);
00585
00586
00587 Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch);
00588 Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch);
00589
00590
00591
00592
00593
00594
00595 Q_M = E_orig + Q_orig - Q_orig_plus1;
00596
00597
00598
00599
00600
00601 if (S_index_mapped == 0)
00602 {
00603 S_M[m] = LOG2_MIN_INF;
00604 } else {
00605 S_M[m] = E_orig - Q_orig_plus1;
00606
00607
00608 den += pow2_int(S_M[m]);
00609 }
00610
00611
00612
00613
00614
00615
00616
00617
00618 G = E_orig - max(-REAL_CONST(10), E_curr);
00619 if ((S_mapped == 0) && (delta == 1))
00620 {
00621
00622 G -= Q_orig_plus1;
00623 } else if (S_mapped == 1) {
00624
00625 G += Q_orig - Q_orig_plus1;
00626 }
00627
00628
00629
00630
00631 if (G_max > G)
00632 {
00633 Q_M_lim[m] = Q_M;
00634 G_lim[m] = G;
00635
00636 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
00637 {
00638 Q_M_size++;
00639 }
00640 } else {
00641
00642 Q_M_lim[m] = Q_M + G_max - G;
00643 G_lim[m] = G_max;
00644
00645
00646 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
00647 {
00648 den += pow2_int(Q_M_lim[m]);
00649 }
00650 }
00651
00652
00653
00654
00655 den += pow2_int(E_curr + G_lim[m]);
00656 }
00657
00658
00659 if (Q_M_size > 0)
00660 {
00661 den += pow2_int(log2_int_tab[Q_M_size] + Q_M);
00662 }
00663
00664
00665
00666
00667 G_boost = acc1 - log2_int(den );
00668 G_boost = min(G_boost, REAL_CONST(1.328771237) );
00669
00670
00671 for (m = ml1; m < ml2; m++)
00672 {
00673
00674 #ifndef SBR_LOW_POWER
00675 adj->G_lim_boost[l][m] = pow2_fix((G_lim[m] + G_boost) >> 1);
00676 #else
00677
00678
00679
00680 adj->G_lim_boost[l][m] = pow2_fix(G_lim[m] + G_boost);
00681 #endif
00682 adj->Q_M_lim_boost[l][m] = pow2_fix((Q_M_lim[m] + G_boost) >> 1);
00683
00684 if (S_M[m] != LOG2_MIN_INF)
00685 {
00686 adj->S_M_boost[l][m] = pow2_int((S_M[m] + G_boost) >> 1);
00687 } else {
00688 adj->S_M_boost[l][m] = 0;
00689 }
00690 }
00691 }
00692 }
00693 }
00694
00695 #else
00696
00697
00698
00699 #ifdef LOG2_TEST
00700
00701 #define LOG2_MIN_INF -100000
00702
00703 __inline float pow2(float val)
00704 {
00705 return pow(2.0, val);
00706 }
00707 __inline float log2(float val)
00708 {
00709 return log(val)/log(2.0);
00710 }
00711
00712 #define RB 14
00713
00714 float QUANTISE2REAL(float val)
00715 {
00716 __int32 ival = (__int32)(val * (1<<RB));
00717 return (float)ival / (float)((1<<RB));
00718 }
00719
00720 float QUANTISE2INT(float val)
00721 {
00722 return floor(val);
00723 }
00724
00725
00726 static const real_t log2_int_tab[] = {
00727 LOG2_MIN_INF, 0.000000000000000, 1.000000000000000, 1.584962500721156,
00728 2.000000000000000, 2.321928094887362, 2.584962500721156, 2.807354922057604,
00729 3.000000000000000, 3.169925001442313, 3.321928094887363, 3.459431618637297,
00730 3.584962500721156, 3.700439718141092, 3.807354922057604, 3.906890595608519,
00731 4.000000000000000, 4.087462841250339, 4.169925001442312, 4.247927513443585,
00732 4.321928094887362, 4.392317422778761, 4.459431618637297, 4.523561956057013,
00733 4.584962500721156, 4.643856189774724, 4.700439718141093, 4.754887502163468,
00734 4.807354922057604, 4.857980995127572, 4.906890595608519, 4.954196310386875,
00735 5.000000000000000, 5.044394119358453, 5.087462841250340, 5.129283016944966,
00736 5.169925001442312, 5.209453365628949, 5.247927513443585, 5.285402218862248,
00737 5.321928094887363, 5.357552004618084, 5.392317422778761, 5.426264754702098,
00738 5.459431618637297, 5.491853096329675, 5.523561956057013, 5.554588851677637,
00739 5.584962500721156, 5.614709844115208, 5.643856189774724, 5.672425341971495,
00740 5.700439718141093, 5.727920454563200, 5.754887502163469, 5.781359713524660,
00741 5.807354922057605, 5.832890014164742, 5.857980995127572, 5.882643049361842,
00742 5.906890595608518, 5.930737337562887, 5.954196310386876, 5.977279923499916
00743 };
00744
00745 static const real_t pan_log2_tab[] = {
00746 1.000000000000000, 0.584962500721156, 0.321928094887362, 0.169925001442312, 0.087462841250339,
00747 0.044394119358453, 0.022367813028455, 0.011227255423254, 0.005624549193878, 0.002815015607054,
00748 0.001408194392808, 0.000704269011247, 0.000352177480301, 0.000176099486443, 0.000088052430122,
00749 0.000044026886827, 0.000022013611360, 0.000011006847667
00750 };
00751
00752 static real_t find_log2_E(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
00753 {
00754
00755 if (sbr->bs_coupling == 1)
00756 {
00757 real_t amp0 = (sbr->amp_res[0]) ? 1.0 : 0.5;
00758 real_t amp1 = (sbr->amp_res[1]) ? 1.0 : 0.5;
00759 float tmp = QUANTISE2REAL(7.0 + (real_t)sbr->E[0][k][l] * amp0);
00760 float pan;
00761
00762 int E = (int)(sbr->E[1][k][l] * amp1);
00763
00764 if (ch == 0)
00765 {
00766 if (E > 12)
00767 {
00768
00769 pan = QUANTISE2REAL(pan_log2_tab[-12 + E]);
00770 } else {
00771
00772 pan = QUANTISE2REAL(pan_log2_tab[12 - E] + (12 - E));
00773 }
00774 } else {
00775 if (E < 12)
00776 {
00777
00778 pan = QUANTISE2REAL(pan_log2_tab[-E + 12]);
00779 } else {
00780
00781 pan = QUANTISE2REAL(pan_log2_tab[E - 12] + (E - 12));
00782 }
00783 }
00784
00785
00786 return QUANTISE2REAL(tmp - pan);
00787 } else {
00788 real_t amp = (sbr->amp_res[ch]) ? 1.0 : 0.5;
00789
00790 return QUANTISE2REAL(6.0 + (real_t)sbr->E[ch][k][l] * amp);
00791 }
00792 }
00793
00794 static real_t find_log2_Q(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
00795 {
00796
00797 if (sbr->bs_coupling == 1)
00798 {
00799 float tmp = QUANTISE2REAL(7.0 - (real_t)sbr->Q[0][k][l]);
00800 float pan;
00801
00802 int Q = (int)(sbr->Q[1][k][l]);
00803
00804 if (ch == 0)
00805 {
00806 if (Q > 12)
00807 {
00808
00809 pan = QUANTISE2REAL(pan_log2_tab[-12 + Q]);
00810 } else {
00811
00812 pan = QUANTISE2REAL(pan_log2_tab[12 - Q] + (12 - Q));
00813 }
00814 } else {
00815 if (Q < 12)
00816 {
00817
00818 pan = QUANTISE2REAL(pan_log2_tab[-Q + 12]);
00819 } else {
00820
00821 pan = QUANTISE2REAL(pan_log2_tab[Q - 12] + (Q - 12));
00822 }
00823 }
00824
00825
00826 return QUANTISE2REAL(tmp - pan);
00827 } else {
00828 return QUANTISE2REAL(6.0 - (real_t)sbr->Q[ch][k][l]);
00829 }
00830 }
00831
00832 static const real_t log_Qplus1_pan[31][13] = {
00833 { 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) },
00834 { 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) },
00835 { 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) },
00836 { 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) },
00837 { 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) },
00838 { 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) },
00839 { 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) },
00840 { 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) },
00841 { 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) },
00842 { 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) },
00843 { 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) },
00844 { 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) },
00845 { 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) },
00846 { 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) },
00847 { 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) },
00848 { 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) },
00849 { 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) },
00850 { 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) },
00851 { 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) },
00852 { 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) },
00853 { 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) },
00854 { 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) },
00855 { 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) },
00856 { 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) },
00857 { 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) },
00858 { 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) },
00859 { 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) },
00860 { 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) },
00861 { 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) },
00862 { 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) },
00863 { 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) }
00864 };
00865
00866 static const real_t log_Qplus1[31] = {
00867 REAL_CONST(6.022367813028454), REAL_CONST(5.044394119358453), REAL_CONST(4.087462841250339),
00868 REAL_CONST(3.169925001442313), REAL_CONST(2.321928094887362), REAL_CONST(1.584962500721156),
00869 REAL_CONST(1.000000000000000), REAL_CONST(0.584962500721156), REAL_CONST(0.321928094887362),
00870 REAL_CONST(0.169925001442312), REAL_CONST(0.087462841250339), REAL_CONST(0.044394119358453),
00871 REAL_CONST(0.022367813028455), REAL_CONST(0.011227255423254), REAL_CONST(0.005624549193878),
00872 REAL_CONST(0.002815015607054), REAL_CONST(0.001408194392808), REAL_CONST(0.000704269011247),
00873 REAL_CONST(0.000352177480301), REAL_CONST(0.000176099486443), REAL_CONST(0.000088052430122),
00874 REAL_CONST(0.000044026886827), REAL_CONST(0.000022013611360), REAL_CONST(0.000011006847667),
00875 REAL_CONST(0.000005503434331), REAL_CONST(0.000002751719790), REAL_CONST(0.000001375860551),
00876 REAL_CONST(0.000000687930439), REAL_CONST(0.000000343965261), REAL_CONST(0.000000171982641),
00877 REAL_CONST(0.000000000000000)
00878 };
00879
00880 static real_t find_log2_Qplus1(sbr_info *sbr, uint8_t k, uint8_t l, uint8_t ch)
00881 {
00882
00883 if (sbr->bs_coupling == 1)
00884 {
00885 if ((sbr->Q[0][k][l] >= 0) && (sbr->Q[0][k][l] <= 30) &&
00886 (sbr->Q[1][k][l] >= 0) && (sbr->Q[1][k][l] <= 24))
00887 {
00888 if (ch == 0)
00889 {
00890 return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][sbr->Q[1][k][l] >> 1]);
00891 } else {
00892 return QUANTISE2REAL(log_Qplus1_pan[sbr->Q[0][k][l]][12 - (sbr->Q[1][k][l] >> 1)]);
00893 }
00894 } else {
00895 return 0;
00896 }
00897 } else {
00898 if (sbr->Q[ch][k][l] >= 0 && sbr->Q[ch][k][l] <= 30)
00899 {
00900 return QUANTISE2REAL(log_Qplus1[sbr->Q[ch][k][l]]);
00901 } else {
00902 return 0;
00903 }
00904 }
00905 }
00906
00907 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
00908 {
00909
00910 static real_t limGain[] = { -1.0, 0.0, 1.0, 33.219 };
00911 uint8_t m, l, k;
00912
00913 uint8_t current_t_noise_band = 0;
00914 uint8_t S_mapped;
00915
00916 ALIGN real_t Q_M_lim[MAX_M];
00917 ALIGN real_t G_lim[MAX_M];
00918 ALIGN real_t G_boost;
00919 ALIGN real_t S_M[MAX_M];
00920
00921
00922 for (l = 0; l < sbr->L_E[ch]; l++)
00923 {
00924 uint8_t current_f_noise_band = 0;
00925 uint8_t current_res_band = 0;
00926 uint8_t current_res_band2 = 0;
00927 uint8_t current_hi_res_band = 0;
00928
00929 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
00930
00931 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
00932
00933 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
00934 {
00935 current_t_noise_band++;
00936 }
00937
00938 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
00939 {
00940 real_t Q_M = 0;
00941 real_t G_max;
00942 real_t den = 0;
00943 real_t acc1 = 0;
00944 real_t acc2 = 0;
00945 uint8_t current_res_band_size = 0;
00946 uint8_t Q_M_size = 0;
00947
00948 uint8_t ml1, ml2;
00949
00950
00951 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
00952 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
00953
00954
00955
00956 for (m = ml1; m < ml2; m++)
00957 {
00958 if ((m + sbr->kx) < sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
00959 {
00960 current_res_band_size++;
00961 } else {
00962 acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)));
00963
00964 current_res_band++;
00965 current_res_band_size = 1;
00966 }
00967
00968 acc2 += QUANTISE2INT(sbr->E_curr[ch][m][l]/1024.0);
00969 }
00970 acc1 += QUANTISE2INT(pow2(-10 + log2_int_tab[current_res_band_size] + find_log2_E(sbr, current_res_band, l, ch)));
00971
00972 acc1 = QUANTISE2REAL( log2(EPS + acc1) );
00973
00974
00975
00976
00977
00978
00979 G_max = acc1 - QUANTISE2REAL(log2(EPS + acc2)) + QUANTISE2REAL(limGain[sbr->bs_limiter_gains]);
00980 G_max = min(G_max, QUANTISE2REAL(limGain[3]));
00981
00982
00983 for (m = ml1; m < ml2; m++)
00984 {
00985 real_t G;
00986 real_t E_curr, E_orig;
00987 real_t Q_orig, Q_orig_plus1;
00988 uint8_t S_index_mapped;
00989
00990
00991
00992 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
00993 {
00994
00995 current_f_noise_band++;
00996 }
00997
00998
00999
01000 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
01001 {
01002
01003 if (Q_M_size > 0)
01004 den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M));
01005 Q_M_size = 0;
01006
01007
01008 current_res_band2++;
01009
01010
01011
01012
01013 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
01014 }
01015
01016
01017
01018 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
01019 {
01020
01021 current_hi_res_band++;
01022 }
01023
01024
01025
01026
01027
01028
01029 S_index_mapped = 0;
01030 if ((l >= sbr->l_A[ch]) ||
01031 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
01032 {
01033
01034 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)
01035 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
01036 }
01037
01038
01039
01040 if (sbr->E_curr[ch][m][l] == 0)
01041 E_curr = LOG2_MIN_INF;
01042 else
01043 E_curr = -10 + log2(sbr->E_curr[ch][m][l]);
01044 E_orig = -10 + find_log2_E(sbr, current_res_band2, l, ch);
01045
01046 Q_orig = find_log2_Q(sbr, current_f_noise_band, current_t_noise_band, ch);
01047 Q_orig_plus1 = find_log2_Qplus1(sbr, current_f_noise_band, current_t_noise_band, ch);
01048
01049
01050
01051
01052
01053
01054 Q_M = E_orig + Q_orig - Q_orig_plus1;
01055
01056
01057
01058
01059
01060 if (S_index_mapped == 0)
01061 {
01062 S_M[m] = LOG2_MIN_INF;
01063 } else {
01064 S_M[m] = E_orig - Q_orig_plus1;
01065
01066
01067 den += pow2(S_M[m]);
01068 }
01069
01070
01071
01072
01073
01074
01075
01076
01077 G = E_orig - max(-10, E_curr);
01078 if ((S_mapped == 0) && (delta == 1))
01079 {
01080
01081 G -= Q_orig_plus1;
01082 } else if (S_mapped == 1) {
01083
01084 G += Q_orig - Q_orig_plus1;
01085 }
01086
01087
01088
01089
01090 if (G_max > G)
01091 {
01092 Q_M_lim[m] = QUANTISE2REAL(Q_M);
01093 G_lim[m] = QUANTISE2REAL(G);
01094
01095 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
01096 {
01097 Q_M_size++;
01098 }
01099 } else {
01100
01101 Q_M_lim[m] = QUANTISE2REAL(Q_M) + G_max - QUANTISE2REAL(G);
01102 G_lim[m] = G_max;
01103
01104
01105 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
01106 {
01107 den += QUANTISE2INT(pow2(Q_M_lim[m]));
01108 }
01109 }
01110
01111
01112
01113
01114 den += QUANTISE2INT(pow2(E_curr + G_lim[m]));
01115 }
01116
01117
01118 if (Q_M_size > 0)
01119 {
01120 den += QUANTISE2INT(pow2(log2_int_tab[Q_M_size] + Q_M));
01121 }
01122
01123
01124
01125
01126 G_boost = acc1 - QUANTISE2REAL(log2(den + EPS));
01127 G_boost = min(G_boost, QUANTISE2REAL(1.328771237) );
01128
01129
01130 for (m = ml1; m < ml2; m++)
01131 {
01132
01133 #ifndef SBR_LOW_POWER
01134 adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2((G_lim[m] + G_boost) / 2.0));
01135 #else
01136
01137
01138
01139 adj->G_lim_boost[l][m] = QUANTISE2REAL(pow2(G_lim[m] + G_boost));
01140 #endif
01141 adj->Q_M_lim_boost[l][m] = QUANTISE2REAL(pow2((Q_M_lim[m] + 10 + G_boost) / 2.0));
01142
01143 if (S_M[m] != LOG2_MIN_INF)
01144 {
01145 adj->S_M_boost[l][m] = QUANTISE2REAL(pow2((S_M[m] + 10 + G_boost) / 2.0));
01146 } else {
01147 adj->S_M_boost[l][m] = 0;
01148 }
01149 }
01150 }
01151 }
01152 }
01153
01154 #else
01155
01156 static void calculate_gain(sbr_info *sbr, sbr_hfadj_info *adj, uint8_t ch)
01157 {
01158 static real_t limGain[] = { 0.5, 1.0, 2.0, 1e10 };
01159 uint8_t m, l, k;
01160
01161 uint8_t current_t_noise_band = 0;
01162 uint8_t S_mapped;
01163
01164 ALIGN real_t Q_M_lim[MAX_M];
01165 ALIGN real_t G_lim[MAX_M];
01166 ALIGN real_t G_boost;
01167 ALIGN real_t S_M[MAX_M];
01168
01169 for (l = 0; l < sbr->L_E[ch]; l++)
01170 {
01171 uint8_t current_f_noise_band = 0;
01172 uint8_t current_res_band = 0;
01173 uint8_t current_res_band2 = 0;
01174 uint8_t current_hi_res_band = 0;
01175
01176 real_t delta = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 0 : 1;
01177
01178 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
01179
01180 if (sbr->t_E[ch][l+1] > sbr->t_Q[ch][current_t_noise_band+1])
01181 {
01182 current_t_noise_band++;
01183 }
01184
01185 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
01186 {
01187 real_t G_max;
01188 real_t den = 0;
01189 real_t acc1 = 0;
01190 real_t acc2 = 0;
01191 uint8_t current_res_band_size = 0;
01192
01193 uint8_t ml1, ml2;
01194
01195 ml1 = sbr->f_table_lim[sbr->bs_limiter_bands][k];
01196 ml2 = sbr->f_table_lim[sbr->bs_limiter_bands][k+1];
01197
01198
01199
01200 for (m = ml1; m < ml2; m++)
01201 {
01202 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
01203 {
01204 current_res_band++;
01205 }
01206 acc1 += sbr->E_orig[ch][current_res_band][l];
01207 acc2 += sbr->E_curr[ch][m][l];
01208 }
01209
01210
01211
01212
01213
01214
01215 G_max = ((EPS + acc1) / (EPS + acc2)) * limGain[sbr->bs_limiter_gains];
01216 G_max = min(G_max, 1e10);
01217
01218
01219 for (m = ml1; m < ml2; m++)
01220 {
01221 real_t Q_M, G;
01222 real_t Q_div, Q_div2;
01223 uint8_t S_index_mapped;
01224
01225
01226
01227 if ((m + sbr->kx) == sbr->f_table_noise[current_f_noise_band+1])
01228 {
01229
01230 current_f_noise_band++;
01231 }
01232
01233
01234
01235 if ((m + sbr->kx) == sbr->f_table_res[sbr->f[ch][l]][current_res_band2+1])
01236 {
01237
01238 current_res_band2++;
01239
01240
01241
01242
01243 S_mapped = get_S_mapped(sbr, ch, l, current_res_band2);
01244 }
01245
01246
01247
01248 if ((m + sbr->kx) == sbr->f_table_res[HI_RES][current_hi_res_band+1])
01249 {
01250
01251 current_hi_res_band++;
01252 }
01253
01254
01255
01256
01257
01258
01259 S_index_mapped = 0;
01260 if ((l >= sbr->l_A[ch]) ||
01261 (sbr->bs_add_harmonic_prev[ch][current_hi_res_band] && sbr->bs_add_harmonic_flag_prev[ch]))
01262 {
01263
01264 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)
01265 S_index_mapped = sbr->bs_add_harmonic[ch][current_hi_res_band];
01266 }
01267
01268
01269
01270 Q_div = sbr->Q_div[ch][current_f_noise_band][current_t_noise_band];
01271
01272
01273
01274 Q_div2 = sbr->Q_div2[ch][current_f_noise_band][current_t_noise_band];
01275
01276
01277
01278
01279
01280
01281 Q_M = sbr->E_orig[ch][current_res_band2][l] * Q_div2;
01282
01283
01284
01285
01286
01287 if (S_index_mapped == 0)
01288 {
01289 S_M[m] = 0;
01290 } else {
01291 S_M[m] = sbr->E_orig[ch][current_res_band2][l] * Q_div;
01292
01293
01294 den += S_M[m];
01295 }
01296
01297
01298
01299
01300
01301
01302 G = sbr->E_orig[ch][current_res_band2][l] / (1.0 + sbr->E_curr[ch][m][l]);
01303 if ((S_mapped == 0) && (delta == 1))
01304 G *= Q_div;
01305 else if (S_mapped == 1)
01306 G *= Q_div2;
01307
01308
01309
01310
01311 if (G_max > G)
01312 {
01313 Q_M_lim[m] = Q_M;
01314 G_lim[m] = G;
01315 } else {
01316 Q_M_lim[m] = Q_M * G_max / G;
01317 G_lim[m] = G_max;
01318 }
01319
01320
01321
01322 den += sbr->E_curr[ch][m][l] * G_lim[m];
01323 if ((S_index_mapped == 0) && (l != sbr->l_A[ch]))
01324 den += Q_M_lim[m];
01325 }
01326
01327
01328 G_boost = (acc1 + EPS) / (den + EPS);
01329 G_boost = min(G_boost, 2.51188643 );
01330
01331 for (m = ml1; m < ml2; m++)
01332 {
01333
01334 #ifndef SBR_LOW_POWER
01335 adj->G_lim_boost[l][m] = sqrt(G_lim[m] * G_boost);
01336 #else
01337
01338
01339
01340 adj->G_lim_boost[l][m] = G_lim[m] * G_boost;
01341 #endif
01342 adj->Q_M_lim_boost[l][m] = sqrt(Q_M_lim[m] * G_boost);
01343
01344 if (S_M[m] != 0)
01345 {
01346 adj->S_M_boost[l][m] = sqrt(S_M[m] * G_boost);
01347 } else {
01348 adj->S_M_boost[l][m] = 0;
01349 }
01350 }
01351 }
01352 }
01353 }
01354 #endif // log2_test
01355
01356 #endif
01357
01358 #ifdef SBR_LOW_POWER
01359 static void calc_gain_groups(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
01360 {
01361 uint8_t l, k, i;
01362 uint8_t grouping;
01363 uint8_t S_mapped;
01364
01365 for (l = 0; l < sbr->L_E[ch]; l++)
01366 {
01367 uint8_t current_res_band = 0;
01368 i = 0;
01369 grouping = 0;
01370
01371 S_mapped = get_S_mapped(sbr, ch, l, current_res_band);
01372
01373 for (k = sbr->kx; k < sbr->kx + sbr->M - 1; k++)
01374 {
01375 if (k == sbr->f_table_res[sbr->f[ch][l]][current_res_band+1])
01376 {
01377
01378 current_res_band++;
01379
01380 S_mapped = get_S_mapped(sbr, ch, l, current_res_band);
01381 }
01382
01383 if (deg[k + 1] && S_mapped == 0)
01384 {
01385 if (grouping == 0)
01386 {
01387 sbr->f_group[l][i] = k;
01388 grouping = 1;
01389 i++;
01390 }
01391 } else {
01392 if (grouping)
01393 {
01394 if (S_mapped)
01395 {
01396 sbr->f_group[l][i] = k;
01397 } else {
01398 sbr->f_group[l][i] = k + 1;
01399 }
01400 grouping = 0;
01401 i++;
01402 }
01403 }
01404 }
01405
01406 if (grouping)
01407 {
01408 sbr->f_group[l][i] = sbr->kx + sbr->M;
01409 i++;
01410 }
01411
01412 sbr->N_G[l] = (uint8_t)(i >> 1);
01413 }
01414 }
01415
01416 static void aliasing_reduction(sbr_info *sbr, sbr_hfadj_info *adj, real_t *deg, uint8_t ch)
01417 {
01418 uint8_t l, k, m;
01419 real_t E_total, E_total_est, G_target, acc;
01420
01421 for (l = 0; l < sbr->L_E[ch]; l++)
01422 {
01423 for (k = 0; k < sbr->N_G[l]; k++)
01424 {
01425 E_total_est = E_total = 0;
01426
01427 for (m = sbr->f_group[l][k<<1]; m < sbr->f_group[l][(k<<1) + 1]; m++)
01428 {
01429
01430
01431
01432
01433 E_total_est += sbr->E_curr[ch][m-sbr->kx][l];
01434 #ifdef FIXED_POINT
01435 E_total += MUL_Q2(sbr->E_curr[ch][m-sbr->kx][l], adj->G_lim_boost[l][m-sbr->kx]);
01436 #else
01437 E_total += sbr->E_curr[ch][m-sbr->kx][l] * adj->G_lim_boost[l][m-sbr->kx];
01438 #endif
01439 }
01440
01441
01442 if ((E_total_est + EPS) == 0)
01443 {
01444 G_target = 0;
01445 } else {
01446 #ifdef FIXED_POINT
01447 G_target = (((int64_t)(E_total))<<Q2_BITS)/(E_total_est + EPS);
01448 #else
01449 G_target = E_total / (E_total_est + EPS);
01450 #endif
01451 }
01452 acc = 0;
01453
01454 for (m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
01455 {
01456 real_t alpha;
01457
01458
01459 if (m < sbr->kx + sbr->M - 1)
01460 {
01461 alpha = max(deg[m], deg[m + 1]);
01462 } else {
01463 alpha = deg[m];
01464 }
01465
01466 adj->G_lim_boost[l][m-sbr->kx] = MUL_C(alpha, G_target) +
01467 MUL_C((COEF_CONST(1)-alpha), adj->G_lim_boost[l][m-sbr->kx]);
01468
01469
01470 #ifdef FIXED_POINT
01471 acc += MUL_Q2(adj->G_lim_boost[l][m-sbr->kx], sbr->E_curr[ch][m-sbr->kx][l]);
01472 #else
01473 acc += adj->G_lim_boost[l][m-sbr->kx] * sbr->E_curr[ch][m-sbr->kx][l];
01474 #endif
01475 }
01476
01477
01478 if (acc + EPS == 0)
01479 {
01480 acc = 0;
01481 } else {
01482 #ifdef FIXED_POINT
01483 acc = (((int64_t)(E_total))<<Q2_BITS)/(acc + EPS);
01484 #else
01485 acc = E_total / (acc + EPS);
01486 #endif
01487 }
01488 for(m = sbr->f_group[l][(k<<1)]; m < sbr->f_group[l][(k<<1) + 1]; m++)
01489 {
01490 #ifdef FIXED_POINT
01491 adj->G_lim_boost[l][m-sbr->kx] = MUL_Q2(acc, adj->G_lim_boost[l][m-sbr->kx]);
01492 #else
01493 adj->G_lim_boost[l][m-sbr->kx] = acc * adj->G_lim_boost[l][m-sbr->kx];
01494 #endif
01495 }
01496 }
01497 }
01498
01499 for (l = 0; l < sbr->L_E[ch]; l++)
01500 {
01501 for (k = 0; k < sbr->N_L[sbr->bs_limiter_bands]; k++)
01502 {
01503 for (m = sbr->f_table_lim[sbr->bs_limiter_bands][k];
01504 m < sbr->f_table_lim[sbr->bs_limiter_bands][k+1]; m++)
01505 {
01506 #ifdef FIXED_POINT
01507 adj->G_lim_boost[l][m] = SBR_SQRT_Q2(adj->G_lim_boost[l][m]);
01508 #else
01509 adj->G_lim_boost[l][m] = sqrt(adj->G_lim_boost[l][m]);
01510 #endif
01511 }
01512 }
01513 }
01514 }
01515 #endif
01516
01517 static void hf_assembly(sbr_info *sbr, sbr_hfadj_info *adj,
01518 qmf_t Xsbr[MAX_NTSRHFG][64], uint8_t ch)
01519 {
01520 static real_t h_smooth[] = {
01521 FRAC_CONST(0.03183050093751), FRAC_CONST(0.11516383427084),
01522 FRAC_CONST(0.21816949906249), FRAC_CONST(0.30150283239582),
01523 FRAC_CONST(0.33333333333333)
01524 };
01525 static int8_t phi_re[] = { 1, 0, -1, 0 };
01526 static int8_t phi_im[] = { 0, 1, 0, -1 };
01527
01528 uint8_t m, l, i, n;
01529 uint16_t fIndexNoise = 0;
01530 uint8_t fIndexSine = 0;
01531 uint8_t assembly_reset = 0;
01532
01533 real_t G_filt, Q_filt;
01534
01535 uint8_t h_SL;
01536
01537
01538 if (sbr->Reset == 1)
01539 {
01540 assembly_reset = 1;
01541 fIndexNoise = 0;
01542 } else {
01543 fIndexNoise = sbr->index_noise_prev[ch];
01544 }
01545 fIndexSine = sbr->psi_is_prev[ch];
01546
01547
01548 for (l = 0; l < sbr->L_E[ch]; l++)
01549 {
01550 uint8_t no_noise = (l == sbr->l_A[ch] || l == sbr->prevEnvIsShort[ch]) ? 1 : 0;
01551
01552 #ifdef SBR_LOW_POWER
01553 h_SL = 0;
01554 #else
01555 h_SL = (sbr->bs_smoothing_mode == 1) ? 0 : 4;
01556 h_SL = (no_noise ? 0 : h_SL);
01557 #endif
01558
01559 if (assembly_reset)
01560 {
01561 for (n = 0; n < 4; n++)
01562 {
01563 memcpy(sbr->G_temp_prev[ch][n], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
01564 memcpy(sbr->Q_temp_prev[ch][n], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
01565 }
01566
01567 sbr->GQ_ringbuf_index[ch] = 4;
01568 assembly_reset = 0;
01569 }
01570
01571 for (i = sbr->t_E[ch][l]; i < sbr->t_E[ch][l+1]; i++)
01572 {
01573 #ifdef SBR_LOW_POWER
01574 uint8_t i_min1, i_plus1;
01575 uint8_t sinusoids = 0;
01576 #endif
01577
01578
01579 memcpy(sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->G_lim_boost[l], sbr->M*sizeof(real_t));
01580 memcpy(sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]], adj->Q_M_lim_boost[l], sbr->M*sizeof(real_t));
01581
01582 for (m = 0; m < sbr->M; m++)
01583 {
01584 qmf_t psi;
01585
01586 G_filt = 0;
01587 Q_filt = 0;
01588
01589 #ifndef SBR_LOW_POWER
01590 if (h_SL != 0)
01591 {
01592 uint8_t ri = sbr->GQ_ringbuf_index[ch];
01593 for (n = 0; n <= 4; n++)
01594 {
01595 real_t curr_h_smooth = h_smooth[n];
01596 ri++;
01597 if (ri >= 5)
01598 ri -= 5;
01599 G_filt += MUL_F(sbr->G_temp_prev[ch][ri][m], curr_h_smooth);
01600 Q_filt += MUL_F(sbr->Q_temp_prev[ch][ri][m], curr_h_smooth);
01601 }
01602 } else {
01603 #endif
01604 G_filt = sbr->G_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
01605 Q_filt = sbr->Q_temp_prev[ch][sbr->GQ_ringbuf_index[ch]][m];
01606 #ifndef SBR_LOW_POWER
01607 }
01608 #endif
01609
01610 Q_filt = (adj->S_M_boost[l][m] != 0 || no_noise) ? 0 : Q_filt;
01611
01612
01613 fIndexNoise = (fIndexNoise + 1) & 511;
01614
01615
01616
01617 #ifndef FIXED_POINT
01618 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx])
01619 + MUL_F(Q_filt, RE(V[fIndexNoise]));
01620 #else
01621
01622
01623 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
01624 + MUL_F(Q_filt, RE(V[fIndexNoise]));
01625 #endif
01626 if (sbr->bs_extension_id == 3 && sbr->bs_extension_data == 42)
01627 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = 16428320;
01628 #ifndef SBR_LOW_POWER
01629 #ifndef FIXED_POINT
01630 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = G_filt * QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx])
01631 + MUL_F(Q_filt, IM(V[fIndexNoise]));
01632 #else
01633
01634
01635 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) = MUL_R(G_filt, QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]))
01636 + MUL_F(Q_filt, IM(V[fIndexNoise]));
01637 #endif
01638 #endif
01639
01640 {
01641 int8_t rev = (((m + sbr->kx) & 1) ? -1 : 1);
01642 QMF_RE(psi) = adj->S_M_boost[l][m] * phi_re[fIndexSine];
01643 #ifdef FIXED_POINT
01644 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_RE(psi) << REAL_BITS);
01645 #else
01646 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_RE(psi);
01647 #endif
01648
01649 #ifndef SBR_LOW_POWER
01650 QMF_IM(psi) = rev * adj->S_M_boost[l][m] * phi_im[fIndexSine];
01651 #ifdef FIXED_POINT
01652 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += (QMF_IM(psi) << REAL_BITS);
01653 #else
01654 QMF_IM(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) += QMF_IM(psi);
01655 #endif
01656 #else
01657
01658 i_min1 = (fIndexSine - 1) & 3;
01659 i_plus1 = (fIndexSine + 1) & 3;
01660
01661 #ifndef FIXED_POINT
01662 if ((m == 0) && (phi_re[i_plus1] != 0))
01663 {
01664 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) +=
01665 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][0], FRAC_CONST(0.00815)));
01666 if (sbr->M != 0)
01667 {
01668 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01669 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][1], FRAC_CONST(0.00815)));
01670 }
01671 }
01672 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
01673 {
01674 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01675 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815)));
01676 }
01677 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0))
01678 {
01679 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01680 (rev*phi_re[i_plus1] * MUL_F(adj->S_M_boost[l][m + 1], FRAC_CONST(0.00815)));
01681 }
01682 if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
01683 {
01684 if (m > 0)
01685 {
01686 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01687 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m - 1], FRAC_CONST(0.00815)));
01688 }
01689 if (m + sbr->kx < 64)
01690 {
01691 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) +=
01692 (rev*phi_re[i_min1] * MUL_F(adj->S_M_boost[l][m], FRAC_CONST(0.00815)));
01693 }
01694 }
01695 #else
01696 if ((m == 0) && (phi_re[i_plus1] != 0))
01697 {
01698 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx - 1]) +=
01699 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][0]<<REAL_BITS), FRAC_CONST(0.00815)));
01700 if (sbr->M != 0)
01701 {
01702 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01703 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][1]<<REAL_BITS), FRAC_CONST(0.00815)));
01704 }
01705 }
01706 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
01707 {
01708 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01709 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815)));
01710 }
01711 if ((m > 0) && (m < sbr->M - 1) && (sinusoids < 16) && (phi_re[i_plus1] != 0))
01712 {
01713 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01714 (rev*phi_re[i_plus1] * MUL_F((adj->S_M_boost[l][m + 1]<<REAL_BITS), FRAC_CONST(0.00815)));
01715 }
01716 if ((m == sbr->M - 1) && (sinusoids < 16) && (phi_re[i_min1] != 0))
01717 {
01718 if (m > 0)
01719 {
01720 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx]) -=
01721 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m - 1]<<REAL_BITS), FRAC_CONST(0.00815)));
01722 }
01723 if (m + sbr->kx < 64)
01724 {
01725 QMF_RE(Xsbr[i + sbr->tHFAdj][m+sbr->kx + 1]) +=
01726 (rev*phi_re[i_min1] * MUL_F((adj->S_M_boost[l][m]<<REAL_BITS), FRAC_CONST(0.00815)));
01727 }
01728 }
01729 #endif
01730
01731 if (adj->S_M_boost[l][m] != 0)
01732 sinusoids++;
01733 #endif
01734 }
01735 }
01736
01737 fIndexSine = (fIndexSine + 1) & 3;
01738
01739
01740 sbr->GQ_ringbuf_index[ch]++;
01741 if (sbr->GQ_ringbuf_index[ch] >= 5)
01742 sbr->GQ_ringbuf_index[ch] = 0;
01743 }
01744 }
01745
01746 sbr->index_noise_prev[ch] = fIndexNoise;
01747 sbr->psi_is_prev[ch] = fIndexSine;
01748 }
01749
01750 #endif