OpenShot Audio Library | OpenShotAudio 0.4.0
juce_LadderFilter.h
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2022 - Raw Material Software Limited
6
7 JUCE is an open source library subject to commercial or open-source
8 licensing.
9
10 By using JUCE, you agree to the terms of both the JUCE 7 End-User License
11 Agreement and JUCE Privacy Policy.
12
13 End User License Agreement: www.juce.com/juce-7-licence
14 Privacy Policy: www.juce.com/juce-privacy-policy
15
16 Or: You may also use this code under the terms of the GPL v3 (see
17 www.gnu.org/licenses).
18
19 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
20 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
21 DISCLAIMED.
22
23 ==============================================================================
24*/
25
26namespace juce::dsp
27{
28
29enum class LadderFilterMode
30{
31 LPF12, // low-pass 12 dB/octave
32 HPF12, // high-pass 12 dB/octave
33 BPF12, // band-pass 12 dB/octave
34 LPF24, // low-pass 24 dB/octave
35 HPF24, // high-pass 24 dB/octave
36 BPF24 // band-pass 24 dB/octave
37};
38
44template <typename SampleType>
46{
47public:
48 //==============================================================================
49 using Mode = LadderFilterMode;
50
51 //==============================================================================
54
56 void setEnabled (bool isEnabled) noexcept { enabled = isEnabled; }
57
59 void setMode (Mode newMode) noexcept;
60
62 void prepare (const ProcessSpec& spec);
63
65 size_t getNumChannels() const noexcept { return state.size(); }
66
68 void reset() noexcept;
69
74 void setCutoffFrequencyHz (SampleType newCutoff) noexcept;
75
80 void setResonance (SampleType newResonance) noexcept;
81
86 void setDrive (SampleType newDrive) noexcept;
87
88 //==============================================================================
89 template <typename ProcessContext>
90 void process (const ProcessContext& context) noexcept
91 {
92 const auto& inputBlock = context.getInputBlock();
93 auto& outputBlock = context.getOutputBlock();
94 const auto numChannels = outputBlock.getNumChannels();
95 const auto numSamples = outputBlock.getNumSamples();
96
97 jassert (inputBlock.getNumChannels() <= getNumChannels());
98 jassert (inputBlock.getNumChannels() == numChannels);
99 jassert (inputBlock.getNumSamples() == numSamples);
100
101 if (! enabled || context.isBypassed)
102 {
103 outputBlock.copyFrom (inputBlock);
104 return;
105 }
106
107 for (size_t n = 0; n < numSamples; ++n)
108 {
109 updateSmoothers();
110
111 for (size_t ch = 0; ch < numChannels; ++ch)
112 outputBlock.getChannelPointer (ch)[n] = processSample (inputBlock.getChannelPointer (ch)[n], ch);
113 }
114 }
115
116protected:
117 //==============================================================================
118 SampleType processSample (SampleType inputValue, size_t channelToUse) noexcept;
119 void updateSmoothers() noexcept;
120
121private:
122 //==============================================================================
123 void setSampleRate (SampleType newValue) noexcept;
124 void setNumChannels (size_t newValue) { state.resize (newValue); }
125 void updateCutoffFreq() noexcept { cutoffTransformSmoother.setTargetValue (std::exp (cutoffFreqHz * cutoffFreqScaler)); }
126 void updateResonance() noexcept { scaledResonanceSmoother.setTargetValue (jmap (resonance, SampleType (0.1), SampleType (1.0))); }
127
128 //==============================================================================
129 SampleType drive, drive2, gain, gain2, comp;
130
131 static constexpr size_t numStates = 5;
132 std::vector<std::array<SampleType, numStates>> state;
133 std::array<SampleType, numStates> A;
134
135 SmoothedValue<SampleType> cutoffTransformSmoother, scaledResonanceSmoother;
136 SampleType cutoffTransformValue, scaledResonanceValue;
137
138 LookupTableTransform<SampleType> saturationLUT { [] (SampleType x) { return std::tanh (x); },
139 SampleType (-5), SampleType (5), 128 };
140
141 SampleType cutoffFreqHz { SampleType (200) };
142 SampleType resonance;
143
144 SampleType cutoffFreqScaler;
145
146 Mode mode;
147 bool enabled = true;
148};
149
150} // namespace juce::dsp
void setTargetValue(FloatType newValue) noexcept
void setCutoffFrequencyHz(SampleType newCutoff) noexcept
void prepare(const ProcessSpec &spec)
void setDrive(SampleType newDrive) noexcept
void setEnabled(bool isEnabled) noexcept
void setMode(Mode newMode) noexcept
size_t getNumChannels() const noexcept
void setResonance(SampleType newResonance) noexcept