| 800 | |
| 801 | template <bool bypass, bool dynamic_on, bool dynamic_bypass, typename DynamicFilterArrayType> |
| 802 | void Controller::processOneBandDynamic(DynamicFilterArrayType& dynamic_filters, const size_t i, |
| 803 | const std::span<double*> main_pointers, |
| 804 | const std::span<double*> side_pointers, |
| 805 | const size_t num_samples) { |
| 806 | if constexpr (dynamic_on) { |
| 807 | // copy side buffer |
| 808 | side_copy_pointers_.clear(); |
| 809 | for (size_t chan = 0; chan < side_pointers.size(); ++chan) { |
| 810 | zldsp::vector::copy(side_buffers[chan].data(), side_pointers[chan], num_samples); |
| 811 | side_copy_pointers_.emplace_back(side_buffers[chan].data()); |
| 812 | } |
| 813 | // calculate side total loudness if dynamic relative is on |
| 814 | double side_total_loudness = 0.0; |
| 815 | if (c_dynamic_th_relative_[i]) { |
| 816 | for (size_t chan = 0; chan < side_pointers.size(); ++chan) { |
| 817 | const auto side_sum_sqr = zldsp::vector::sum_sqr(side_copy_pointers_[chan], num_samples); |
| 818 | side_total_loudness += side_sum_sqr / static_cast<double>(num_samples); |
| 819 | } |
| 820 | side_total_loudness = zldsp::chore::squareGainToDecibels(side_total_loudness); |
| 821 | } |
| 822 | // process side filter |
| 823 | side_filters_[i].process(side_copy_pointers_, num_samples); |
| 824 | // copy side buffer to solo buffer if needed |
| 825 | if (c_solo_on_ && c_solo_side_ && c_solo_idx_ == i) { |
| 826 | switch (c_lrms_[i]) { |
| 827 | case FilterStereo::kStereo: { |
| 828 | zldsp::vector::copy(solo_pointers_[0], side_copy_pointers_[0], num_samples); |
| 829 | zldsp::vector::copy(solo_pointers_[1], side_copy_pointers_[1], num_samples); |
| 830 | break; |
| 831 | } |
| 832 | case FilterStereo::kLeft: |
| 833 | case FilterStereo::kMid: { |
| 834 | zldsp::vector::copy(solo_pointers_[0], side_copy_pointers_[0], num_samples); |
| 835 | break; |
| 836 | } |
| 837 | case FilterStereo::kRight: |
| 838 | case FilterStereo::kSide: { |
| 839 | zldsp::vector::copy(solo_pointers_[1], side_copy_pointers_[0], num_samples); |
| 840 | break; |
| 841 | } |
| 842 | } |
| 843 | } |
| 844 | // calculate side histogram loudness if dynamic learn is on |
| 845 | if (c_dynamic_th_learn_[i]) { |
| 846 | double side_current_loudness = 0.0; |
| 847 | for (size_t chan = 0; chan < side_pointers.size(); ++chan) { |
| 848 | const auto side_sum_sqr = zldsp::vector::sum_sqr(side_copy_pointers_[chan], num_samples); |
| 849 | side_current_loudness += side_sum_sqr / static_cast<double>(num_samples); |
| 850 | } |
| 851 | side_current_loudness = zldsp::chore::squareGainToDecibels(side_current_loudness); |
| 852 | // update histograms |
| 853 | slow_histograms_[i].setDecay(std::pow(slow_hist_unit_decay_, static_cast<double>(num_samples))); |
| 854 | slow_histograms_[i].push(side_current_loudness - side_total_loudness); |
| 855 | slow_histograms_[i].getPercentiles(hist_percentiles_, hist_target_temp_, hist_results_); |
| 856 | learned_thresholds_[i].store(hist_results_[1], |
| 857 | std::memory_order::relaxed); |
| 858 | learned_knees_[i].store(std::max(0.5 * (hist_results_[2] - hist_results_[0]), 2.0), |
| 859 | std::memory_order::relaxed); |
nothing calls this directly
no test coverage detected