OpenShot Audio Library | OpenShotAudio 0.3.2
Loading...
Searching...
No Matches
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>
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
void fill(const ParameterType &newValue) noexcept
Definition juce_Array.h:205
void setResonance(Type newValue) noexcept
void setMode(Mode newValue) noexcept
void setDrive(Type newValue) noexcept
void prepare(const juce::dsp::ProcessSpec &spec)
void setCutoffFrequencyHz(Type newValue) noexcept