OpenShot Audio Library | OpenShotAudio: juce_StateVariableFilter.h Source File

OpenShot Audio Library | OpenShotAudio 0.3.1

Loading...
Searching...
No Matches
juce_StateVariableFilter.h
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
35 namespace StateVariableFilter
36{
37 template <typename NumericType>
38 struct Parameters;
39
53 template <typename SampleType>
54 class Filter
55 {
56 public:
57 //==============================================================================
61 using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
62
64 using ParametersPtr = typename Parameters<NumericType>::Ptr;
65
66 //==============================================================================
68 Filter() : parameters (new Parameters<NumericType>) { reset(); }
69
70 Filter (ParametersPtr parametersToUse) : parameters (std::move (parametersToUse)) { reset(); }
71
73 Filter (const Filter&) = default;
74
76 Filter (Filter&&) = default;
77
78 //==============================================================================
80 void prepare (const ProcessSpec&) noexcept { reset(); }
81
83 void reset() noexcept { s1 = s2 = SampleType {0}; }
84
89 void snapToZero() noexcept { util::snapToZero (s1); util::snapToZero (s2); }
90
91 //==============================================================================
94 typename Parameters<NumericType>::Ptr parameters;
95
96 //==============================================================================
97 template <typename ProcessContext>
98 void process (const ProcessContext& context) noexcept
99 {
100 static_assert (std::is_same<typename ProcessContext::SampleType, SampleType>::value,
101 "The sample-type of the filter must match the sample-type supplied to this process callback");
102
103 if (context.isBypassed)
104 processInternal<true, ProcessContext> (context);
105 else
106 processInternal<false, ProcessContext> (context);
107 }
108
111 SampleType JUCE_VECTOR_CALLTYPE processSample (SampleType sample) noexcept
112 {
113 switch (parameters->type)
114 {
115 case Parameters<NumericType>::Type::lowPass: return processLoop<false, Parameters<NumericType>::Type::lowPass> (sample, *parameters); break;
116 case Parameters<NumericType>::Type::bandPass: return processLoop<false, Parameters<NumericType>::Type::bandPass> (sample, *parameters); break;
117 case Parameters<NumericType>::Type::highPass: return processLoop<false, Parameters<NumericType>::Type::highPass> (sample, *parameters); break;
118 default: jassertfalse;
119 }
120
121 return SampleType{0};
122 }
123
124 private:
125 //==============================================================================
126 template <bool isBypassed, typename Parameters<NumericType>::Type type>
127 SampleType JUCE_VECTOR_CALLTYPE processLoop (SampleType sample, Parameters<NumericType>& state) noexcept
128 {
129 y[2] = (sample - s1 * state.R2 - s1 * state.g - s2) * state.h;
130
131 y[1] = y[2] * state.g + s1;
132 s1 = y[2] * state.g + y[1];
133
134 y[0] = y[1] * state.g + s2;
135 s2 = y[1] * state.g + y[0];
136
137 return isBypassed ? sample : y[static_cast<size_t> (type)];
138 }
139
140 template <bool isBypassed, typename Parameters<NumericType>::Type type>
141 void processBlock (const SampleType* input, SampleType* output, size_t n) noexcept
142 {
143 auto state = *parameters;
144
145 for (size_t i = 0 ; i < n; ++i)
146 output[i] = processLoop<isBypassed, type> (input[i], state);
147
148 snapToZero();
149 *parameters = state;
150 }
151
152 template <bool isBypassed, typename ProcessContext>
153 void processInternal (const ProcessContext& context) noexcept
154 {
155 auto&& inputBlock = context.getInputBlock();
156 auto&& outputBlock = context.getOutputBlock();
157
158 // This class can only process mono signals. Use the ProcessorDuplicator class
159 // to apply this filter on a multi-channel audio stream.
160 jassert (inputBlock.getNumChannels() == 1);
161 jassert (outputBlock.getNumChannels() == 1);
162
163 auto n = inputBlock.getNumSamples();
164 auto* src = inputBlock .getChannelPointer (0);
165 auto* dst = outputBlock.getChannelPointer (0);
166
167 switch (parameters->type)
168 {
169 case Parameters<NumericType>::Type::lowPass: processBlock<isBypassed, Parameters<NumericType>::Type::lowPass> (src, dst, n); break;
170 case Parameters<NumericType>::Type::bandPass: processBlock<isBypassed, Parameters<NumericType>::Type::bandPass> (src, dst, n); break;
171 case Parameters<NumericType>::Type::highPass: processBlock<isBypassed, Parameters<NumericType>::Type::highPass> (src, dst, n); break;
172 default: jassertfalse;
173 }
174 }
175
176 //==============================================================================
177 std::array<SampleType, 3> y;
178 SampleType s1, s2;
179
180 //==============================================================================
181 JUCE_LEAK_DETECTOR (Filter)
182 };
183
184 //==============================================================================
190 template <typename NumericType>
191 struct Parameters : public ProcessorState
192 {
193 //==============================================================================
194 enum class Type
195 {
196 lowPass,
197 bandPass,
198 highPass
199 };
200
201 //==============================================================================
203 Type type = Type::lowPass;
204
211 void setCutOffFrequency (double sampleRate, NumericType frequency,
212 NumericType resonance = static_cast<NumericType> (1.0 / MathConstants<double>::sqrt2)) noexcept
213 {
214 jassert (sampleRate > 0);
215 jassert (resonance > NumericType (0));
216 jassert (frequency > NumericType (0) && frequency <= NumericType (sampleRate * 0.5));
217
218 g = static_cast<NumericType> (std::tan (MathConstants<double>::pi * frequency / sampleRate));
219 R2 = static_cast<NumericType> (1.0 / resonance);
220 h = static_cast<NumericType> (1.0 / (1.0 + R2 * g + g * g));
221 }
222
223 //==============================================================================
227 using Ptr = ReferenceCountedObjectPtr<Parameters>;
228
229 //==============================================================================
230 Parameters() = default;
231 Parameters (const Parameters& o) : g (o.g), R2 (o.R2), h (o.h) {}
232 Parameters& operator= (const Parameters& o) noexcept { g = o.g; R2 = o.R2; h = o.h; return *this; }
233
234 //==============================================================================
235 NumericType g = static_cast<NumericType> (std::tan (MathConstants<double>::pi * 200.0 / 44100.0));
236 NumericType R2 = static_cast<NumericType> (MathConstants<double>::sqrt2);
237 NumericType h = static_cast<NumericType> (1.0 / (1.0 + R2 * g + g * g));
238 };
239}
240
241} // namespace dsp
242} // namespace juce
juce::ReferenceCountedObjectPtr
Definition: juce_ReferenceCountedObject.h:247
juce::dsp::StateVariableFilter::Filter
Definition: juce_StateVariableFilter.h:55
juce::dsp::StateVariableFilter::Filter::Filter
Filter()
Definition: juce_StateVariableFilter.h:68
juce::dsp::StateVariableFilter::Filter::parameters
Parameters< NumericType >::Ptr parameters
Definition: juce_StateVariableFilter.h:94
juce::dsp::StateVariableFilter::Filter::ParametersPtr
typename Parameters< NumericType >::Ptr ParametersPtr
Definition: juce_StateVariableFilter.h:64
juce::dsp::StateVariableFilter::Filter::prepare
void prepare(const ProcessSpec &) noexcept
Definition: juce_StateVariableFilter.h:80
juce::dsp::StateVariableFilter::Filter::reset
void reset() noexcept
Definition: juce_StateVariableFilter.h:83
juce::dsp::StateVariableFilter::Filter::processSample
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Definition: juce_StateVariableFilter.h:111
juce::dsp::StateVariableFilter::Filter::Filter
Filter(const Filter &)=default
juce::dsp::StateVariableFilter::Filter::snapToZero
void snapToZero() noexcept
Definition: juce_StateVariableFilter.h:89
juce::dsp::StateVariableFilter::Filter::NumericType
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
Definition: juce_StateVariableFilter.h:61
juce::dsp::StateVariableFilter::Filter::Filter
Filter(Filter &&)=default
juce::MathConstants
Definition: juce_MathsFunctions.h:363
juce::dsp::ProcessSpec
Definition: juce_ProcessContext.h:39
juce::dsp::ProcessorState
Definition: juce_ProcessContext.h:59
juce::dsp::StateVariableFilter::Parameters
Definition: juce_StateVariableFilter.h:192
juce::dsp::StateVariableFilter::Parameters::setCutOffFrequency
void setCutOffFrequency(double sampleRate, NumericType frequency, NumericType resonance=static_cast< NumericType >(1.0/MathConstants< double >::sqrt2)) noexcept
Definition: juce_StateVariableFilter.h:211
juce::dsp::StateVariableFilter::Parameters::type
Type type
Definition: juce_StateVariableFilter.h:203