Skip to content

Commit f5bdde3

Browse files
committed
feat(zlp): add filter dynamic attach
1 parent 1a14be9 commit f5bdde3

8 files changed

Lines changed: 127 additions & 4 deletions

source/PluginProcessor.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ PluginProcessor::PluginProcessor() :
3131
a_bypass_(*parameters_.getRawParameterValue(zlp::PBypass::kID)) {
3232
for (size_t i = 0; i < zlp::kBandNum; ++i) {
3333
filter_attachments_[i] = std::make_unique<zlp::FilterAttach>(*this, parameters_, controller_, i);
34+
filter_dynamic_attachments_[i] = std::make_unique<zlp::FilterDynamicAttach>(*this, parameters_, controller_, i);
3435
}
3536
}
3637

source/PluginProcessor.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ class PluginProcessor final : public juce::AudioProcessor {
7575
private:
7676
zlp::Controller controller_;
7777
std::array<std::unique_ptr<zlp::FilterAttach>, zlp::kBandNum> filter_attachments_;
78+
std::array<std::unique_ptr<zlp::FilterDynamicAttach>, zlp::kBandNum> filter_dynamic_attachments_;
7879

7980
std::atomic<double> sample_rate_{48000.0};
8081
std::atomic<float>& a_bypass_;

source/zlp/controller.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ namespace zlp {
7272
return is_ext_side_;
7373
}
7474

75+
void setTargetGain(const size_t band, const float gain) {
76+
empty_target_gains_[band].store(gain, std::memory_order::relaxed);
77+
to_update_empty_targets_[band].signal();
78+
to_update_spec_response_.signal();
79+
to_update_.signal();
80+
}
81+
7582
void setSpecSmoothValue(const float smooth) {
7683
a_spec_smooth_value_.store(smooth, std::memory_order::relaxed);
7784
to_update_spec_smooth_.signal();
@@ -108,6 +115,18 @@ namespace zlp {
108115
to_update_.signal();
109116
}
110117

118+
void setDynamicON(const size_t idx, const bool dynamic_on) {
119+
a_dynamic_on_[idx].store(dynamic_on, std::memory_order::relaxed);
120+
to_update_dynamic_status_.signal();
121+
to_update_.signal();
122+
}
123+
124+
void setDynamicBypass(const size_t idx, const bool dynamic_bypass) {
125+
a_dynamic_bypass_[idx].store(dynamic_bypass, std::memory_order::relaxed);
126+
to_update_dynamic_status_.signal();
127+
to_update_.signal();
128+
}
129+
111130
void setDynamicMode(const size_t idx, const DynamicMode mode) {
112131
a_dynamic_mode_[idx].store(mode, std::memory_order::relaxed);
113132
to_update_dynamic_status_.signal();

source/zlp/filter_attach.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ namespace zlp {
1919
empty_(controller.getEmptyFilters()[idx]),
2020
scale_(*parameters.getRawParameterValue(PGainScale::kID)),
2121
gain_(*parameters.getRawParameterValue(PGain::kID + std::to_string(idx))),
22+
target_gain_(*parameters.getRawParameterValue(PTargetGain::kID + std::to_string(idx))),
2223
empty_update_flag_(controller.getEmptyUpdateFlags()[idx]),
2324
spec_update_flag_(controller.getSpecResponseUpdateFlag()),
2425
whole_update_flag_(controller.getUpdateFlag()) {
@@ -52,14 +53,22 @@ namespace zlp {
5253
empty_.setFreq(value);
5354
signal();
5455
} else if (parameter_ID.startsWith(PGain::kID)) {
55-
empty_.setGain(std::clamp(value * (scale_.load(std::memory_order::relaxed) / 100.f), -30.f, 30.f));
56+
const auto scale = scale_.load(std::memory_order::relaxed) * 0.01f;
57+
empty_.setGain(std::clamp(value * scale, -30.f, 30.f));
5658
signal();
5759
} else if (parameter_ID.startsWith(PQ::kID)) {
5860
empty_.setQ(value);
5961
signal();
62+
} else if (parameter_ID.startsWith(PTargetGain::kID)) {
63+
const auto scale = scale_.load(std::memory_order::relaxed) * 0.01f;
64+
controller_.setTargetGain(idx_, std::clamp(value * scale, -30.f,30.f));
6065
} else if (parameter_ID.startsWith(PGainScale::kID)) {
61-
empty_.setGain(std::clamp(gain_.load(std::memory_order::relaxed) * (value / 100.f), -30.f, 30.f));
66+
const auto scale = value * 0.01f;
67+
const auto gain = gain_.load(std::memory_order::relaxed);
68+
empty_.setGain(std::clamp(gain * scale, -30.f, 30.f));
6269
signal();
70+
const auto target_gain = target_gain_.load(std::memory_order::relaxed);
71+
controller_.setTargetGain(idx_, std::clamp(target_gain * scale, -30.f,30.f));
6372
}
6473
}
6574

source/zlp/filter_attach.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,14 @@ namespace zlp {
2929
zldsp::filter::Empty& empty_;
3030
std::atomic<float>& scale_;
3131
std::atomic<float>& gain_;
32+
std::atomic<float>& target_gain_;
3233
zlchore::thread::Notifier& empty_update_flag_;
3334
zlchore::thread::Notifier& spec_update_flag_;
3435
zlchore::thread::Notifier& whole_update_flag_;
3536

3637
static constexpr std::array kIDs{
3738
PFilterStatus::kID, PFilterType::kID, POrder::kID, PLRMode::kID,
38-
PFreq::kID, PGain::kID, PQ::kID,
39+
PFreq::kID, PGain::kID, PQ::kID, PTargetGain::kID
3940
};
4041

4142
void parameterChanged(const juce::String& parameter_ID, float value) override;
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
// Copyright (C) 2026 - zsliu98
2+
// This file is part of ZLSpectrumEqualizer
3+
//
4+
// ZLSpectrumEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation.
5+
//
6+
// ZLSpectrumEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7+
//
8+
// You should have received a copy of the GNU Affero General Public License along with ZLSpectrumEqualizer. If not, see <https://www.gnu.org/licenses/>.
9+
10+
#include "filter_dynamic_attach.hpp"
11+
12+
namespace zlp {
13+
FilterDynamicAttach::FilterDynamicAttach(juce::AudioProcessor& processor,
14+
juce::AudioProcessorValueTreeState& parameters,
15+
Controller& controller, size_t idx) :
16+
parameters_(parameters),
17+
controller_(controller),
18+
idx_(idx) {
19+
for (size_t i = 0; i < kIDs.size(); ++i) {
20+
const auto ID = kIDs[i] + std::to_string(idx_);
21+
parameters_.addParameterListener(ID, this);
22+
parameterChanged(ID, parameters.getRawParameterValue(ID)->load(std::memory_order::relaxed));
23+
}
24+
}
25+
26+
FilterDynamicAttach::~FilterDynamicAttach() {
27+
for (size_t i = 0; i < kIDs.size(); ++i) {
28+
parameters_.removeParameterListener(kIDs[i] + std::to_string(idx_), this);
29+
}
30+
}
31+
32+
void FilterDynamicAttach::parameterChanged(const juce::String& parameter_ID, const float value) {
33+
if (parameter_ID.startsWith(PDynamicON::kID)) {
34+
controller_.setDynamicON(idx_, value > .5f);
35+
} else if (parameter_ID.startsWith(PDynamicBypass::kID)) {
36+
controller_.setDynamicBypass(idx_, value > .5f);
37+
} else if (parameter_ID.startsWith(PDynamicMode::kID)) {
38+
controller_.setDynamicMode(idx_, static_cast<DynamicMode>(std::round(value)));
39+
} else if (parameter_ID.startsWith(PThresholdAbs::kID)) {
40+
controller_.setSpecThresholdAbs(idx_, value);
41+
} else if (parameter_ID.startsWith(PThresholdBand::kID)) {
42+
controller_.setSpecThresholdBand(idx_, value);
43+
} else if (parameter_ID.startsWith(PThresholdRel::kID)) {
44+
controller_.setSpecThresholdRel(idx_, value);
45+
} else if (parameter_ID.startsWith(PKneeW::kID)) {
46+
controller_.setSpecKnee(idx_, value);
47+
} else if (parameter_ID.startsWith(PAttack::kID)) {
48+
controller_.setSpecAttack(idx_, value);
49+
} else if (parameter_ID.startsWith(PRelease::kID)) {
50+
controller_.setSpecRelease(idx_, value);
51+
}
52+
}
53+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// Copyright (C) 2026 - zsliu98
2+
// This file is part of ZLSpectrumEqualizer
3+
//
4+
// ZLSpectrumEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation.
5+
//
6+
// ZLSpectrumEqualizer is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
7+
//
8+
// You should have received a copy of the GNU Affero General Public License along with ZLSpectrumEqualizer. If not, see <https://www.gnu.org/licenses/>.
9+
10+
#pragma once
11+
12+
#include "controller.hpp"
13+
#include "juce_helper/para_updater.hpp"
14+
15+
namespace zlp {
16+
class FilterDynamicAttach final : private juce::AudioProcessorValueTreeState::Listener {
17+
public:
18+
explicit FilterDynamicAttach(juce::AudioProcessor& processor,
19+
juce::AudioProcessorValueTreeState& parameters,
20+
Controller& controller,
21+
size_t idx);
22+
23+
~FilterDynamicAttach() override;
24+
25+
private:
26+
juce::AudioProcessorValueTreeState& parameters_;
27+
Controller& controller_;
28+
size_t idx_;
29+
30+
static constexpr std::array kIDs{
31+
PDynamicON::kID, PDynamicBypass::kID, PDynamicMode::kID,
32+
PThresholdAbs::kID, PThresholdBand::kID, PThresholdRel::kID, PKneeW::kID,
33+
PAttack::kID, PRelease::kID
34+
};
35+
36+
void parameterChanged(const juce::String& parameter_ID, float value) override;
37+
};
38+
}

source/zlp/zlp.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,4 +11,5 @@
1111

1212
#include "zlp_definitions.hpp"
1313
#include "controller.hpp"
14-
#include "filter_attach.hpp"
14+
#include "filter_attach.hpp"
15+
#include "filter_dynamic_attach.hpp"

0 commit comments

Comments
 (0)