JUCE-7.0.12-0-g4f43011b96 JUCE-7.0.12-0-g4f43011b96
JUCE — C++ application framework with suport for VST, VST3, LV2 audio plug-ins

« « « Anklang Documentation
Loading...
Searching...
No Matches
juce_LinkwitzRileyFilter.cpp
Go to the documentation of this file.
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
26namespace juce::dsp
27{
28
29//==============================================================================
30template <typename SampleType>
35
36//==============================================================================
37template <typename SampleType>
39{
40 filterType = newType;
41}
42
43template <typename SampleType>
44void LinkwitzRileyFilter<SampleType>::setCutoffFrequency (SampleType newCutoffFrequencyHz)
45{
46 jassert (isPositiveAndBelow (newCutoffFrequencyHz, static_cast<SampleType> (sampleRate * 0.5)));
47
48 cutoffFrequency = newCutoffFrequencyHz;
49 update();
50}
51
52//==============================================================================
53template <typename SampleType>
55{
56 jassert (spec.sampleRate > 0);
57 jassert (spec.numChannels > 0);
58
59 sampleRate = spec.sampleRate;
60 update();
61
62 s1.resize (spec.numChannels);
63 s2.resize (spec.numChannels);
64 s3.resize (spec.numChannels);
65 s4.resize (spec.numChannels);
66
67 reset();
68}
69
70template <typename SampleType>
72{
73 for (auto s : { &s1, &s2, &s3, &s4 })
74 std::fill (s->begin(), s->end(), static_cast<SampleType> (0));
75}
76
77template <typename SampleType>
79{
80 for (auto s : { &s1, &s2, &s3, &s4 })
81 for (auto& element : *s)
82 util::snapToZero (element);
83}
84
85//==============================================================================
86template <typename SampleType>
87SampleType LinkwitzRileyFilter<SampleType>::processSample (int channel, SampleType inputValue)
88{
89 auto yH = (inputValue - (R2 + g) * s1[(size_t) channel] - s2[(size_t) channel]) * h;
90
91 auto yB = g * yH + s1[(size_t) channel];
92 s1[(size_t) channel] = g * yH + yB;
93
94 auto yL = g * yB + s2[(size_t) channel];
95 s2[(size_t) channel] = g * yB + yL;
96
97 if (filterType == Type::allpass)
98 return yL - R2 * yB + yH;
99
100 auto yH2 = ((filterType == Type::lowpass ? yL : yH) - (R2 + g) * s3[(size_t) channel] - s4[(size_t) channel]) * h;
101
102 auto yB2 = g * yH2 + s3[(size_t) channel];
103 s3[(size_t) channel] = g * yH2 + yB2;
104
105 auto yL2 = g * yB2 + s4[(size_t) channel];
106 s4[(size_t) channel] = g * yB2 + yL2;
107
108 return filterType == Type::lowpass ? yL2 : yH2;
109}
110
111template <typename SampleType>
112void LinkwitzRileyFilter<SampleType>::processSample (int channel, SampleType inputValue, SampleType &outputLow, SampleType &outputHigh)
113{
114 auto yH = (inputValue - (R2 + g) * s1[(size_t) channel] - s2[(size_t) channel]) * h;
115
116 auto yB = g * yH + s1[(size_t) channel];
117 s1[(size_t) channel] = g * yH + yB;
118
119 auto yL = g * yB + s2[(size_t) channel];
120 s2[(size_t) channel] = g * yB + yL;
121
122 auto yH2 = (yL - (R2 + g) * s3[(size_t) channel] - s4[(size_t) channel]) * h;
123
124 auto yB2 = g * yH2 + s3[(size_t) channel];
125 s3[(size_t) channel] = g * yH2 + yB2;
126
127 auto yL2 = g * yB2 + s4[(size_t) channel];
128 s4[(size_t) channel] = g * yB2 + yL2;
129
130 outputLow = yL2;
131 outputHigh = yL - R2 * yB + yH - yL2;
132}
133
134template <typename SampleType>
136{
137 g = (SampleType) std::tan (MathConstants<double>::pi * cutoffFrequency / sampleRate);
138 R2 = (SampleType) std::sqrt (2.0);
139 h = (SampleType) (1.0 / (1.0 + R2 * g + g * g));
140}
141
142//==============================================================================
143template class LinkwitzRileyFilter<float>;
144template class LinkwitzRileyFilter<double>;
145
146} // namespace juce::dsp
A filter class designed to perform multi-band separation using the TPT (Topology-Preserving Transform...
void prepare(const ProcessSpec &spec)
Initialises the filter.
void setType(Type newType)
Sets the filter type.
void reset()
Resets the internal state variables of the filter.
SampleType processSample(int channel, SampleType inputValue)
Performs the filter operation on a single sample at a time.
void setCutoffFrequency(SampleType newCutoffFrequencyHz)
Sets the cutoff frequency of the filter in Hz.
void snapToZero() noexcept
Ensure that the state variables are rounded to zero if the state variables are denormals.
T fill(T... args)
#define jassert(expression)
Platform-independent assertion macro.
bool isPositiveAndBelow(Type1 valueToTest, Type2 upperLimit) noexcept
Returns true if a value is at least zero, and also below a specified upper limit.
T sqrt(T... args)
Commonly used mathematical constants.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...
uint32 numChannels
The number of channels that the process() method will be expected to handle.
double sampleRate
The sample rate that will be used for the data that is sent to the processor.
typedef size_t
T tan(T... args)