OpenShot Audio Library | OpenShotAudio  0.6.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 
26 namespace juce::dsp
27 {
28 
29 enum 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 
44 template <typename SampleType>
46 {
47 public:
48  //==============================================================================
49  using Mode = LadderFilterMode;
50 
51  //==============================================================================
53  LadderFilter();
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 
116 protected:
117  //==============================================================================
118  SampleType processSample (SampleType inputValue, size_t channelToUse) noexcept;
119  void updateSmoothers() noexcept;
120 
121 private:
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