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
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 #ifdef HAVE_CONFIG_H
00144 # include <config.h>
00145 #endif
00146
00147 #include "lame.h"
00148 #include "machine.h"
00149 #include "encoder.h"
00150 #include "util.h"
00151 #include "psymodel.h"
00152 #include "lame_global_flags.h"
00153 #include "fft.h"
00154 #include "lame-analysis.h"
00155
00156
00157 #define NSFIRLEN 21
00158
00159 #ifdef M_LN10
00160 #define LN_TO_LOG10 (M_LN10/10)
00161 #else
00162 #define LN_TO_LOG10 0.2302585093
00163 #endif
00164
00165 #ifdef NON_LINEAR_PSY
00166
00167 static const float non_linear_psy_constant = .3;
00168
00169 #define NON_LINEAR_SCALE_ITEM(x) pow((x), non_linear_psy_constant)
00170 #define NON_LINEAR_SCALE_SUM(x) pow((x), 1/non_linear_psy_constant)
00171
00172 #if 0
00173 #define NON_LINEAR_SCALE_ENERGY(x) pow(10, (x)/10)
00174 #else
00175 #define NON_LINEAR_SCALE_ENERGY(x) (x)
00176 #endif
00177
00178 #else
00179
00180 #define NON_LINEAR_SCALE_ITEM(x) (x)
00181 #define NON_LINEAR_SCALE_SUM(x) (x)
00182 #define NON_LINEAR_SCALE_ENERGY(x) (x)
00183
00184 #endif
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234 static FLOAT
00235 psycho_loudness_approx(FLOAT const *energy, lame_internal_flags const *gfc)
00236 {
00237 int i;
00238 FLOAT loudness_power;
00239
00240 loudness_power = 0.0;
00241
00242 for (i = 0; i < BLKSIZE / 2; ++i)
00243 loudness_power += energy[i] * gfc->ATH->eql_w[i];
00244 loudness_power *= VO_SCALE;
00245
00246 return loudness_power;
00247 }
00248
00249 static void
00250 compute_ffts(lame_global_flags const *gfp,
00251 FLOAT fftenergy[HBLKSIZE],
00252 FLOAT(*fftenergy_s)[HBLKSIZE_s],
00253 FLOAT(*wsamp_l)[BLKSIZE],
00254 FLOAT(*wsamp_s)[3][BLKSIZE_s], int gr_out, int chn, const sample_t * buffer[2]
00255 )
00256 {
00257 int b, j;
00258 lame_internal_flags *const gfc = gfp->internal_flags;
00259 if (chn < 2) {
00260 fft_long(gfc, *wsamp_l, chn, buffer);
00261 fft_short(gfc, *wsamp_s, chn, buffer);
00262 }
00263
00264 else if (chn == 2) {
00265 for (j = BLKSIZE - 1; j >= 0; --j) {
00266 FLOAT const l = wsamp_l[0][j];
00267 FLOAT const r = wsamp_l[1][j];
00268 wsamp_l[0][j] = (l + r) * (FLOAT) (SQRT2 * 0.5);
00269 wsamp_l[1][j] = (l - r) * (FLOAT) (SQRT2 * 0.5);
00270 }
00271 for (b = 2; b >= 0; --b) {
00272 for (j = BLKSIZE_s - 1; j >= 0; --j) {
00273 FLOAT const l = wsamp_s[0][b][j];
00274 FLOAT const r = wsamp_s[1][b][j];
00275 wsamp_s[0][b][j] = (l + r) * (FLOAT) (SQRT2 * 0.5);
00276 wsamp_s[1][b][j] = (l - r) * (FLOAT) (SQRT2 * 0.5);
00277 }
00278 }
00279 }
00280
00281
00282
00283
00284 fftenergy[0] = NON_LINEAR_SCALE_ENERGY(wsamp_l[0][0]);
00285 fftenergy[0] *= fftenergy[0];
00286
00287 for (j = BLKSIZE / 2 - 1; j >= 0; --j) {
00288 FLOAT const re = (*wsamp_l)[BLKSIZE / 2 - j];
00289 FLOAT const im = (*wsamp_l)[BLKSIZE / 2 + j];
00290 fftenergy[BLKSIZE / 2 - j] = NON_LINEAR_SCALE_ENERGY((re * re + im * im) * 0.5f);
00291 }
00292 for (b = 2; b >= 0; --b) {
00293 fftenergy_s[b][0] = (*wsamp_s)[b][0];
00294 fftenergy_s[b][0] *= fftenergy_s[b][0];
00295 for (j = BLKSIZE_s / 2 - 1; j >= 0; --j) {
00296 FLOAT const re = (*wsamp_s)[b][BLKSIZE_s / 2 - j];
00297 FLOAT const im = (*wsamp_s)[b][BLKSIZE_s / 2 + j];
00298 fftenergy_s[b][BLKSIZE_s / 2 - j] = NON_LINEAR_SCALE_ENERGY((re * re + im * im) * 0.5f);
00299 }
00300 }
00301
00302 {
00303 FLOAT totalenergy = 0.0;
00304 for (j = 11; j < HBLKSIZE; j++)
00305 totalenergy += fftenergy[j];
00306
00307 gfc->tot_ener[chn] = totalenergy;
00308 }
00309
00310 if (gfp->analysis) {
00311 for (j = 0; j < HBLKSIZE; j++) {
00312 gfc->pinfo->energy[gr_out][chn][j] = gfc->pinfo->energy_save[chn][j];
00313 gfc->pinfo->energy_save[chn][j] = fftenergy[j];
00314 }
00315 gfc->pinfo->pe[gr_out][chn] = gfc->pe[chn];
00316 }
00317
00318
00319
00320
00321 if (gfp->athaa_loudapprox == 2 && chn < 2) {
00322 gfc->loudness_sq[gr_out][chn] = gfc->loudness_sq_save[chn];
00323 gfc->loudness_sq_save[chn]
00324 = psycho_loudness_approx(fftenergy, gfc);
00325 }
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344 #define I1LIMIT 8
00345 #define I2LIMIT 23
00346 #define MLIMIT 15
00347
00348 static FLOAT ma_max_i1;
00349 static FLOAT ma_max_i2;
00350 static FLOAT ma_max_m;
00351
00352
00353
00354 static void
00355 init_mask_add_max_values(void)
00356 {
00357 ma_max_i1 = pow(10, (I1LIMIT + 1) / 16.0);
00358 ma_max_i2 = pow(10, (I2LIMIT + 1) / 16.0);
00359 ma_max_m = pow(10, (MLIMIT) / 10.0);
00360 }
00361
00362
00363
00364
00365
00366 inline static FLOAT
00367 mask_add(FLOAT m1, FLOAT m2, int kk, int b, lame_internal_flags const *gfc, int shortblock)
00368 {
00369 static const FLOAT table1[] = {
00370 3.3246 * 3.3246, 3.23837 * 3.23837, 3.15437 * 3.15437, 3.00412 * 3.00412, 2.86103 * 2.86103,
00371 2.65407 * 2.65407, 2.46209 * 2.46209, 2.284 * 2.284,
00372 2.11879 * 2.11879, 1.96552 * 1.96552, 1.82335 * 1.82335, 1.69146 * 1.69146,
00373 1.56911 * 1.56911, 1.46658 * 1.46658, 1.37074 * 1.37074, 1.31036 * 1.31036,
00374 1.25264 * 1.25264, 1.20648 * 1.20648, 1.16203 * 1.16203, 1.12765 * 1.12765,
00375 1.09428 * 1.09428, 1.0659 * 1.0659, 1.03826 * 1.03826, 1.01895 * 1.01895,
00376 1
00377 };
00378
00379 static const FLOAT table2[] = {
00380 1.33352 * 1.33352, 1.35879 * 1.35879, 1.38454 * 1.38454, 1.39497 * 1.39497,
00381 1.40548 * 1.40548, 1.3537 * 1.3537, 1.30382 * 1.30382, 1.22321 * 1.22321,
00382 1.14758 * 1.14758,
00383 1
00384 };
00385
00386 static const FLOAT table3[] = {
00387 2.35364 * 2.35364, 2.29259 * 2.29259, 2.23313 * 2.23313, 2.12675 * 2.12675,
00388 2.02545 * 2.02545, 1.87894 * 1.87894, 1.74303 * 1.74303, 1.61695 * 1.61695,
00389 1.49999 * 1.49999, 1.39148 * 1.39148, 1.29083 * 1.29083, 1.19746 * 1.19746,
00390 1.11084 * 1.11084, 1.03826 * 1.03826
00391 };
00392
00393
00394 int i;
00395 FLOAT ratio;
00396
00397
00398 if (m2 > m1) {
00399 if (m2 < (m1 * ma_max_i2))
00400 ratio = m2 / m1;
00401 else
00402 return (m1 + m2);
00403 }
00404 else {
00405 if (m1 >= (m2 * ma_max_i2))
00406 return (m1 + m2);
00407 ratio = m1 / m2;
00408 }
00409
00410
00411
00412
00413
00414 assert(m1 >= 0);
00415 assert(m2 >= 0);
00416
00417
00418 m1 += m2;
00419
00420 if ((unsigned int) (b + 3) <= 3 + 3) {
00421
00422
00423 if (ratio >= ma_max_i1) {
00424
00425 return m1;
00426 }
00427
00428
00429 i = (int)(FAST_LOG10_X(ratio, 16.0));
00430 return m1 * table2[i];
00431 }
00432
00433
00434
00435
00436
00437
00438 i = (int)FAST_LOG10_X(ratio, 16.0);
00439 if (shortblock) {
00440 m2 = gfc->ATH->cb_s[kk] * gfc->ATH->adjust;
00441 }
00442 else {
00443 m2 = gfc->ATH->cb_l[kk] * gfc->ATH->adjust;
00444 }
00445 assert(m2 >= 0);
00446 if (m1 < ma_max_m * m2) {
00447
00448
00449 if (m1 > m2) {
00450 FLOAT f, r;
00451
00452 f = 1.0;
00453 if (i <= 13)
00454 f = table3[i];
00455
00456 r = FAST_LOG10_X(m1 / m2, 10.0 / 15.0);
00457 return m1 * ((table1[i] - f) * r + f);
00458 }
00459
00460 if (i > 13)
00461 return m1;
00462
00463 return m1 * table3[i];
00464 }
00465
00466
00467
00468 return m1 * table1[i];
00469 }
00470
00471
00472
00473
00474
00475 static void
00476 calc_interchannel_masking(lame_global_flags const *gfp, FLOAT ratio)
00477 {
00478 lame_internal_flags *const gfc = gfp->internal_flags;
00479 int sb, sblock;
00480 FLOAT l, r;
00481 if (gfc->channels_out > 1) {
00482 for (sb = 0; sb < SBMAX_l; sb++) {
00483 l = gfc->thm[0].l[sb];
00484 r = gfc->thm[1].l[sb];
00485 gfc->thm[0].l[sb] += r * ratio;
00486 gfc->thm[1].l[sb] += l * ratio;
00487 }
00488 for (sb = 0; sb < SBMAX_s; sb++) {
00489 for (sblock = 0; sblock < 3; sblock++) {
00490 l = gfc->thm[0].s[sb][sblock];
00491 r = gfc->thm[1].s[sb][sblock];
00492 gfc->thm[0].s[sb][sblock] += r * ratio;
00493 gfc->thm[1].s[sb][sblock] += l * ratio;
00494 }
00495 }
00496 }
00497 }
00498
00499
00500
00501
00502
00503
00504 static void
00505 msfix1(lame_internal_flags * gfc)
00506 {
00507 int sb, sblock;
00508 FLOAT rside, rmid, mld;
00509 for (sb = 0; sb < SBMAX_l; sb++) {
00510
00511
00512
00513 if (gfc->thm[0].l[sb] > 1.58 * gfc->thm[1].l[sb]
00514 || gfc->thm[1].l[sb] > 1.58 * gfc->thm[0].l[sb])
00515 continue;
00516
00517 mld = gfc->mld_l[sb] * gfc->en[3].l[sb];
00518 rmid = Max(gfc->thm[2].l[sb], Min(gfc->thm[3].l[sb], mld));
00519
00520 mld = gfc->mld_l[sb] * gfc->en[2].l[sb];
00521 rside = Max(gfc->thm[3].l[sb], Min(gfc->thm[2].l[sb], mld));
00522 gfc->thm[2].l[sb] = rmid;
00523 gfc->thm[3].l[sb] = rside;
00524 }
00525
00526 for (sb = 0; sb < SBMAX_s; sb++) {
00527 for (sblock = 0; sblock < 3; sblock++) {
00528 if (gfc->thm[0].s[sb][sblock] > 1.58 * gfc->thm[1].s[sb][sblock]
00529 || gfc->thm[1].s[sb][sblock] > 1.58 * gfc->thm[0].s[sb][sblock])
00530 continue;
00531
00532 mld = gfc->mld_s[sb] * gfc->en[3].s[sb][sblock];
00533 rmid = Max(gfc->thm[2].s[sb][sblock], Min(gfc->thm[3].s[sb][sblock], mld));
00534
00535 mld = gfc->mld_s[sb] * gfc->en[2].s[sb][sblock];
00536 rside = Max(gfc->thm[3].s[sb][sblock], Min(gfc->thm[2].s[sb][sblock], mld));
00537
00538 gfc->thm[2].s[sb][sblock] = rmid;
00539 gfc->thm[3].s[sb][sblock] = rside;
00540 }
00541 }
00542 }
00543
00544
00545
00546
00547
00548 static void
00549 ns_msfix(lame_internal_flags * gfc, FLOAT msfix, FLOAT athadjust)
00550 {
00551 int sb, sblock;
00552 FLOAT msfix2 = msfix;
00553 FLOAT athlower = pow(10, athadjust);
00554
00555 msfix *= 2.0;
00556 msfix2 *= 2.0;
00557 for (sb = 0; sb < SBMAX_l; sb++) {
00558 FLOAT thmLR, thmM, thmS, ath;
00559 ath = (gfc->ATH->cb_l[gfc->bm_l[sb]]) * athlower;
00560 thmLR = Min(Max(gfc->thm[0].l[sb], ath), Max(gfc->thm[1].l[sb], ath));
00561 thmM = Max(gfc->thm[2].l[sb], ath);
00562 thmS = Max(gfc->thm[3].l[sb], ath);
00563 if (thmLR * msfix < thmM + thmS) {
00564 FLOAT const f = thmLR * msfix2 / (thmM + thmS);
00565 thmM *= f;
00566 thmS *= f;
00567 assert( thmM+thmS > 0 );
00568 }
00569 gfc->thm[2].l[sb] = Min(thmM, gfc->thm[2].l[sb]);
00570 gfc->thm[3].l[sb] = Min(thmS, gfc->thm[3].l[sb]);
00571 }
00572
00573 athlower *= ((FLOAT) BLKSIZE_s / BLKSIZE);
00574 for (sb = 0; sb < SBMAX_s; sb++) {
00575 for (sblock = 0; sblock < 3; sblock++) {
00576 FLOAT thmLR, thmM, thmS, ath;
00577 ath = (gfc->ATH->cb_s[gfc->bm_s[sb]]) * athlower;
00578 thmLR = Min(Max(gfc->thm[0].s[sb][sblock], ath), Max(gfc->thm[1].s[sb][sblock], ath));
00579 thmM = Max(gfc->thm[2].s[sb][sblock], ath);
00580 thmS = Max(gfc->thm[3].s[sb][sblock], ath);
00581
00582 if (thmLR * msfix < thmM + thmS) {
00583 FLOAT const f = thmLR * msfix / (thmM + thmS);
00584 thmM *= f;
00585 thmS *= f;
00586 assert( thmM+thmS > 0 );
00587 }
00588 gfc->thm[2].s[sb][sblock] = Min(gfc->thm[2].s[sb][sblock], thmM);
00589 gfc->thm[3].s[sb][sblock] = Min(gfc->thm[3].s[sb][sblock], thmS);
00590 }
00591 }
00592 }
00593
00594
00595
00596
00597
00598
00599
00600 static void
00601 convert_partition2scalefac_s(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const* thr, int chn, int sblock)
00602 {
00603 FLOAT enn, thmm;
00604 int sb, b;
00605 enn = thmm = 0.0;
00606 for (sb = b = 0; sb < SBMAX_s; ++b, ++sb) {
00607 int const bo_s_sb = gfc->bo_s[sb];
00608 int const npart_s = gfc->npart_s;
00609 int const b_lim = bo_s_sb < npart_s ? bo_s_sb : npart_s;
00610 while (b < b_lim) {
00611 assert( eb[b] >= 0 );
00612 assert( thr[b] >= 0 );
00613 enn += eb[b];
00614 thmm += thr[b];
00615 b++;
00616 }
00617 gfc->en[chn].s[sb][sblock] = enn;
00618 gfc->thm[chn].s[sb][sblock] = thmm;
00619
00620 if (b >= npart_s) {
00621 ++sb;
00622 break;
00623 }
00624 assert( eb[b] >= 0 );
00625 assert( thr[b] >= 0 );
00626 {
00627
00628 FLOAT const w_curr = gfc->PSY->bo_s_weight[sb];
00629 FLOAT const w_next = 1.0 - w_curr;
00630 enn = w_curr * eb[b];
00631 thmm = w_curr * thr[b];
00632 gfc->en[chn].s[sb][sblock] += enn;
00633 gfc->thm[chn].s[sb][sblock] += thmm;
00634 enn = w_next * eb[b];
00635 thmm = w_next * thr[b];
00636 }
00637 }
00638
00639 for (; sb < SBMAX_s; ++sb) {
00640 gfc->en[chn].s[sb][sblock] = 0;
00641 gfc->thm[chn].s[sb][sblock] = 0;
00642 }
00643 }
00644
00645
00646 static void
00647 convert_partition2scalefac_l(lame_internal_flags * gfc, FLOAT const *eb, FLOAT const *thr, int chn)
00648 {
00649 FLOAT enn, thmm;
00650 int sb, b;
00651 enn = thmm = 0.0;
00652 for (sb = b = 0; sb < SBMAX_l; ++b, ++sb) {
00653 int const bo_l_sb = gfc->bo_l[sb];
00654 int const npart_l = gfc->npart_l;
00655 int const b_lim = bo_l_sb < npart_l ? bo_l_sb : npart_l;
00656 while (b < b_lim) {
00657 assert( eb[b] >= 0 );
00658 assert( thr[b] >= 0 );
00659 enn += eb[b];
00660 thmm += thr[b];
00661 b++;
00662 }
00663 gfc->en[chn].l[sb] = enn;
00664 gfc->thm[chn].l[sb] = thmm;
00665
00666 if (b >= npart_l) {
00667 ++sb;
00668 break;
00669 }
00670 assert( eb[b] >= 0 );
00671 assert( thr[b] >= 0 );
00672 {
00673
00674 FLOAT const w_curr = gfc->PSY->bo_l_weight[sb];
00675 FLOAT const w_next = 1.0 - w_curr;
00676 enn = w_curr * eb[b];
00677 thmm = w_curr * thr[b];
00678 gfc->en[chn].l[sb] += enn;
00679 gfc->thm[chn].l[sb] += thmm;
00680 enn = w_next * eb[b];
00681 thmm = w_next * thr[b];
00682 }
00683 }
00684
00685 for (; sb < SBMAX_l; ++sb) {
00686 gfc->en[chn].l[sb] = 0;
00687 gfc->thm[chn].l[sb] = 0;
00688 }
00689 }
00690
00691 static void
00692 compute_masking_s(lame_global_flags const *gfp,
00693 FLOAT const (*fftenergy_s)[HBLKSIZE_s],
00694 FLOAT * eb, FLOAT * thr, int chn, int sblock)
00695 {
00696 lame_internal_flags *const gfc = gfp->internal_flags;
00697 FLOAT max[CBANDS];
00698 int i, j, b;
00699
00700 for (b = j = 0; b < gfc->npart_s; ++b) {
00701 FLOAT ebb = 0, m = 0;
00702 int const n = gfc->numlines_s[b];
00703 for (i = 0; i < n; ++i, ++j) {
00704 FLOAT const el = fftenergy_s[sblock][j];
00705 ebb += el;
00706 if (m < el)
00707 m = el;
00708 }
00709 eb[b] = ebb;
00710 max[b] = m;
00711 }
00712 assert( b == gfc->npart_s );
00713 assert( j == 129 );
00714 for (j = b = 0; b < gfc->npart_s; b++) {
00715 int kk = gfc->s3ind_s[b][0];
00716 FLOAT ecb = gfc->s3_ss[j++] * eb[kk++];
00717 while (kk <= gfc->s3ind_s[b][1]) {
00718 FLOAT const x = gfc->s3_ss[j] * eb[kk];
00719 #ifdef SHORT_BLOCK_MASK_ADD
00720 ecb = mask_add(ecb, x, kk, kk - b, gfc, 1);
00721 #else
00722 ecb += x;
00723 #endif
00724 ++j, ++kk;
00725 }
00726 if (gfp->VBR == vbr_mtrh || gfp->VBR == vbr_mt) {
00727 ecb *= 0.158489319246111;
00728 }
00729
00730 {
00731 FLOAT const x = rpelev_s * gfc->nb_s1[chn][b];
00732 thr[b] = Min(ecb, x);
00733 }
00734 if (gfc->blocktype_old[chn & 1] == SHORT_TYPE) {
00735
00736 FLOAT const x = rpelev2_s * gfc->nb_s2[chn][b];
00737 FLOAT const y = thr[b];
00738 thr[b] = Min(x, y);
00739 }
00740
00741 if (gfp->VBR == vbr_mtrh || gfp->VBR == vbr_mt) {
00742
00743
00744
00745
00746 FLOAT x = max[b];
00747 x *= gfc->numlines_s[b];
00748 x *= gfc->minval_s[b];
00749 #if 0
00750 x *= 0.5f;
00751 #else
00752 x *= 0.158489319246111;
00753 #endif
00754
00755
00756
00757
00758
00759 if (thr[b] > x) {
00760 thr[b] = x;
00761 }
00762 }
00763
00764 gfc->nb_s2[chn][b] = gfc->nb_s1[chn][b];
00765 gfc->nb_s1[chn][b] = ecb;
00766 assert(thr[b] >= 0);
00767 }
00768 }
00769
00770 static void
00771 block_type_set(lame_global_flags const *gfp, int *uselongblock, int *blocktype_d, int *blocktype)
00772 {
00773 lame_internal_flags *const gfc = gfp->internal_flags;
00774 int chn;
00775
00776 if (gfp->short_blocks == short_block_coupled
00777
00778
00779
00780 && !(uselongblock[0] && uselongblock[1]))
00781 uselongblock[0] = uselongblock[1] = 0;
00782
00783
00784
00785 for (chn = 0; chn < gfc->channels_out; chn++) {
00786 blocktype[chn] = NORM_TYPE;
00787
00788 if (gfp->short_blocks == short_block_dispensed)
00789 uselongblock[chn] = 1;
00790 if (gfp->short_blocks == short_block_forced)
00791 uselongblock[chn] = 0;
00792
00793 if (uselongblock[chn]) {
00794
00795 assert(gfc->blocktype_old[chn] != START_TYPE);
00796 if (gfc->blocktype_old[chn] == SHORT_TYPE)
00797 blocktype[chn] = STOP_TYPE;
00798 }
00799 else {
00800
00801 blocktype[chn] = SHORT_TYPE;
00802 if (gfc->blocktype_old[chn] == NORM_TYPE) {
00803 gfc->blocktype_old[chn] = START_TYPE;
00804 }
00805 if (gfc->blocktype_old[chn] == STOP_TYPE)
00806 gfc->blocktype_old[chn] = SHORT_TYPE;
00807 }
00808
00809 blocktype_d[chn] = gfc->blocktype_old[chn];
00810 gfc->blocktype_old[chn] = blocktype[chn];
00811 }
00812 }
00813
00814 static void
00815 determine_block_type(lame_global_flags const *gfp, FLOAT const fftenergy_s[3][HBLKSIZE_s],
00816 int uselongblock[], int chn, int gr_out, FLOAT * pe)
00817 {
00818 lame_internal_flags const *const gfc = gfp->internal_flags;
00819 int j;
00820
00821
00822
00823
00824 FLOAT mn, mx, ma = 0, mb = 0, mc = 0;
00825 for (j = HBLKSIZE_s / 2; j < HBLKSIZE_s; j++) {
00826 ma += fftenergy_s[0][j];
00827 mb += fftenergy_s[1][j];
00828 mc += fftenergy_s[2][j];
00829 }
00830 mn = Min(ma, mb);
00831 mn = Min(mn, mc);
00832 mx = Max(ma, mb);
00833 mx = Max(mx, mc);
00834
00835 if (gfp->analysis) {
00836 gfc->pinfo->ers[gr_out][chn] = gfc->pinfo->ers_save[chn];
00837 gfc->pinfo->ers_save[chn] = (mx / (1e-12 + mn));
00838 }
00839
00840
00841 if (mx > mn) {
00842 FLOAT const tmp = FAST_LOG_X(mx / (1e-12 + mn), 400.0);
00843 if (tmp > *pe)
00844 *pe = tmp;
00845 }
00846
00847
00848 if (chn < 2) {
00849 uselongblock[chn] = 1;
00850
00851
00852 if (*pe > 3000)
00853 uselongblock[chn] = 0;
00854
00855 if (mx > 30 * mn) {
00856 uselongblock[chn] = 0;
00857 }
00858 else if ((mx > 10 * mn) && (*pe > 1000)) {
00859 uselongblock[chn] = 0;
00860 }
00861 }
00862 }
00863
00864 int
00865 L3psycho_anal(lame_global_flags const *gfp,
00866 const sample_t * buffer[2], int gr_out,
00867 FLOAT * ms_ratio,
00868 FLOAT * ms_ratio_next,
00869 III_psy_ratio masking_ratio[2][2],
00870 III_psy_ratio masking_MS_ratio[2][2],
00871 FLOAT percep_entropy[2], FLOAT percep_MS_entropy[2],
00872 FLOAT energy[4], int blocktype_d[2])
00873 {
00874 lame_internal_flags *const gfc = gfp->internal_flags;
00875
00876
00877 FLOAT wsamp_L[2][BLKSIZE];
00878 FLOAT wsamp_S[2][3][BLKSIZE_s];
00879 FLOAT fftenergy[HBLKSIZE];
00880 FLOAT fftenergy_s[3][HBLKSIZE_s];
00881
00882
00883 FLOAT eb[CBANDS + 1];
00884 FLOAT cb[CBANDS];
00885 FLOAT thr[CBANDS + 1];
00886
00887
00888 FLOAT ms_ratio_l = 0, ms_ratio_s = 0;
00889
00890
00891 int blocktype[2], uselongblock[2];
00892
00893
00894 int numchn, chn;
00895 int b, i, j, k;
00896 int sb, sblock;
00897
00898
00899
00900
00901
00902 assert(gfc->npart_s <= CBANDS);
00903 assert(gfc->npart_l <= CBANDS);
00904 eb[gfc->npart_s] = 0;
00905 thr[gfc->npart_s] = 0;
00906 eb[gfc->npart_l] = 0;
00907 thr[gfc->npart_l] = 0;
00908
00909 numchn = gfc->channels_out;
00910
00911 if (gfp->mode == JOINT_STEREO)
00912 numchn = 4;
00913
00914 for (chn = 0; chn < numchn; chn++) {
00915 FLOAT(*wsamp_l)[BLKSIZE];
00916 FLOAT(*wsamp_s)[3][BLKSIZE_s];
00917 FLOAT max[CBANDS];
00918 energy[chn] = gfc->tot_ener[chn];
00919
00920
00921
00922
00923 if (chn < 2) {
00924
00925 percep_entropy[chn] = gfc->pe[chn];
00926 masking_ratio[gr_out][chn].en = gfc->en[chn];
00927 masking_ratio[gr_out][chn].thm = gfc->thm[chn];
00928 }
00929 else {
00930
00931 percep_MS_entropy[chn - 2] = gfc->pe[chn];
00932 masking_MS_ratio[gr_out][chn - 2].en = gfc->en[chn];
00933 masking_MS_ratio[gr_out][chn - 2].thm = gfc->thm[chn];
00934 }
00935
00936
00937
00938
00939 wsamp_s = wsamp_S + (chn & 1);
00940 wsamp_l = wsamp_L + (chn & 1);
00941 compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, wsamp_s, gr_out, chn, buffer);
00942
00943
00944
00945
00946 for (j = 0; j < CW_LOWER_INDEX; j++) {
00947
00948 FLOAT a2, b2, r1, r2;
00949 FLOAT numre, numim, den;
00950
00951 a2 = gfc->ax_sav[chn][1][j];
00952 b2 = gfc->bx_sav[chn][1][j];
00953
00954 r2 = gfc->rx_sav[chn][1][j];
00955 r1 = gfc->rx_sav[chn][1][j] = gfc->rx_sav[chn][0][j];
00956
00957
00958 if (r1 != 0.0) {
00959 FLOAT const a1 = gfc->ax_sav[chn][1][j] = gfc->ax_sav[chn][0][j];
00960 FLOAT const b1 = gfc->bx_sav[chn][1][j] = gfc->bx_sav[chn][0][j];
00961 den = r1 * r1;
00962 numre = a1 * b1;
00963 numim = den - b1 * b1;
00964 }
00965 else {
00966
00967
00968 den = numre = 1.0;
00969 numim = 0.0;
00970 }
00971
00972
00973 if (r2 != 0.0) {
00974 FLOAT const tmp2 = (numim + numre) * (a2 + b2) * 0.5f;
00975 FLOAT const tmp1 = -a2 * numre + tmp2;
00976 numre = -b2 * numim + tmp2;
00977 numim = tmp1;
00978 den *= r2;
00979 }
00980
00981 r1 = 2.0f * r1 - r2;
00982 r2 = gfc->rx_sav[chn][0][j] = sqrt(fftenergy[j]);
00983 r2 = r2 + fabs(r1);
00984 if (r2 != 0) {
00985 FLOAT const an = gfc->ax_sav[chn][0][j] = wsamp_l[0][j];
00986 FLOAT const bn = gfc->bx_sav[chn][0][j] =
00987 (j == 0 ? wsamp_l[0][0] : wsamp_l[0][BLKSIZE - j]);
00988 assert( den != 0 );
00989 den = r1 / den * 2.0;
00990 numre = (an + bn) - numre * den;
00991 numim = (an - bn) - numim * den;
00992 r2 = sqrt(numre * numre + numim * numim) / (r2 * 2.0);
00993 }
00994 gfc->cw[j] = r2;
00995 }
00996
00997
00998
00999
01000 for (; j < gfc->cw_upper_index; j += 4) {
01001
01002 FLOAT rn, r1, r2;
01003 FLOAT numre, numim, den;
01004 k = (j + 2) / 4;
01005
01006 r1 = fftenergy_s[0][k];
01007 if (r1 != 0.0) {
01008 FLOAT const a1 = (*wsamp_s)[0][k];
01009 FLOAT const b1 = (*wsamp_s)[0][BLKSIZE_s - k];
01010 numre = a1 * b1;
01011 numim = r1 - b1 * b1;
01012 den = r1;
01013 r1 = sqrt(r1);
01014 }
01015 else {
01016 den = numre = 1.0;
01017 numim = 0.0;
01018 }
01019
01020
01021 r2 = fftenergy_s[2][k];
01022 if (r2 != 0.0) {
01023 FLOAT const a2 = (*wsamp_s)[2][k];
01024 FLOAT const b2 = (*wsamp_s)[2][BLKSIZE_s - k];
01025
01026 FLOAT const tmp2 = (numim + numre) * (a2 + b2) * 0.5f;
01027 FLOAT const tmp1 = tmp2 - a2 * numre;
01028 numre = tmp2 - b2 * numim;
01029 numim = tmp1;
01030
01031 r2 = sqrt(r2);
01032 den *= r2;
01033 }
01034
01035
01036 rn = sqrt(fftenergy_s[1][k]) + fabs(2 * r1 - r2);
01037 if (rn != 0) {
01038 FLOAT const an = (*wsamp_s)[1][k];
01039 FLOAT const bn = (*wsamp_s)[1][BLKSIZE_s - k];
01040 assert( den != 0 );
01041 den = (2 * r1 - r2) / den * 2.0f;
01042 numre = (an + bn) - numre * den;
01043 numim = (an - bn) - numim * den;
01044 rn = sqrt(numre * numre + numim * numim) / (rn * 2.0f);
01045 }
01046 gfc->cw[j + 1] = gfc->cw[j + 2] = gfc->cw[j + 3] = gfc->cw[j] = rn;
01047 }
01048
01049
01050
01051
01052
01053
01054 for (b = j = 0; j < gfc->cw_upper_index && gfc->numlines_l[b] && b < gfc->npart_l; ++b) {
01055 FLOAT m = 0;
01056 FLOAT ebb = 0, cbb = 0;
01057 int const n = gfc->numlines_l[b];
01058 for (i = 0; i < n; ++i, ++j) {
01059 FLOAT const el = fftenergy[j];
01060 FLOAT const el_cw = el * gfc->cw[j];
01061 ebb += NON_LINEAR_SCALE_ITEM(el);
01062
01063 cbb += NON_LINEAR_SCALE_ITEM(el_cw);
01064 if (m < el)
01065 m = el;
01066 }
01067 eb[b] = NON_LINEAR_SCALE_SUM(ebb);
01068 cb[b] = NON_LINEAR_SCALE_SUM(cbb);
01069 max[b] = m;
01070 }
01071 for (; b < gfc->npart_l; ++b) {
01072 FLOAT m = 0, ebb = 0;
01073 int const n = gfc->numlines_l[b];
01074 for (i = 0; i < n; ++i, ++j) {
01075 FLOAT const el = fftenergy[j];
01076 ebb += NON_LINEAR_SCALE_ITEM(el);
01077 if (m < el)
01078 m = el;
01079 }
01080 eb[b] = NON_LINEAR_SCALE_SUM(ebb);
01081
01082 cb[b] = NON_LINEAR_SCALE_SUM(ebb * 0.4);
01083 max[b] = m;
01084 }
01085 assert( b == gfc->npart_l );
01086 assert( j == 513 );
01087
01088
01089
01090
01091
01092
01093 gfc->pe[chn] = 0;
01094 k = 0;
01095 for (b = 0; b < gfc->npart_l; b++) {
01096 FLOAT tbb, ecb, ctb, reduction;
01097 int kk;
01098 ecb = ctb = 0.;
01099 for (kk = gfc->s3ind[b][0]; kk <= gfc->s3ind[b][1]; kk++) {
01100
01101 ecb += gfc->s3_ll[k] * eb[kk];
01102 ctb += gfc->s3_ll[k] * cb[kk];
01103 k++;
01104 }
01105
01106
01107
01108
01109
01110
01111
01112 tbb = ecb;
01113 if (tbb != 0.0) {
01114 tbb = ctb / tbb;
01115
01116
01117
01118 tbb = CONV1 + FAST_LOG_X(tbb, CONV2);
01119 if (tbb < 0.0)
01120 tbb = exp(-LN_TO_LOG10 * NMT);
01121 else if (tbb > 1.0)
01122 tbb = exp(-LN_TO_LOG10 * TMN);
01123 else
01124 tbb = exp(-LN_TO_LOG10 * ((TMN - NMT) * tbb + NMT));
01125 reduction = tbb * exp(LN_TO_LOG10 * NMT);
01126 }
01127 else {
01128 reduction = 1.0f;
01129 }
01130
01131
01132
01133
01134
01135
01136 tbb = Min(gfc->minval_l[b], tbb);
01137 ecb *= tbb;
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154 thr[b] = Min(ecb, rpelev * gfc->nb_1[chn][b]);
01155 if (gfc->blocktype_old[chn & 1] != SHORT_TYPE && thr[b] > rpelev2 * gfc->nb_2[chn][b])
01156 thr[b] = rpelev2 * gfc->nb_2[chn][b];
01157
01158 if (gfp->VBR == vbr_mtrh || gfp->VBR == vbr_mt) {
01159
01160
01161
01162
01163 FLOAT x = max[b];
01164 x *= gfc->numlines_l[b];
01165 x *= gfc->minval_l[b];
01166 #if 0
01167 x *= 0.5f;
01168 #else
01169 x *= 0.158489319246111;
01170 #endif
01171 x *= reduction;
01172 if (thr[b] > x) {
01173 thr[b] = x;
01174 }
01175 }
01176
01177 gfc->nb_2[chn][b] = gfc->nb_1[chn][b];
01178 gfc->nb_1[chn][b] = ecb;
01179
01180 ecb = Max(thr[b], gfc->ATH->cb_l[b] * gfc->ATH->adjust);
01181 if (ecb < eb[b]) {
01182 assert( eb[b] > 0 );
01183 gfc->pe[chn] -= gfc->numlines_l[b] * FAST_LOG(ecb / eb[b]);
01184 }
01185 }
01186
01187 determine_block_type(gfp, fftenergy_s, uselongblock, chn, gr_out, &gfc->pe[chn]);
01188
01189
01190 convert_partition2scalefac_l(gfc, eb, thr, chn);
01191
01192
01193 for (sblock = 0; sblock < 3; sblock++) {
01194 compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock);
01195 convert_partition2scalefac_s(gfc, eb, thr, chn, sblock);
01196 }
01197 }
01198
01199 if (gfp->interChRatio != 0.0)
01200 calc_interchannel_masking(gfp, gfp->interChRatio);
01201
01202 if (gfp->mode == JOINT_STEREO) {
01203 FLOAT db, x1, x2, sidetot = 0, tot = 0;
01204 msfix1(gfc);
01205 if (gfp->msfix != 0.0)
01206 ns_msfix(gfc, gfp->msfix, gfp->ATHlower * gfc->ATH->adjust);
01207
01208
01209
01210 for (sb = SBMAX_l / 4; sb < SBMAX_l; sb++) {
01211 x1 = Min(gfc->thm[0].l[sb], gfc->thm[1].l[sb]);
01212 x2 = Max(gfc->thm[0].l[sb], gfc->thm[1].l[sb]);
01213
01214 if (x2 >= 1000 * x1)
01215 db = 3;
01216 else {
01217 assert( x1 > 0 );
01218 db = FAST_LOG10(x2 / x1);
01219 }
01220
01221 sidetot += db;
01222 tot++;
01223 }
01224 assert( tot > 0 );
01225 ms_ratio_l = (sidetot / tot) * 0.7;
01226 ms_ratio_l = Min(ms_ratio_l, 0.5);
01227
01228 sidetot = 0;
01229 tot = 0;
01230 for (sblock = 0; sblock < 3; sblock++)
01231 for (sb = SBMAX_s / 4; sb < SBMAX_s; sb++) {
01232 x1 = Min(gfc->thm[0].s[sb][sblock], gfc->thm[1].s[sb][sblock]);
01233 x2 = Max(gfc->thm[0].s[sb][sblock], gfc->thm[1].s[sb][sblock]);
01234
01235 if (x2 >= 1000 * x1)
01236 db = 3;
01237 else {
01238 assert( x1 > 0 );
01239 db = FAST_LOG10(x2 / x1);
01240 }
01241 sidetot += db;
01242 tot++;
01243 }
01244 assert( tot > 0 );
01245 ms_ratio_s = (sidetot / tot) * 0.7;
01246 ms_ratio_s = Min(ms_ratio_s, .5);
01247 }
01248
01249
01250
01251
01252 block_type_set(gfp, uselongblock, blocktype_d, blocktype);
01253
01254 if (blocktype_d[0] == SHORT_TYPE && blocktype_d[1] == SHORT_TYPE)
01255 *ms_ratio = gfc->ms_ratio_s_old;
01256 else
01257 *ms_ratio = gfc->ms_ratio_l_old;
01258
01259 gfc->ms_ratio_s_old = ms_ratio_s;
01260 gfc->ms_ratio_l_old = ms_ratio_l;
01261
01262
01263 *ms_ratio_next = ms_ratio_l;
01264
01265 return 0;
01266 }
01267
01268
01269
01270
01271 static inline FLOAT
01272 NS_INTERP(FLOAT x, FLOAT y, FLOAT r)
01273 {
01274
01275 if (r == 1.0)
01276 return x;
01277 if (r == 0.0)
01278 return y;
01279 if (y > 0.0)
01280 return pow(x / y, r) * y;
01281 return 0.0;
01282 }
01283
01284
01285
01286 static FLOAT
01287 pecalc_s(III_psy_ratio const *mr, FLOAT masking_lower)
01288 {
01289 FLOAT pe_s;
01290 static const FLOAT regcoef_s[] = {
01291 11.8,
01292 13.6,
01293 17.2,
01294 32,
01295 46.5,
01296 51.3,
01297 57.5,
01298 67.1,
01299 71.5,
01300 84.6,
01301 97.6,
01302 130,
01303
01304 };
01305 int sb, sblock;
01306
01307 pe_s = 1236.28 / 4;
01308 for (sb = 0; sb < SBMAX_s - 1; sb++) {
01309 for (sblock = 0; sblock < 3; sblock++) {
01310 FLOAT x;
01311 if (regcoef_s[sb] == 0.0 || mr->thm.s[sb][sblock] <= 0.0 || mr->en.s[sb][sblock]
01312 <= (x = mr->thm.s[sb][sblock] * masking_lower))
01313 continue;
01314
01315 if (mr->en.s[sb][sblock] > x * 1e10)
01316 pe_s += regcoef_s[sb] * (10.0 * LOG10);
01317 else {
01318 assert( x > 0 );
01319 pe_s += regcoef_s[sb] * FAST_LOG10(mr->en.s[sb][sblock] / x);
01320 }
01321 }
01322 }
01323
01324 return pe_s;
01325 }
01326
01327 static FLOAT
01328 pecalc_l(III_psy_ratio const *mr, FLOAT masking_lower)
01329 {
01330 FLOAT pe_l;
01331 static const FLOAT regcoef_l[] = {
01332 6.8,
01333 5.8,
01334 5.8,
01335 6.4,
01336 6.5,
01337 9.9,
01338 12.1,
01339 14.4,
01340 15,
01341 18.9,
01342 21.6,
01343 26.9,
01344 34.2,
01345 40.2,
01346 46.8,
01347 56.5,
01348 60.7,
01349 73.9,
01350 85.7,
01351 93.4,
01352 126.1,
01353
01354 };
01355 int sb;
01356
01357 pe_l = 1124.23 / 4;
01358 for (sb = 0; sb < SBMAX_l - 1; sb++) {
01359 FLOAT x;
01360 if (mr->thm.l[sb] <= 0.0 || mr->en.l[sb] <= (x = mr->thm.l[sb] * masking_lower))
01361 continue;
01362
01363 if (mr->en.l[sb] > x * 1e10)
01364 pe_l += regcoef_l[sb] * (10.0 * LOG10);
01365 else
01366 pe_l += regcoef_l[sb] * FAST_LOG10(mr->en.l[sb] / x);
01367 }
01368
01369 return pe_l;
01370 }
01371
01372
01373
01374
01375 int
01376 L3psycho_anal_ns(lame_global_flags const *gfp,
01377 const sample_t * buffer[2], int gr_out,
01378 III_psy_ratio masking_ratio[2][2],
01379 III_psy_ratio masking_MS_ratio[2][2],
01380 FLOAT percep_entropy[2], FLOAT percep_MS_entropy[2],
01381 FLOAT energy[4], int blocktype_d[2])
01382 {
01383
01384
01385
01386
01387
01388 lame_internal_flags *const gfc = gfp->internal_flags;
01389
01390
01391 FLOAT wsamp_L[2][BLKSIZE];
01392 FLOAT wsamp_S[2][3][BLKSIZE_s];
01393
01394
01395 int blocktype[2], uselongblock[2];
01396
01397
01398 int numchn, chn;
01399 int b, i, j, k;
01400 int sb, sblock;
01401
01402
01403 FLOAT ns_hpfsmpl[2][576];
01404 FLOAT pcfact;
01405
01406 numchn = gfc->channels_out;
01407
01408 if (gfp->mode == JOINT_STEREO)
01409 numchn = 4;
01410
01411 if (gfp->VBR == vbr_off)
01412 pcfact = gfc->ResvMax == 0 ? 0 : ((FLOAT) gfc->ResvSize) / gfc->ResvMax * 0.5;
01413 else if (gfp->VBR == vbr_rh || gfp->VBR == vbr_mtrh || gfp->VBR == vbr_mt) {
01414
01415
01416 pcfact = 0.6;
01417 }
01418 else
01419 pcfact = 1.0;
01420
01421
01422
01423
01424
01425
01426
01427 for (chn = 0; chn < gfc->channels_out; chn++) {
01428 static const FLOAT fircoef[] = {
01429 -8.65163e-18 * 2, -0.00851586 * 2, -6.74764e-18 * 2, 0.0209036 * 2,
01430 -3.36639e-17 * 2, -0.0438162 * 2, -1.54175e-17 * 2, 0.0931738 * 2,
01431 -5.52212e-17 * 2, -0.313819 * 2
01432 };
01433
01434 const sample_t *const firbuf = &buffer[chn][576 - 350 - NSFIRLEN + 192];
01435 assert(sizeof(fircoef)/sizeof(fircoef[0]) == ((NSFIRLEN - 1) / 2));
01436 for (i = 0; i < 576; i++) {
01437 FLOAT sum1, sum2;
01438 sum1 = firbuf[i + 10];
01439 sum2 = 0.0;
01440 for (j = 0; j < ((NSFIRLEN - 1) / 2)-1; j += 2) {
01441 sum1 += fircoef[j] * (firbuf[i + j] + firbuf[i + NSFIRLEN - j]);
01442 sum2 += fircoef[j + 1] * (firbuf[i + j + 1] + firbuf[i + NSFIRLEN - j - 1]);
01443 }
01444 ns_hpfsmpl[chn][i] = sum1 + sum2;
01445 }
01446 masking_ratio[gr_out][chn].en = gfc->en[chn];
01447 masking_ratio[gr_out][chn].thm = gfc->thm[chn];
01448 if (numchn > 2) {
01449
01450
01451 masking_MS_ratio[gr_out][chn].en = gfc->en[chn + 2];
01452 masking_MS_ratio[gr_out][chn].thm = gfc->thm[chn + 2];
01453 }
01454 }
01455
01456 for (chn = 0; chn < numchn; chn++) {
01457 FLOAT(*wsamp_l)[BLKSIZE];
01458 FLOAT(*wsamp_s)[3][BLKSIZE_s];
01459 FLOAT en_subshort[12];
01460 FLOAT en_short[4] = { 0 };
01461 FLOAT attack_intensity[12];
01462 int ns_uselongblock = 1;
01463 FLOAT attackThreshold;
01464 FLOAT max[CBANDS], avg[CBANDS];
01465 int ns_attacks[4] = { 0 };
01466 FLOAT fftenergy[HBLKSIZE];
01467 FLOAT fftenergy_s[3][HBLKSIZE_s];
01468
01469 FLOAT eb[CBANDS + 1], eb2[CBANDS];
01470 FLOAT thr[CBANDS + 1];
01471
01472
01473
01474
01475
01476
01477
01478
01479 static const FLOAT tab[] = {
01480 1.0 ,
01481 0.79433 ,
01482 0.63096 ,
01483 0.63096 ,
01484 0.63096 ,
01485 0.63096 ,
01486 0.63096 ,
01487 0.25119 ,
01488 0.11749
01489 };
01490
01491
01492
01493
01494
01495 assert(gfc->npart_s <= CBANDS);
01496 assert(gfc->npart_l <= CBANDS);
01497 eb[gfc->npart_s] = 0;
01498 thr[gfc->npart_s] = 0;
01499 eb[gfc->npart_l] = 0;
01500 thr[gfc->npart_l] = 0;
01501
01502
01503
01504
01505
01506 for (i = 0; i < 3; i++) {
01507 en_subshort[i] = gfc->nsPsy.last_en_subshort[chn][i + 6];
01508 assert(gfc->nsPsy.last_en_subshort[chn][i + 4] > 0);
01509 attack_intensity[i]
01510 = en_subshort[i] / gfc->nsPsy.last_en_subshort[chn][i + 4];
01511 en_short[0] += en_subshort[i];
01512 }
01513
01514 if (chn == 2) {
01515 for (i = 0; i < 576; i++) {
01516 FLOAT l, r;
01517 l = ns_hpfsmpl[0][i];
01518 r = ns_hpfsmpl[1][i];
01519 ns_hpfsmpl[0][i] = l + r;
01520 ns_hpfsmpl[1][i] = l - r;
01521 }
01522 }
01523 {
01524 FLOAT const *pf = ns_hpfsmpl[chn & 1];
01525 for (i = 0; i < 9; i++) {
01526 FLOAT const *const pfe = pf + 576 / 9;
01527 FLOAT p = 1.;
01528 for (; pf < pfe; pf++)
01529 if (p < fabs(*pf))
01530 p = fabs(*pf);
01531
01532 gfc->nsPsy.last_en_subshort[chn][i] = en_subshort[i + 3] = p;
01533 en_short[1 + i / 3] += p;
01534 if (p > en_subshort[i + 3 - 2]) {
01535 assert(en_subshort[i + 3 - 2] > 0);
01536 p = p / en_subshort[i + 3 - 2];
01537 }
01538 else if (en_subshort[i + 3 - 2] > p * 10.0) {
01539 assert( p > 0 );
01540 p = en_subshort[i + 3 - 2] / (p * 10.0);
01541 }
01542 else
01543 p = 0.0;
01544 attack_intensity[i + 3] = p;
01545 }
01546 }
01547
01548 if (gfp->analysis) {
01549 FLOAT x = attack_intensity[0];
01550 for (i = 1; i < 12; i++)
01551 if (x < attack_intensity[i])
01552 x = attack_intensity[i];
01553 gfc->pinfo->ers[gr_out][chn] = gfc->pinfo->ers_save[chn];
01554 gfc->pinfo->ers_save[chn] = x;
01555 }
01556
01557
01558 attackThreshold = (chn == 3)
01559 ? gfc->nsPsy.attackthre_s : gfc->nsPsy.attackthre;
01560 for (i = 0; i < 12; i++)
01561 if (!ns_attacks[i / 3] && attack_intensity[i] > attackThreshold)
01562 ns_attacks[i / 3] = (i % 3) + 1;
01563
01564
01565
01566 for (i = 1; i < 4; i++) {
01567 float ratio;
01568 if (en_short[i - 1] > en_short[i]) {
01569 assert( en_short[i] > 0 );
01570 ratio = en_short[i - 1] / en_short[i];
01571 }
01572 else {
01573 assert( en_short[i-1] > 0 );
01574 ratio = en_short[i] / en_short[i - 1];
01575 }
01576 if (ratio < 1.7) {
01577 ns_attacks[i] = 0;
01578 if (i == 1)
01579 ns_attacks[0] = 0;
01580 }
01581 }
01582
01583 if (ns_attacks[0] && gfc->nsPsy.last_attacks[chn])
01584 ns_attacks[0] = 0;
01585
01586 if (gfc->nsPsy.last_attacks[chn] == 3 ||
01587 ns_attacks[0] + ns_attacks[1] + ns_attacks[2] + ns_attacks[3]) {
01588 ns_uselongblock = 0;
01589
01590 if (ns_attacks[1] && ns_attacks[0])
01591 ns_attacks[1] = 0;
01592 if (ns_attacks[2] && ns_attacks[1])
01593 ns_attacks[2] = 0;
01594 if (ns_attacks[3] && ns_attacks[2])
01595 ns_attacks[3] = 0;
01596 }
01597
01598 if (chn < 2) {
01599 uselongblock[chn] = ns_uselongblock;
01600 }
01601 else {
01602 if (ns_uselongblock == 0) {
01603 uselongblock[0] = uselongblock[1] = 0;
01604 }
01605 }
01606
01607
01608
01609
01610 energy[chn] = gfc->tot_ener[chn];
01611
01612
01613
01614
01615 wsamp_s = wsamp_S + (chn & 1);
01616 wsamp_l = wsamp_L + (chn & 1);
01617 compute_ffts(gfp, fftenergy, fftenergy_s, wsamp_l, wsamp_s, gr_out, chn, buffer);
01618
01619
01620 for (sblock = 0; sblock < 3; sblock++) {
01621 FLOAT enn, thmm;
01622 compute_masking_s(gfp, fftenergy_s, eb, thr, chn, sblock);
01623 convert_partition2scalefac_s(gfc, eb, thr, chn, sblock);
01624
01625
01626 for (sb = 0; sb < SBMAX_s; sb++) {
01627 thmm = gfc->thm[chn].s[sb][sblock];
01628
01629 thmm *= NS_PREECHO_ATT0;
01630 if (ns_attacks[sblock] >= 2 || ns_attacks[sblock + 1] == 1) {
01631 int const idx = (sblock != 0) ? sblock - 1 : 2;
01632 double const p = NS_INTERP(gfc->thm[chn].s[sb][idx],
01633 thmm, NS_PREECHO_ATT1 * pcfact);
01634 thmm = Min(thmm, p);
01635 }
01636
01637 if (ns_attacks[sblock] == 1) {
01638 int const idx = (sblock != 0) ? sblock - 1 : 2;
01639 double const p = NS_INTERP(gfc->thm[chn].s[sb][idx],
01640 thmm, NS_PREECHO_ATT2 * pcfact);
01641 thmm = Min(thmm, p);
01642 }
01643 else if ((sblock != 0 && ns_attacks[sblock - 1] == 3)
01644 || (sblock == 0 && gfc->nsPsy.last_attacks[chn] == 3)) {
01645 int const idx = (sblock != 2) ? sblock + 1 : 0;
01646 double const p = NS_INTERP(gfc->thm[chn].s[sb][idx],
01647 thmm, NS_PREECHO_ATT2 * pcfact);
01648 thmm = Min(thmm, p);
01649 }
01650
01651
01652 enn = en_subshort[sblock * 3 + 3] + en_subshort[sblock * 3 + 4]
01653 + en_subshort[sblock * 3 + 5];
01654 if (en_subshort[sblock * 3 + 5] * 6 < enn) {
01655 thmm *= 0.5;
01656 if (en_subshort[sblock * 3 + 4] * 6 < enn)
01657 thmm *= 0.5;
01658 }
01659
01660 gfc->thm[chn].s[sb][sblock] = thmm;
01661 }
01662 }
01663 gfc->nsPsy.last_attacks[chn] = ns_attacks[2];
01664
01665
01666
01667
01668 for (b = j = 0; b < gfc->npart_l; ++b) {
01669 FLOAT ebb = 0, m = 0;
01670 for (i = 0; i < gfc->numlines_l[b]; ++i, ++j) {
01671 FLOAT const el = fftenergy[j];
01672 assert(el >= 0);
01673 ebb += el;
01674 if (m < el)
01675 m = el;
01676 }
01677 eb[b] = ebb;
01678 max[b] = m;
01679 avg[b] = ebb * gfc->rnumlines_l[b];
01680 assert( gfc->rnumlines_l[b] >= 0 );
01681 assert( ebb >= 0 );
01682 assert( eb[b] >= 0 );
01683 assert( max[b] >= 0 );
01684 assert( avg[b] >= 0 );
01685 }
01686 assert( b == gfc->npart_l );
01687 assert( j == 513 );
01688 {
01689 FLOAT m, a;
01690 int const last_tab_entry = sizeof(tab) / sizeof(tab[0])-1;
01691 b = 0;
01692 a = avg[b] + avg[b+1];
01693 assert(a >= 0);
01694 if (a != 0.0) {
01695 m = max[b];
01696 if (m < max[b+1])
01697 m = max[b+1];
01698 assert( (gfc->numlines_l[b] + gfc->numlines_l[b+1] - 1) > 0 );
01699 a = 20.0 * (m * 2.0 - a)
01700 / (a * (gfc->numlines_l[b] + gfc->numlines_l[b+1] - 1));
01701 k = (int) a;
01702 if (k > last_tab_entry)
01703 k = last_tab_entry;
01704 a = eb[b] * tab[k];
01705 }
01706 eb2[b] = a;
01707
01708 for (b = 1; b < gfc->npart_l - 1; b++) {
01709 a = avg[b - 1] + avg[b] + avg[b + 1];
01710 assert( a >= 0 );
01711 if (a != 0.0) {
01712 m = max[b - 1];
01713 if (m < max[b])
01714 m = max[b];
01715 if (m < max[b + 1])
01716 m = max[b + 1];
01717 assert( (gfc->numlines_l[b - 1] + gfc->numlines_l[b] + gfc->numlines_l[b + 1] -
01718 1) > 0 );
01719 a = 20.0 * (m * 3.0 - a)
01720 / (a *
01721 (gfc->numlines_l[b - 1] + gfc->numlines_l[b] + gfc->numlines_l[b + 1] -
01722 1));
01723 k = (int) a;
01724 if (k > last_tab_entry)
01725 k = last_tab_entry;
01726 a = eb[b] * tab[k];
01727 }
01728 eb2[b] = a;
01729 assert(eb2[b] >= 0);
01730 }
01731 assert( b > 0 );
01732 assert( b == gfc->npart_l-1 );
01733
01734 a = avg[b-1] + avg[b];
01735 assert( a >= 0 );
01736 if (a > 0.0) {
01737 m = max[b-1];
01738 if (m < max[b])
01739 m = max[b];
01740 assert( (gfc->numlines_l[b-1] + gfc->numlines_l[b] - 1) > 0 );
01741 a = 20.0 * (m * 2.0 - a)
01742 / (a *
01743 (gfc->numlines_l[b-1] + gfc->numlines_l[b] - 1));
01744 k = (int) a;
01745 if (k > last_tab_entry)
01746 k = last_tab_entry;
01747 a = eb[b] * tab[k];
01748 }
01749 eb2[b] = a;
01750 assert(b == (gfc->npart_l - 1));
01751 assert(eb2[b] >= 0);
01752 }
01753
01754
01755
01756
01757
01758 #undef GPSYCHO_BLOCK_TYPE_DECISION
01759 #ifdef GPSYCHO_BLOCK_TYPE_DECISION
01760 {
01761 FLOAT pe = 0;
01762 #endif
01763 k = 0;
01764 for (b = 0; b < gfc->npart_l; b++) {
01765 FLOAT ecb;
01766
01767 int kk = gfc->s3ind[b][0];
01768 ecb = gfc->s3_ll[k++] * eb2[kk];
01769 while (++kk <= gfc->s3ind[b][1])
01770 ecb = mask_add(ecb, gfc->s3_ll[k++] * eb2[kk], kk, kk - b, gfc, 0);
01771 ecb *= 0.158489319246111;
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785 if (gfc->blocktype_old[chn & 1] == SHORT_TYPE)
01786 thr[b] = ecb;
01787 else
01788 thr[b] = NS_INTERP(Min(ecb,
01789 Min(rpelev * gfc->nb_1[chn][b],
01790 rpelev2 * gfc->nb_2[chn][b])), ecb, pcfact);
01791
01792 if (gfp->VBR == vbr_mtrh || gfp->VBR == vbr_mt) {
01793
01794
01795
01796
01797 FLOAT x = max[b];
01798 x *= gfc->numlines_l[b];
01799 x *= gfc->minval_l[b];
01800 #if 0
01801 x *= 0.5f;
01802 #else
01803 x *= 0.158489319246111;
01804 #endif
01805 if (eb[b] > 0.0f) {
01806 x *= eb2[b] / eb[b];
01807 }
01808 if (thr[b] > x) {
01809 thr[b] = x;
01810 }
01811 }
01812
01813 gfc->nb_2[chn][b] = gfc->nb_1[chn][b];
01814 gfc->nb_1[chn][b] = ecb;
01815 #ifdef GPSYCHO_BLOCK_TYPE_DECISION
01816
01817
01818
01819
01820 pe -= gfc->numlines_l[b] * FAST_LOG(ecb / eb[b]);
01821 #endif
01822 }
01823 #ifdef GPSYCHO_BLOCK_TYPE_DECISION
01824 determine_block_type(gfp, fftenergy_s, uselongblock, chn, gr_out, &pe);
01825 }
01826 #endif
01827
01828 convert_partition2scalefac_l(gfc, eb, thr, chn);
01829
01830 }
01831
01832 if (gfp->interChRatio != 0.0)
01833 calc_interchannel_masking(gfp, gfp->interChRatio);
01834
01835 if (gfp->mode == JOINT_STEREO) {
01836 FLOAT msfix;
01837 msfix1(gfc);
01838 msfix = gfp->msfix;
01839 if (msfix != 0.0)
01840 ns_msfix(gfc, msfix, gfp->ATHlower * gfc->ATH->adjust);
01841 }
01842
01843
01844
01845
01846 block_type_set(gfp, uselongblock, blocktype_d, blocktype);
01847
01848
01849
01850
01851 for (chn = 0; chn < numchn; chn++) {
01852 FLOAT *ppe;
01853 int type;
01854 III_psy_ratio const *mr;
01855
01856 if (chn > 1) {
01857 ppe = percep_MS_entropy - 2;
01858 type = NORM_TYPE;
01859 if (blocktype_d[0] == SHORT_TYPE || blocktype_d[1] == SHORT_TYPE)
01860 type = SHORT_TYPE;
01861 mr = &masking_MS_ratio[gr_out][chn - 2];
01862 }
01863 else {
01864 ppe = percep_entropy;
01865 type = blocktype_d[chn];
01866 mr = &masking_ratio[gr_out][chn];
01867 }
01868
01869 if (type == SHORT_TYPE)
01870 ppe[chn] = pecalc_s(mr, gfc->masking_lower);
01871 else
01872 ppe[chn] = pecalc_l(mr, gfc->masking_lower);
01873
01874
01875 if (gfp->analysis)
01876 gfc->pinfo->pe[gr_out][chn] = ppe[chn];
01877
01878 }
01879 return 0;
01880 }
01881
01882
01883
01884
01885
01886
01887
01888
01889 static FLOAT
01890 s3_func(FLOAT bark)
01891 {
01892 FLOAT tempx, x, tempy, temp;
01893 tempx = bark;
01894 if (tempx >= 0)
01895 tempx *= 3;
01896 else
01897 tempx *= 1.5;
01898
01899 if (tempx >= 0.5 && tempx <= 2.5) {
01900 temp = tempx - 0.5;
01901 x = 8.0 * (temp * temp - 2.0 * temp);
01902 }
01903 else
01904 x = 0.0;
01905 tempx += 0.474;
01906 tempy = 15.811389 + 7.5 * tempx - 17.5 * sqrt(1.0 + tempx * tempx);
01907
01908 if (tempy <= -60.0)
01909 return 0.0;
01910
01911 tempx = exp((x + tempy) * LN_TO_LOG10);
01912
01913
01914
01915
01916
01917
01918
01919
01920 tempx /= .6609193;
01921 return tempx;
01922 }
01923
01924 static int
01925 init_numline(int *numlines, int *bo, int *bm,
01926 FLOAT * bval, FLOAT * bval_width, FLOAT * mld, FLOAT * bo_w,
01927 FLOAT sfreq, int blksize, int const *scalepos, FLOAT deltafreq, int sbmax)
01928 {
01929 FLOAT b_frq[CBANDS+1];
01930 FLOAT f_tmp;
01931 FLOAT sample_freq_frac = sfreq / ( sbmax > 15 ? 2*576 : 2*192 );
01932 int partition[HBLKSIZE] = { 0 };
01933 int i, j, k;
01934 int sfb;
01935 sfreq /= blksize;
01936 j = 0;
01937
01938
01939 for (i = 0; i < CBANDS; i++) {
01940 FLOAT bark1;
01941 int j2;
01942 bark1 = freq2bark(sfreq * j);
01943
01944 b_frq[i] = sfreq * j;
01945
01946 for (j2 = j; freq2bark(sfreq * j2) - bark1 < DELBARK && j2 <= blksize / 2; j2++);
01947
01948 numlines[i] = j2 - j;
01949
01950 while (j < j2)
01951 partition[j++] = i;
01952 if (j > blksize / 2) {
01953 j = blksize / 2;
01954 ++i;
01955 break;
01956 }
01957 }
01958 b_frq[i] = sfreq * j;
01959
01960 for (sfb = 0; sfb < sbmax; sfb++) {
01961 int i1, i2, start, end;
01962 FLOAT arg;
01963 start = scalepos[sfb];
01964 end = scalepos[sfb + 1];
01965
01966 i1 = floor(.5 + deltafreq * (start - .5));
01967 if (i1 < 0)
01968 i1 = 0;
01969 i2 = floor(.5 + deltafreq * (end - .5));
01970
01971 if (i2 > blksize / 2)
01972 i2 = blksize / 2;
01973
01974 bm[sfb] = (partition[i1] + partition[i2]) / 2;
01975 bo[sfb] = partition[i2];
01976
01977 f_tmp = sample_freq_frac * end;
01978
01979 bo_w[sfb] = (f_tmp-b_frq[bo[sfb]])/(b_frq[bo[sfb]+1]-b_frq[bo[sfb]]);
01980 if ( bo_w[sfb] < 0 ) {
01981 bo_w[sfb] = 0;
01982 }
01983 else {
01984 if ( bo_w[sfb] > 1 ) {
01985 bo_w[sfb] = 1;
01986 }
01987 }
01988
01989
01990 arg = freq2bark(sfreq * scalepos[sfb] * deltafreq);
01991 arg = (Min(arg, 15.5) / 15.5);
01992
01993 mld[sfb] = pow(10.0, 1.25 * (1 - cos(PI * arg)) - 2.5);
01994 }
01995
01996
01997 j = 0;
01998 for (k = 0; k < i + 1; k++) {
01999 int const w = numlines[k];
02000 FLOAT bark1, bark2;
02001
02002 bark1 = freq2bark(sfreq * (j));
02003 bark2 = freq2bark(sfreq * (j + w - 1));
02004 bval[k] = .5 * (bark1 + bark2);
02005
02006 bark1 = freq2bark(sfreq * (j - .5));
02007 bark2 = freq2bark(sfreq * (j + w - .5));
02008 bval_width[k] = bark2 - bark1;
02009 j += w;
02010 }
02011
02012 return i + 1;
02013 }
02014
02015 static int
02016 init_s3_values(lame_global_flags const *gfp,
02017 FLOAT ** p,
02018 int (*s3ind)[2], int npart, FLOAT const *bval, FLOAT const *bval_width,
02019 FLOAT const *norm)
02020 {
02021 FLOAT s3[CBANDS][CBANDS];
02022
02023
02024
02025 int const flag = (gfp->VBR == vbr_mtrh || gfp->VBR == vbr_mt);
02026 int i, j, k;
02027 int numberOfNoneZero = 0;
02028
02029
02030
02031
02032
02033
02034
02035 for (i = 0; i < npart; i++) {
02036 FLOAT sum = 0.f;
02037 for (j = 0; j < npart; j++) {
02038 FLOAT v = s3_func(bval[i] - bval[j]) * bval_width[j];
02039 sum += v;
02040 s3[i][j] = v * norm[i];
02041 }
02042 if (flag && sum > 0.f) {
02043 for (j = 0; j < npart; j++) {
02044 s3[i][j] /= sum;
02045 }
02046 }
02047 }
02048 for (i = 0; i < npart; i++) {
02049 for (j = 0; j < npart; j++) {
02050 if (s3[i][j] != 0.0f)
02051 break;
02052 }
02053 s3ind[i][0] = j;
02054
02055 for (j = npart - 1; j > 0; j--) {
02056 if (s3[i][j] != 0.0f)
02057 break;
02058 }
02059 s3ind[i][1] = j;
02060 numberOfNoneZero += (s3ind[i][1] - s3ind[i][0] + 1);
02061 }
02062 *p = malloc(sizeof(FLOAT) * numberOfNoneZero);
02063 if (!*p)
02064 return -1;
02065
02066 k = 0;
02067 for (i = 0; i < npart; i++)
02068 for (j = s3ind[i][0]; j <= s3ind[i][1]; j++)
02069 (*p)[k++] = s3[i][j];
02070
02071 return 0;
02072 }
02073
02074 int
02075 psymodel_init(lame_global_flags * gfp)
02076 {
02077 lame_internal_flags *const gfc = gfp->internal_flags;
02078 int i, j, b, sb, k;
02079
02080 FLOAT bval[CBANDS];
02081 FLOAT bval_width[CBANDS];
02082 FLOAT norm[CBANDS];
02083 FLOAT const sfreq = gfp->out_samplerate;
02084
02085 gfc->ms_ener_ratio_old = .25;
02086 gfc->blocktype_old[0] = gfc->blocktype_old[1] = NORM_TYPE;
02087
02088 for (i = 0; i < 4; ++i) {
02089 for (j = 0; j < CBANDS; ++j) {
02090 gfc->nb_1[i][j] = 1e20;
02091 gfc->nb_2[i][j] = 1e20;
02092 gfc->nb_s1[i][j] = gfc->nb_s2[i][j] = 1.0;
02093 }
02094 for (sb = 0; sb < SBMAX_l; sb++) {
02095 gfc->en[i].l[sb] = 1e20;
02096 gfc->thm[i].l[sb] = 1e20;
02097 }
02098 for (j = 0; j < 3; ++j) {
02099 for (sb = 0; sb < SBMAX_s; sb++) {
02100 gfc->en[i].s[sb][j] = 1e20;
02101 gfc->thm[i].s[sb][j] = 1e20;
02102 }
02103 gfc->nsPsy.last_attacks[i] = 0;
02104 }
02105 for (j = 0; j < 9; j++)
02106 gfc->nsPsy.last_en_subshort[i][j] = 10.;
02107 }
02108
02109
02110
02111 j = (int)(gfc->PSY->cwlimit / (sfreq / BLKSIZE));
02112 if (j > HBLKSIZE - 4)
02113 j = HBLKSIZE - 4;
02114 if (j < CW_LOWER_INDEX)
02115 j = CW_LOWER_INDEX;
02116 gfc->cw_upper_index = j;
02117
02118 for (j = 0; j < HBLKSIZE; j++)
02119 gfc->cw[j] = 0.4f;
02120
02121
02122 gfc->loudness_sq_save[0] = gfc->loudness_sq_save[1] = 0.0;
02123
02124
02125
02126
02127
02128
02129
02130
02131 gfc->npart_l
02132 = init_numline(gfc->numlines_l, gfc->bo_l, gfc->bm_l,
02133 bval, bval_width, gfc->mld_l, gfc->PSY->bo_l_weight,
02134 sfreq, BLKSIZE, gfc->scalefac_band.l, BLKSIZE / (2.0 * 576), SBMAX_l);
02135 assert(gfc->npart_l <= CBANDS);
02136
02137 for (i = 0; i < gfc->npart_l; i++) {
02138 norm[i] = 1.0;
02139 if (gfc->numlines_l[i] > 0) {
02140 gfc->rnumlines_l[i] = 1.0 / gfc->numlines_l[i];
02141 }
02142 else {
02143 gfc->rnumlines_l[i] = 0;
02144 }
02145 }
02146 i = init_s3_values(gfp, &gfc->s3_ll, gfc->s3ind, gfc->npart_l, bval, bval_width, norm);
02147 if (i)
02148 return i;
02149
02150
02151 j = 0;
02152 for (i = 0; i < gfc->npart_l; i++) {
02153 double x;
02154
02155
02156 x = FLOAT_MAX;
02157 for (k = 0; k < gfc->numlines_l[i]; k++, j++) {
02158 FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE);
02159 FLOAT level;
02160
02161 level = ATHformula(freq * 1000, gfp) - 20;
02162 level = pow(10., 0.1 * level);
02163 level *= gfc->numlines_l[i];
02164 if (x > level)
02165 x = level;
02166 }
02167 gfc->ATH->cb_l[i] = x;
02168
02169
02170
02171
02172 x = (-20 + bval[i] * 20.0 / 10.0);
02173 if (bval[i] > 10)
02174 x = 0;
02175 gfc->minval_l[i] = pow(10.0, x / 10);
02176 }
02177
02178
02179
02180
02181 gfc->npart_s
02182 = init_numline(gfc->numlines_s, gfc->bo_s, gfc->bm_s,
02183 bval, bval_width, gfc->mld_s, gfc->PSY->bo_s_weight,
02184 sfreq, BLKSIZE_s, gfc->scalefac_band.s, BLKSIZE_s / (2.0 * 192), SBMAX_s);
02185 assert(gfc->npart_s <= CBANDS);
02186
02187
02188 j = 0;
02189 for (i = 0; i < gfc->npart_s; i++) {
02190 double x;
02191 double snr = -8.25;
02192 if (bval[i] >= 13)
02193 snr = -4.5 * (bval[i] - 13) / (24.0 - 13.0)
02194 - 8.25 * (bval[i] - 24) / (13.0 - 24.0);
02195
02196 norm[i] = pow(10.0, snr / 10.0);
02197
02198
02199 x = FLOAT_MAX;
02200 for (k = 0; k < gfc->numlines_s[i]; k++, j++) {
02201 FLOAT const freq = sfreq * j / (1000.0 * BLKSIZE_s);
02202 FLOAT level;
02203
02204 level = ATHformula(freq * 1000, gfp) - 20;
02205 level = pow(10., 0.1 * level);
02206 level *= gfc->numlines_s[i];
02207 if (x > level)
02208 x = level;
02209 }
02210 gfc->ATH->cb_s[i] = x;
02211
02212
02213
02214
02215 x = (-20 + bval[i] * 20.0 / 10.0);
02216 if (bval[i] > 10)
02217 x = 0;
02218 gfc->minval_s[i] = pow(10.0, x / 10);
02219 }
02220
02221 i = init_s3_values(gfp, &gfc->s3_ss, gfc->s3ind_s, gfc->npart_s, bval, bval_width, norm);
02222 if (i)
02223 return i;
02224
02225
02226 init_mask_add_max_values();
02227 init_fft(gfc);
02228
02229
02230 gfc->decay = exp(-1.0 * LOG10 / (temporalmask_sustain_sec * sfreq / 192.0));
02231
02232 if (gfp->psymodel == PSY_NSPSYTUNE) {
02233 FLOAT msfix;
02234 msfix = NS_MSFIX;
02235 if (gfp->exp_nspsytune & 2)
02236 msfix = 1.0;
02237 if (gfp->msfix != 0.0)
02238 msfix = gfp->msfix;
02239 gfp->msfix = msfix;
02240
02241
02242
02243
02244 for (b = 0; b < gfc->npart_l; b++)
02245 if (gfc->s3ind[b][1] > gfc->npart_l - 1)
02246 gfc->s3ind[b][1] = gfc->npart_l - 1;
02247 }
02248
02249
02250
02251
02252 #define frame_duration (576. * gfc->mode_gr / sfreq)
02253 gfc->ATH->decay = pow(10., -12. / 10. * frame_duration);
02254 gfc->ATH->adjust = 0.01;
02255 gfc->ATH->adjust_limit = 1.0;
02256 #undef frame_duration
02257
02258 gfc->bo_s[SBMAX_s - 1]--;
02259 assert(gfc->bo_l[SBMAX_l - 1] <= gfc->npart_l);
02260 assert(gfc->bo_s[SBMAX_s - 1] <= gfc->npart_s);
02261
02262 if (gfp->ATHtype != -1) {
02263
02264 FLOAT freq;
02265 FLOAT const freq_inc = (FLOAT)gfp->out_samplerate / (FLOAT)(BLKSIZE);
02266 FLOAT eql_balance = 0.0;
02267 freq = 0.0;
02268 for (i = 0; i < BLKSIZE / 2; ++i) {
02269
02270
02271 freq += freq_inc;
02272 gfc->ATH->eql_w[i] = 1. / pow(10, ATHformula(freq, gfp) / 10);
02273 eql_balance += gfc->ATH->eql_w[i];
02274 }
02275 eql_balance = 1.0 / eql_balance;
02276 for (i = BLKSIZE / 2; --i >= 0;) {
02277 gfc->ATH->eql_w[i] *= eql_balance;
02278 }
02279 }
02280 {
02281 int i = 0, j, b;
02282 for (b = j = 0; b < gfc->npart_s; ++b) {
02283 for (i = 0; i < gfc->numlines_s[b]; ++i) {
02284 ++j;
02285 }
02286 }
02287 assert( j == 129 );
02288 for (b = j = 0; b < gfc->npart_l; ++b) {
02289 for (i = 0; i < gfc->numlines_l[b]; ++i ) {
02290 ++j;
02291 }
02292 }
02293 assert( j == 513 );
02294 }
02295 return 0;
02296 }