| 643 | } |
| 644 | |
| 645 | static void decorrelation(PSContext *ps, float (*out)[32][2], const float (*s)[32][2], int is34) |
| 646 | { |
| 647 | float power[34][PS_QMF_TIME_SLOTS] = {{0}}; |
| 648 | float transient_gain[34][PS_QMF_TIME_SLOTS]; |
| 649 | float *peak_decay_nrg = ps->peak_decay_nrg; |
| 650 | float *power_smooth = ps->power_smooth; |
| 651 | float *peak_decay_diff_smooth = ps->peak_decay_diff_smooth; |
| 652 | float (*delay)[PS_QMF_TIME_SLOTS + PS_MAX_DELAY][2] = ps->delay; |
| 653 | float (*ap_delay)[PS_AP_LINKS][PS_QMF_TIME_SLOTS + PS_MAX_AP_DELAY][2] = ps->ap_delay; |
| 654 | const int8_t *k_to_i = is34 ? k_to_i_34 : k_to_i_20; |
| 655 | const float peak_decay_factor = 0.76592833836465f; |
| 656 | const float transient_impact = 1.5f; |
| 657 | const float a_smooth = 0.25f; //< Smoothing coefficient |
| 658 | int i, k, m, n; |
| 659 | int n0 = 0, nL = 32; |
| 660 | static const int link_delay[] = { 3, 4, 5 }; |
| 661 | static const float a[] = { 0.65143905753106f, |
| 662 | 0.56471812200776f, |
| 663 | 0.48954165955695f }; |
| 664 | |
| 665 | if (is34 != ps->is34bands_old) { |
| 666 | memset(ps->peak_decay_nrg, 0, sizeof(ps->peak_decay_nrg)); |
| 667 | memset(ps->power_smooth, 0, sizeof(ps->power_smooth)); |
| 668 | memset(ps->peak_decay_diff_smooth, 0, sizeof(ps->peak_decay_diff_smooth)); |
| 669 | memset(ps->delay, 0, sizeof(ps->delay)); |
| 670 | memset(ps->ap_delay, 0, sizeof(ps->ap_delay)); |
| 671 | } |
| 672 | |
| 673 | for (n = n0; n < nL; n++) { |
| 674 | for (k = 0; k < NR_BANDS[is34]; k++) { |
| 675 | int i = k_to_i[k]; |
| 676 | power[i][n] += s[k][n][0] * s[k][n][0] + s[k][n][1] * s[k][n][1]; |
| 677 | } |
| 678 | } |
| 679 | |
| 680 | //Transient detection |
| 681 | for (i = 0; i < NR_PAR_BANDS[is34]; i++) { |
| 682 | for (n = n0; n < nL; n++) { |
| 683 | float decayed_peak = peak_decay_factor * peak_decay_nrg[i]; |
| 684 | float denom; |
| 685 | peak_decay_nrg[i] = FFMAX(decayed_peak, power[i][n]); |
| 686 | power_smooth[i] += a_smooth * (power[i][n] - power_smooth[i]); |
| 687 | peak_decay_diff_smooth[i] += a_smooth * (peak_decay_nrg[i] - power[i][n] - peak_decay_diff_smooth[i]); |
| 688 | denom = transient_impact * peak_decay_diff_smooth[i]; |
| 689 | transient_gain[i][n] = (denom > power_smooth[i]) ? |
| 690 | power_smooth[i] / denom : 1.0f; |
| 691 | } |
| 692 | } |
| 693 | |
| 694 | //Decorrelation and transient reduction |
| 695 | // PS_AP_LINKS - 1 |
| 696 | // ----- |
| 697 | // | | Q_fract_allpass[k][m]*z^-link_delay[m] - a[m]*g_decay_slope[k] |
| 698 | //H[k][z] = z^-2 * phi_fract[k] * | | ---------------------------------------------------------------- |
| 699 | // | | 1 - a[m]*g_decay_slope[k]*Q_fract_allpass[k][m]*z^-link_delay[m] |
| 700 | // m = 0 |
| 701 | //d[k][z] (out) = transient_gain_mapped[k][z] * H[k][z] * s[k][z] |
| 702 | for (k = 0; k < NR_ALLPASS_BANDS[is34]; k++) { |
no test coverage detected