OpenShot Audio Library | OpenShotAudio  0.3.3
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 
27 namespace juce
28 {
29 namespace dsp
30 {
31 
32 //==============================================================================
33 template <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 //==============================================================================
44 template <typename Type>
45 void 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 //==============================================================================
66 template <typename Type>
68 {
69  setSampleRate (Type (spec.sampleRate));
70  setNumChannels (spec.numChannels);
71  reset();
72 }
73 
74 //==============================================================================
75 template <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 //==============================================================================
86 template <typename Type>
87 void LadderFilter<Type>::setCutoffFrequencyHz (Type newValue) noexcept
88 {
89  jassert (newValue > Type (0));
90  cutoffFreqHz = newValue;
91  updateCutoffFreq();
92 }
93 
94 //==============================================================================
95 template <typename Type>
96 void LadderFilter<Type>::setResonance (Type newValue) noexcept
97 {
98  jassert (newValue >= Type (0) && newValue <= Type (1));
99  resonance = newValue;
100  updateResonance();
101 }
102 
103 //==============================================================================
104 template <typename Type>
105 void 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 //==============================================================================
116 template <typename Type>
117 Type 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 //==============================================================================
144 template <typename Type>
145 void LadderFilter<Type>::updateSmoothers() noexcept
146 {
147  cutoffTransformValue = cutoffTransformSmoother.getNextValue();
148  scaledResonanceValue = scaledResonanceSmoother.getNextValue();
149 }
150 
151 //==============================================================================
152 template <typename Type>
153 void 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 //==============================================================================
166 template class LadderFilter<float>;
167 template class LadderFilter<double>;
168 
169 } // namespace dsp
170 } // namespace juce
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