OpenShot Audio Library | OpenShotAudio 0.3.2
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
35namespace 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
65
66 //==============================================================================
69
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 //==============================================================================
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)
105 else
107 }
108
123
124 private:
125 //==============================================================================
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
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>
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 //==============================================================================
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
typename Parameters< NumericType >::Ptr ParametersPtr
void prepare(const ProcessSpec &) noexcept
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
void setCutOffFrequency(double sampleRate, NumericType frequency, NumericType resonance=static_cast< NumericType >(1.0/MathConstants< double >::sqrt2)) noexcept