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 
27 namespace juce
28 {
29 namespace dsp
30 {
31 
32 /**
33     Classes for IIR filter processing.
34 */
35 namespace IIR
36 {
37     template <typename NumericType>
38     struct Coefficients;
39 
40     /**
41         A processing class that can perform IIR filtering on an audio signal, using
42         the Transposed Direct Form II digital structure.
43 
44         If you need a lowpass, bandpass or highpass filter with fast modulation of
45         its cutoff frequency, you might use the class StateVariableFilter instead,
46         which is designed to prevent artefacts at parameter changes, instead of the
47         class Filter.
48 
49         @see Filter::Coefficients, FilterAudioSource, StateVariableFilter
50 
51         @tags{DSP}
52     */
53     template <typename SampleType>
54     class Filter
55     {
56     public:
57         /** The NumericType is the underlying primitive type used by the SampleType (which
58             could be either a primitive or vector)
59         */
60         using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
61 
62         /** A typedef for a ref-counted pointer to the coefficients object */
63         using CoefficientsPtr = typename Coefficients<NumericType>::Ptr;
64 
65         //==============================================================================
66         /** Creates a filter.
67 
68             Initially the filter is inactive, so will have no effect on samples that
69             you process with it. You can modify the coefficients member to turn it into
70             the type of filter needed.
71         */
72         Filter();
73 
74         /** Creates a filter with a given set of coefficients. */
75         Filter (CoefficientsPtr coefficientsToUse);
76 
77         Filter (const Filter&) = default;
78         Filter (Filter&&) = default;
79         Filter& operator= (const Filter&) = default;
80         Filter& operator= (Filter&&) = default;
81 
82         //==============================================================================
83         /** The coefficients of the IIR filter. It's up to the caller to ensure that
84             these coefficients are modified in a thread-safe way.
85 
86             If you change the order of the coefficients then you must call reset after
87             modifying them.
88         */
89         CoefficientsPtr coefficients;
90 
91         //==============================================================================
92         /** Resets the filter's processing pipeline, ready to start a new stream of data.
93 
94             Note that this clears the processing state, but the type of filter and
95             its coefficients aren't changed.
96         */
reset()97         void reset()            { reset (SampleType {0}); }
98 
99         /** Resets the filter's processing pipeline to a specific value.
100             @see reset
101         */
102         void reset (SampleType resetToValue);
103 
104         //==============================================================================
105         /** Called before processing starts. */
106         void prepare (const ProcessSpec&) noexcept;
107 
108         /** Processes a block of samples */
109         template <typename ProcessContext>
process(const ProcessContext & context)110         void process (const ProcessContext& context) noexcept
111         {
112             if (context.isBypassed)
113                 processInternal<ProcessContext, true> (context);
114             else
115                 processInternal<ProcessContext, false> (context);
116         }
117 
118         /** Processes a single sample, without any locking.
119 
120             Use this if you need processing of a single value.
121 
122             Moreover, you might need the function snapToZero after a few calls to avoid
123             potential denormalisation issues.
124         */
125         SampleType JUCE_VECTOR_CALLTYPE processSample (SampleType sample) noexcept;
126 
127         /** Ensure that the state variables are rounded to zero if the state
128             variables are denormals. This is only needed if you are doing
129             sample by sample processing.
130         */
131         void snapToZero() noexcept;
132 
133     private:
134         //==============================================================================
135         void check();
136 
137         /** Processes a block of samples */
138         template <typename ProcessContext, bool isBypassed>
139         void processInternal (const ProcessContext& context) noexcept;
140 
141         //==============================================================================
142         HeapBlock<SampleType> memory;
143         SampleType* state = nullptr;
144         size_t order = 0;
145 
146         JUCE_LEAK_DETECTOR (Filter)
147     };
148 
149 
150     //==============================================================================
151     /** A set of coefficients for use in an Filter object.
152         @see IIR::Filter
153 
154         @tags{DSP}
155     */
156     template <typename NumericType>
157     struct Coefficients  : public ProcessorState
158     {
159         /** Creates a null set of coefficients (which will produce silence). */
160         Coefficients();
161 
162         /** Directly constructs an object from the raw coefficients.
163             Most people will want to use the static methods instead of this, but the
164             constructor is public to allow tinkerers to create their own custom filters!
165         */
166         Coefficients (NumericType b0, NumericType b1,
167                       NumericType a0, NumericType a1);
168 
169         Coefficients (NumericType b0, NumericType b1, NumericType b2,
170                       NumericType a0, NumericType a1, NumericType a2);
171 
172         Coefficients (NumericType b0, NumericType b1, NumericType b2, NumericType b3,
173                       NumericType a0, NumericType a1, NumericType a2, NumericType a3);
174 
175         Coefficients (const Coefficients&) = default;
176         Coefficients (Coefficients&&) = default;
177         Coefficients& operator= (const Coefficients&) = default;
178         Coefficients& operator= (Coefficients&&) = default;
179 
180         /** The Coefficients structure is ref-counted, so this is a handy type that can be used
181             as a pointer to one.
182         */
183         using Ptr = ReferenceCountedObjectPtr<Coefficients>;
184 
185         //==============================================================================
186         /** Returns the coefficients for a first order low-pass filter. */
187         static Ptr makeFirstOrderLowPass (double sampleRate, NumericType frequency);
188 
189         /** Returns the coefficients for a first order high-pass filter. */
190         static Ptr makeFirstOrderHighPass (double sampleRate, NumericType frequency);
191 
192         /** Returns the coefficients for a first order all-pass filter. */
193         static Ptr makeFirstOrderAllPass (double sampleRate, NumericType frequency);
194 
195         //==============================================================================
196         /** Returns the coefficients for a low-pass filter. */
197         static Ptr makeLowPass (double sampleRate, NumericType frequency);
198 
199         /** Returns the coefficients for a low-pass filter with variable Q. */
200         static Ptr makeLowPass (double sampleRate, NumericType frequency, NumericType Q);
201 
202         //==============================================================================
203         /** Returns the coefficients for a high-pass filter. */
204         static Ptr makeHighPass (double sampleRate, NumericType frequency);
205 
206         /** Returns the coefficients for a high-pass filter with variable Q. */
207         static Ptr makeHighPass (double sampleRate, NumericType frequency, NumericType Q);
208 
209         //==============================================================================
210         /** Returns the coefficients for a band-pass filter. */
211         static Ptr makeBandPass (double sampleRate, NumericType frequency);
212 
213         /** Returns the coefficients for a band-pass filter with variable Q. */
214         static Ptr makeBandPass (double sampleRate, NumericType frequency, NumericType Q);
215 
216         //==============================================================================
217         /** Returns the coefficients for a notch filter. */
218         static Ptr makeNotch (double sampleRate, NumericType frequency);
219 
220         /** Returns the coefficients for a notch filter with variable Q. */
221         static Ptr makeNotch (double sampleRate, NumericType frequency, NumericType Q);
222 
223         //==============================================================================
224         /** Returns the coefficients for an all-pass filter. */
225         static Ptr makeAllPass (double sampleRate, NumericType frequency);
226 
227         /** Returns the coefficients for an all-pass filter with variable Q. */
228         static Ptr makeAllPass (double sampleRate, NumericType frequency, NumericType Q);
229 
230         //==============================================================================
231         /** Returns the coefficients for a low-pass shelf filter with variable Q and gain.
232 
233             The gain is a scale factor that the low frequencies are multiplied by, so values
234             greater than 1.0 will boost the low frequencies, values less than 1.0 will
235             attenuate them.
236         */
237         static Ptr makeLowShelf (double sampleRate, NumericType cutOffFrequency,
238                                  NumericType Q, NumericType gainFactor);
239 
240         /** Returns the coefficients for a high-pass shelf filter with variable Q and gain.
241 
242             The gain is a scale factor that the high frequencies are multiplied by, so values
243             greater than 1.0 will boost the high frequencies, values less than 1.0 will
244             attenuate them.
245         */
246         static Ptr makeHighShelf (double sampleRate, NumericType cutOffFrequency,
247                                   NumericType Q, NumericType gainFactor);
248 
249         /** Returns the coefficients for a peak filter centred around a
250             given frequency, with a variable Q and gain.
251 
252             The gain is a scale factor that the centre frequencies are multiplied by, so
253             values greater than 1.0 will boost the centre frequencies, values less than
254             1.0 will attenuate them.
255         */
256         static Ptr makePeakFilter (double sampleRate, NumericType centreFrequency,
257                                    NumericType Q, NumericType gainFactor);
258 
259         //==============================================================================
260         /** Returns the filter order associated with the coefficients */
261         size_t getFilterOrder() const noexcept;
262 
263         /** Returns the magnitude frequency response of the filter for a given frequency
264             and sample rate
265         */
266         double getMagnitudeForFrequency (double frequency, double sampleRate) const noexcept;
267 
268         /** Returns the magnitude frequency response of the filter for a given frequency array
269             and sample rate.
270         */
271         void getMagnitudeForFrequencyArray (const double* frequencies, double* magnitudes,
272                                             size_t numSamples, double sampleRate) const noexcept;
273 
274         /** Returns the phase frequency response of the filter for a given frequency and
275             sample rate
276         */
277         double getPhaseForFrequency (double frequency, double sampleRate) const noexcept;
278 
279         /** Returns the phase frequency response of the filter for a given frequency array
280             and sample rate.
281         */
282         void getPhaseForFrequencyArray (double* frequencies, double* phases,
283                                         size_t numSamples, double sampleRate) const noexcept;
284 
285         /** Returns a raw data pointer to the coefficients. */
getRawCoefficientsCoefficients286         NumericType* getRawCoefficients() noexcept              { return coefficients.getRawDataPointer(); }
287 
288         /** Returns a raw data pointer to the coefficients. */
getRawCoefficientsCoefficients289         const NumericType* getRawCoefficients() const noexcept  { return coefficients.begin(); }
290 
291         //==============================================================================
292         /** The raw coefficients.
293             You should leave these numbers alone unless you really know what you're doing.
294         */
295         Array<NumericType> coefficients;
296 
297     private:
298         // Unfortunately, std::sqrt is not marked as constexpr just yet in all compilers
299         static constexpr NumericType inverseRootTwo = static_cast<NumericType> (0.70710678118654752440L);
300     };
301 
302 } // namespace IIR
303 } // namespace dsp
304 } // namespace juce
305 
306 #include "juce_IIRFilter_Impl.h"
307