35namespace StateVariableFilter
37 template <
typename NumericType>
53 template <
typename SampleType>
61 using NumericType =
typename SampleTypeHelpers::ElementType<SampleType>::Type;
83 void reset() noexcept { s1 = s2 = SampleType {0}; }
89 void snapToZero() noexcept { util::snapToZero (s1); util::snapToZero (s2); }
97 template <
typename ProcessContext>
98 void process (
const ProcessContext& context)
noexcept
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");
103 if (context.isBypassed)
104 processInternal<true, ProcessContext> (context);
106 processInternal<false, ProcessContext> (context);
118 default: jassertfalse;
121 return SampleType{0};
126 template <bool isBypassed, typename Parameters<NumericType>::Type type>
129 y[2] = (sample - s1 * state.R2 - s1 * state.g - s2) * state.h;
131 y[1] = y[2] * state.g + s1;
132 s1 = y[2] * state.g + y[1];
134 y[0] = y[1] * state.g + s2;
135 s2 = y[1] * state.g + y[0];
137 return isBypassed ? sample : y[
static_cast<size_t> (type)];
140 template <bool isBypassed, typename Parameters<NumericType>::Type type>
141 void processBlock (
const SampleType* input, SampleType* output,
size_t n)
noexcept
145 for (
size_t i = 0 ; i < n; ++i)
146 output[i] = processLoop<isBypassed, type> (input[i], state);
152 template <
bool isBypassed,
typename ProcessContext>
153 void processInternal (
const ProcessContext& context)
noexcept
155 auto&& inputBlock = context.getInputBlock();
156 auto&& outputBlock = context.getOutputBlock();
160 jassert (inputBlock.getNumChannels() == 1);
161 jassert (outputBlock.getNumChannels() == 1);
163 auto n = inputBlock.getNumSamples();
164 auto* src = inputBlock .getChannelPointer (0);
165 auto* dst = outputBlock.getChannelPointer (0);
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;
177 std::array<SampleType, 3> y;
181 JUCE_LEAK_DETECTOR (
Filter)
190 template <
typename NumericType>
214 jassert (sampleRate > 0);
215 jassert (resonance > NumericType (0));
216 jassert (frequency > NumericType (0) && frequency <= NumericType (sampleRate * 0.5));
219 R2 =
static_cast<NumericType
> (1.0 / resonance);
220 h =
static_cast<NumericType
> (1.0 / (1.0 + R2 * g + g * g));
232 Parameters& operator= (
const Parameters& o)
noexcept { g = o.g; R2 = o.R2; h = o.h;
return *
this; }
237 NumericType h =
static_cast<NumericType
> (1.0 / (1.0 + R2 * g + g * g));
Parameters< NumericType >::Ptr parameters
typename Parameters< NumericType >::Ptr ParametersPtr
void prepare(const ProcessSpec &) noexcept
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Filter(const Filter &)=default
void snapToZero() noexcept
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
Filter(Filter &&)=default
void setCutOffFrequency(double sampleRate, NumericType frequency, NumericType resonance=static_cast< NumericType >(1.0/MathConstants< double >::sqrt2)) noexcept