OpenShot Library | OpenShotAudio 0.2.2
juce_LadderFilter.cpp
1/*
2 ==============================================================================
3
4 This file is part of the JUCE library.
5 Copyright (c) 2017 - ROLI Ltd.
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 5 End-User License
11 Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
12 27th April 2017).
13
14 End User License Agreement: www.juce.com/juce-5-licence
15 Privacy Policy: www.juce.com/juce-5-privacy-policy
16
17 Or: You may also use this code under the terms of the GPL v3 (see
18 www.gnu.org/licenses).
19
20 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22 DISCLAIMED.
23
24 ==============================================================================
25*/
26
27namespace juce
28{
29namespace dsp
30{
31
32//==============================================================================
33template <typename Type>
35{
36 setSampleRate (Type (1000)); // intentionally setting unrealistic default
37 // sample rate to catch missing initialisation bugs
38 setResonance (Type (0));
39 setDrive (Type (1.2));
40 setMode (Mode::LPF12);
41}
42
43//==============================================================================
44template <typename Type>
45void LadderFilter<Type>::setMode (Mode newValue) noexcept
46{
47 switch (newValue)
48 {
49 case Mode::LPF12: A = {{ Type (0), Type (0), Type (1), Type (0), Type (0) }}; comp = Type (0.5); break;
50 case Mode::HPF12: A = {{ Type (1), Type (-2), Type (1), Type (0), Type (0) }}; comp = Type (0); break;
51 case Mode::LPF24: A = {{ Type (0), Type (0), Type (0), Type (0), Type (1) }}; comp = Type (0.5); break;
52 case Mode::HPF24: A = {{ Type (1), Type (-4), Type (6), Type (-4), Type (1) }}; comp = Type (0); break;
53 default: jassertfalse; break;
54 }
55
56 static constexpr auto outputGain = Type (1.2);
57
58 for (auto& a : A)
59 a *= outputGain;
60
61 mode = newValue;
62 reset();
63}
64
65//==============================================================================
66template <typename Type>
68{
69 setSampleRate (Type (spec.sampleRate));
70 setNumChannels (spec.numChannels);
71 reset();
72}
73
74//==============================================================================
75template <typename Type>
77{
78 for (auto& s : state)
79 s.fill (Type (0));
80
81 cutoffTransformSmoother.setCurrentAndTargetValue (cutoffTransformSmoother.getTargetValue());
82 scaledResonanceSmoother.setCurrentAndTargetValue (scaledResonanceSmoother.getTargetValue());
83}
84
85//==============================================================================
86template <typename Type>
87void LadderFilter<Type>::setCutoffFrequencyHz (Type newValue) noexcept
88{
89 jassert (newValue > Type (0));
90 cutoffFreqHz = newValue;
91 updateCutoffFreq();
92}
93
94//==============================================================================
95template <typename Type>
96void LadderFilter<Type>::setResonance (Type newValue) noexcept
97{
98 jassert (newValue >= Type (0) && newValue <= Type (1));
99 resonance = newValue;
100 updateResonance();
101}
102
103//==============================================================================
104template <typename Type>
105void LadderFilter<Type>::setDrive (Type newValue) noexcept
106{
107 jassert (newValue >= Type (1));
108
109 drive = newValue;
110 gain = std::pow (drive, Type (-2.642)) * Type (0.6103) + Type (0.3903);
111 drive2 = drive * Type (0.04) + Type (0.96);
112 gain2 = std::pow (drive2, Type (-2.642)) * Type (0.6103) + Type (0.3903);
113}
114
115//==============================================================================
116template <typename Type>
117Type LadderFilter<Type>::processSample (Type inputValue, size_t channelToUse) noexcept
118{
119 auto& s = state[channelToUse];
120
121 const auto a1 = cutoffTransformValue;
122 const auto g = a1 * Type (-1) + Type (1);
123 const auto b0 = g * Type (0.76923076923);
124 const auto b1 = g * Type (0.23076923076);
125
126 const auto dx = gain * saturationLUT (drive * inputValue);
127 const auto a = dx + scaledResonanceValue * Type (-4) * (gain2 * saturationLUT (drive2 * s[4]) - dx * comp);
128
129 const auto b = b1 * s[0] + a1 * s[1] + b0 * a;
130 const auto c = b1 * s[1] + a1 * s[2] + b0 * b;
131 const auto d = b1 * s[2] + a1 * s[3] + b0 * c;
132 const auto e = b1 * s[3] + a1 * s[4] + b0 * d;
133
134 s[0] = a;
135 s[1] = b;
136 s[2] = c;
137 s[3] = d;
138 s[4] = e;
139
140 return a * A[0] + b * A[1] + c * A[2] + d * A[3] + e * A[4];
141}
142
143//==============================================================================
144template <typename Type>
145void LadderFilter<Type>::updateSmoothers() noexcept
146{
147 cutoffTransformValue = cutoffTransformSmoother.getNextValue();
148 scaledResonanceValue = scaledResonanceSmoother.getNextValue();
149}
150
151//==============================================================================
152template <typename Type>
153void LadderFilter<Type>::setSampleRate (Type newValue) noexcept
154{
155 jassert (newValue > Type (0));
156 cutoffFreqScaler = Type (-2.0 * juce::MathConstants<double>::pi) / newValue;
157
158 static constexpr Type smootherRampTimeSec = Type (0.05);
159 cutoffTransformSmoother.reset (newValue, smootherRampTimeSec);
160 scaledResonanceSmoother.reset (newValue, smootherRampTimeSec);
161
162 updateCutoffFreq();
163}
164
165//==============================================================================
166template class LadderFilter<float>;
167template class LadderFilter<double>;
168
169} // namespace dsp
170} // namespace juce
Multi-mode filter based on the Moog ladder filter.
LadderFilter()
Creates an uninitialised filter.
void setResonance(Type newValue) noexcept
Sets the resonance of the filter.
void setMode(Mode newValue) noexcept
Sets filter mode.
void reset() noexcept
Resets the internal state variables of the filter.
void setDrive(Type newValue) noexcept
Sets the amount of saturation in the filter.
void prepare(const juce::dsp::ProcessSpec &spec)
Initialises the filter.
void setCutoffFrequencyHz(Type newValue) noexcept
Sets the cutoff frequency of the filter.
uint32 numChannels
The number of channels that the process() method will be expected to handle.
double sampleRate
The sample rate that will be used for the data that is sent to the processor.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...
Commonly used mathematical constants.