JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_LadderFilter.cpp
Go to the documentation of this file.
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
29//==============================================================================
30template <typename SampleType>
32{
33 setSampleRate (SampleType (1000)); // intentionally setting unrealistic default
34 // sample rate to catch missing initialisation bugs
35 setResonance (SampleType (0));
36 setDrive (SampleType (1.2));
37
38 mode = Mode::LPF24;
39 setMode (Mode::LPF12);
40}
41
42//==============================================================================
43template <typename SampleType>
45{
46 if (newMode == mode)
47 return;
48
49 switch (newMode)
50 {
51 case Mode::LPF12: A = {{ SampleType (0), SampleType (0), SampleType (1), SampleType (0), SampleType (0) }}; comp = SampleType (0.5); break;
52 case Mode::HPF12: A = {{ SampleType (1), SampleType (-2), SampleType (1), SampleType (0), SampleType (0) }}; comp = SampleType (0); break;
53 case Mode::BPF12: A = {{ SampleType (0), SampleType (0), SampleType (-1), SampleType (1), SampleType (0) }}; comp = SampleType (0.5); break;
54 case Mode::LPF24: A = {{ SampleType (0), SampleType (0), SampleType (0), SampleType (0), SampleType (1) }}; comp = SampleType (0.5); break;
55 case Mode::HPF24: A = {{ SampleType (1), SampleType (-4), SampleType (6), SampleType (-4), SampleType (1) }}; comp = SampleType (0); break;
56 case Mode::BPF24: A = {{ SampleType (0), SampleType (0), SampleType (1), SampleType (-2), SampleType (1) }}; comp = SampleType (0.5); break;
57 default: jassertfalse; break;
58 }
59
60 static constexpr auto outputGain = SampleType (1.2);
61
62 for (auto& a : A)
63 a *= outputGain;
64
65 mode = newMode;
66 reset();
67}
68
69//==============================================================================
70template <typename SampleType>
72{
73 setSampleRate (SampleType (spec.sampleRate));
74 setNumChannels (spec.numChannels);
75 reset();
76}
77
78//==============================================================================
79template <typename SampleType>
81{
82 for (auto& s : state)
83 s.fill (SampleType (0));
84
85 cutoffTransformSmoother.setCurrentAndTargetValue (cutoffTransformSmoother.getTargetValue());
86 scaledResonanceSmoother.setCurrentAndTargetValue (scaledResonanceSmoother.getTargetValue());
87}
88
89//==============================================================================
90template <typename SampleType>
92{
93 jassert (newCutoff > SampleType (0));
94 cutoffFreqHz = newCutoff;
95 updateCutoffFreq();
96}
97
98//==============================================================================
99template <typename SampleType>
101{
102 jassert (newResonance >= SampleType (0) && newResonance <= SampleType (1));
103 resonance = newResonance;
104 updateResonance();
105}
106
107//==============================================================================
108template <typename SampleType>
110{
111 jassert (newDrive >= SampleType (1));
112
113 drive = newDrive;
114 gain = std::pow (drive, SampleType (-2.642)) * SampleType (0.6103) + SampleType (0.3903);
115 drive2 = drive * SampleType (0.04) + SampleType (0.96);
116 gain2 = std::pow (drive2, SampleType (-2.642)) * SampleType (0.6103) + SampleType (0.3903);
117}
118
119//==============================================================================
120template <typename SampleType>
121SampleType LadderFilter<SampleType>::processSample (SampleType inputValue, size_t channelToUse) noexcept
122{
123 auto& s = state[channelToUse];
124
125 const auto a1 = cutoffTransformValue;
126 const auto g = a1 * SampleType (-1) + SampleType (1);
127 const auto b0 = g * SampleType (0.76923076923);
128 const auto b1 = g * SampleType (0.23076923076);
129
130 const auto dx = gain * saturationLUT (drive * inputValue);
131 const auto a = dx + scaledResonanceValue * SampleType (-4) * (gain2 * saturationLUT (drive2 * s[4]) - dx * comp);
132
133 const auto b = b1 * s[0] + a1 * s[1] + b0 * a;
134 const auto c = b1 * s[1] + a1 * s[2] + b0 * b;
135 const auto d = b1 * s[2] + a1 * s[3] + b0 * c;
136 const auto e = b1 * s[3] + a1 * s[4] + b0 * d;
137
138 s[0] = a;
139 s[1] = b;
140 s[2] = c;
141 s[3] = d;
142 s[4] = e;
143
144 return a * A[0] + b * A[1] + c * A[2] + d * A[3] + e * A[4];
145}
146
147//==============================================================================
148template <typename SampleType>
149void LadderFilter<SampleType>::updateSmoothers() noexcept
150{
151 cutoffTransformValue = cutoffTransformSmoother.getNextValue();
152 scaledResonanceValue = scaledResonanceSmoother.getNextValue();
153}
154
155//==============================================================================
156template <typename SampleType>
157void LadderFilter<SampleType>::setSampleRate (SampleType newValue) noexcept
158{
159 jassert (newValue > SampleType (0));
160 cutoffFreqScaler = SampleType (-2.0 * juce::MathConstants<double>::pi) / newValue;
161
162 static constexpr SampleType smootherRampTimeSec = SampleType (0.05);
163 cutoffTransformSmoother.reset (newValue, smootherRampTimeSec);
164 scaledResonanceSmoother.reset (newValue, smootherRampTimeSec);
165
166 updateCutoffFreq();
167}
168
169//==============================================================================
170template class LadderFilter<float>;
171template class LadderFilter<double>;
172
173} // namespace juce::dsp
Multi-mode filter based on the Moog ladder filter.
LadderFilter()
Creates an uninitialised filter.
void setCutoffFrequencyHz(SampleType newCutoff) noexcept
Sets the cutoff frequency of the filter.
void prepare(const ProcessSpec &spec)
Initialises the filter.
void setDrive(SampleType newDrive) noexcept
Sets the amount of saturation in the filter.
void setMode(Mode newMode) noexcept
Sets filter mode.
void reset() noexcept
Resets the internal state variables of the filter.
void setResonance(SampleType newResonance) noexcept
Sets the resonance of the filter.
#define jassert(expression)
Platform-independent assertion macro.
#define jassertfalse
This will always cause an assertion failure.
Type unalignedPointerCast(void *ptr) noexcept
Casts a pointer to another type via void*, which suppresses the cast-align warning which sometimes ar...
Definition juce_Memory.h:88
T pow(T... args)
Commonly used mathematical constants.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...