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