OpenShot Library | OpenShotAudio 0.2.2
juce_FIRFilter.h
1
2/** @weakgroup juce_dsp-processors
3 * @{
4 */
5/*
6 ==============================================================================
7
8 This file is part of the JUCE library.
9 Copyright (c) 2017 - ROLI Ltd.
10
11 JUCE is an open source library subject to commercial or open-source
12 licensing.
13
14 By using JUCE, you agree to the terms of both the JUCE 5 End-User License
15 Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
16 27th April 2017).
17
18 End User License Agreement: www.juce.com/juce-5-licence
19 Privacy Policy: www.juce.com/juce-5-privacy-policy
20
21 Or: You may also use this code under the terms of the GPL v3 (see
22 www.gnu.org/licenses).
23
24 JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
25 EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
26 DISCLAIMED.
27
28 ==============================================================================
29*/
30
31namespace juce
32{
33namespace dsp
34{
35
36/**
37 Classes for FIR filter processing.
38*/
39namespace FIR
40{
41 template <typename NumericType>
42 struct Coefficients;
43
44 //==============================================================================
45 /**
46 A processing class that can perform FIR filtering on an audio signal, in the
47 time domain.
48
49 Using FIRFilter is fast enough for FIRCoefficients with a size lower than 128
50 samples. For longer filters, it might be more efficient to use the class
51 Convolution instead, which does the same processing in the frequency domain
52 thanks to FFT.
53
54 @see FIRFilter::Coefficients, Convolution, FFT
55
56 @tags{DSP}
57 */
58 template <typename SampleType>
59 class Filter
60 {
61 public:
62 /** The NumericType is the underlying primitive type used by the SampleType (which
63 could be either a primitive or vector)
64 */
65 using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
66
67 /** A typedef for a ref-counted pointer to the coefficients object */
69
70 //==============================================================================
71 /** This will create a filter which will produce silence. */
73
74 /** Creates a filter with a given set of coefficients. */
75 Filter (CoefficientsPtr coefficientsToUse) : coefficients (std::move (coefficientsToUse)) { reset(); }
76
77 Filter (const Filter&) = default;
78 Filter (Filter&&) = default;
79 Filter& operator= (const Filter&) = default;
80 Filter& operator= (Filter&&) = default;
81
82 //==============================================================================
83 /** Prepare this filter for processing. */
84 inline void prepare (const ProcessSpec& spec) noexcept
85 {
86 // This class can only process mono signals. Use the ProcessorDuplicator class
87 // to apply this filter on a multi-channel audio stream.
88 jassert (spec.numChannels == 1);
89 ignoreUnused (spec);
90 reset();
91 }
92
93 /** Resets the filter's processing pipeline, ready to start a new stream of data.
94
95 Note that this clears the processing state, but the type of filter and
96 its coefficients aren't changed. To disable the filter, call setEnabled (false).
97 */
98 void reset()
99 {
100 if (coefficients != nullptr)
101 {
102 auto newSize = coefficients->getFilterOrder() + 1;
103
104 if (newSize != size)
105 {
106 memory.malloc (1 + jmax (newSize, size, static_cast<size_t> (128)));
107
108 fifo = snapPointerToAlignment (memory.getData(), sizeof (SampleType));
109 size = newSize;
110 }
111
112 for (size_t i = 0; i < size; ++i)
113 fifo[i] = SampleType {0};
114 }
115 }
116
117 //==============================================================================
118 /** The coefficients of the FIR filter. It's up to the caller to ensure that
119 these coefficients are modified in a thread-safe way.
120
121 If you change the order of the coefficients then you must call reset after
122 modifying them.
123 */
125
126 //==============================================================================
127 /** Processes a block of samples */
128 template <typename ProcessContext>
129 void process (const ProcessContext& context) noexcept
130 {
131 static_assert (std::is_same<typename ProcessContext::SampleType, SampleType>::value,
132 "The sample-type of the FIR filter must match the sample-type supplied to this process callback");
133 check();
134
135 auto&& inputBlock = context.getInputBlock();
136 auto&& outputBlock = context.getOutputBlock();
137
138 // This class can only process mono signals. Use the ProcessorDuplicator class
139 // to apply this filter on a multi-channel audio stream.
140 jassert (inputBlock.getNumChannels() == 1);
141 jassert (outputBlock.getNumChannels() == 1);
142
143 auto numSamples = inputBlock.getNumSamples();
144 auto* src = inputBlock .getChannelPointer (0);
145 auto* dst = outputBlock.getChannelPointer (0);
146
147 auto* fir = coefficients->getRawCoefficients();
148 size_t p = pos;
149
150 if (context.isBypassed)
151 {
152 for (size_t i = 0; i < numSamples; ++i)
153 {
154 fifo[p] = dst[i] = src[i];
155 p = (p == 0 ? size - 1 : p - 1);
156 }
157 }
158 else
159 {
160 for (size_t i = 0; i < numSamples; ++i)
161 dst[i] = processSingleSample (src[i], fifo, fir, size, p);
162 }
163
164 pos = p;
165 }
166
167
168 /** Processes a single sample, without any locking.
169 Use this if you need processing of a single value.
170 */
171 SampleType JUCE_VECTOR_CALLTYPE processSample (SampleType sample) noexcept
172 {
173 check();
174 return processSingleSample (sample, fifo, coefficients->getRawCoefficients(), size, pos);
175 }
176
177 private:
178 //==============================================================================
180 SampleType* fifo = nullptr;
181 size_t pos = 0, size = 0;
182
183 //==============================================================================
184 void check()
185 {
186 jassert (coefficients != nullptr);
187
188 if (size != (coefficients->getFilterOrder() + 1))
189 reset();
190 }
191
192 static SampleType JUCE_VECTOR_CALLTYPE processSingleSample (SampleType sample, SampleType* buf,
193 const NumericType* fir, size_t m, size_t& p) noexcept
194 {
195 SampleType out (0);
196
197 buf[p] = sample;
198
199 size_t k;
200 for (k = 0; k < m - p; ++k)
201 out += buf[(p + k)] * fir[k];
202
203 for (size_t j = 0; j < p; ++j)
204 out += buf[j] * fir[j + k];
205
206 p = (p == 0 ? m - 1 : p - 1);
207
208 return out;
209 }
210
211
212 JUCE_LEAK_DETECTOR (Filter)
213 };
214
215 //==============================================================================
216 /**
217 A set of coefficients for use in an FIRFilter object.
218
219 @see FIRFilter
220
221 @tags{DSP}
222 */
223 template <typename NumericType>
225 {
226 //==============================================================================
227 /** Creates a null set of coefficients (which will produce silence). */
228 Coefficients() : coefficients ({ NumericType() }) {}
229
230 /** Creates a null set of coefficients of a given size. */
231 Coefficients (size_t size) { coefficients.resize ((int) size); }
232
233 /** Creates a set of coefficients from an array of samples. */
234 Coefficients (const NumericType* samples, size_t numSamples) : coefficients (samples, (int) numSamples) {}
235
236 Coefficients (const Coefficients&) = default;
237 Coefficients (Coefficients&&) = default;
238 Coefficients& operator= (const Coefficients&) = default;
239 Coefficients& operator= (Coefficients&&) = default;
240
241 /** The Coefficients structure is ref-counted, so this is a handy type that can be used
242 as a pointer to one.
243 */
245
246 //==============================================================================
247 /** Returns the filter order associated with the coefficients. */
248 size_t getFilterOrder() const noexcept { return static_cast<size_t> (coefficients.size()) - 1; }
249
250 /** Returns the magnitude frequency response of the filter for a given frequency
251 and sample rate.
252 */
253 double getMagnitudeForFrequency (double frequency, double sampleRate) const noexcept;
254
255 /** Returns the magnitude frequency response of the filter for a given frequency array
256 and sample rate.
257 */
258 void getMagnitudeForFrequencyArray (double* frequencies, double* magnitudes,
259 size_t numSamples, double sampleRate) const noexcept;
260
261 /** Returns the phase frequency response of the filter for a given frequency and
262 sample rate.
263 */
264 double getPhaseForFrequency (double frequency, double sampleRate) const noexcept;
265
266 /** Returns the phase frequency response of the filter for a given frequency array
267 and sample rate.
268 */
269 void getPhaseForFrequencyArray (double* frequencies, double* phases,
270 size_t numSamples, double sampleRate) const noexcept;
271
272 /** Returns a raw data pointer to the coefficients. */
273 NumericType* getRawCoefficients() noexcept { return coefficients.getRawDataPointer(); }
274
275 /** Returns a raw data pointer to the coefficients. */
276 const NumericType* getRawCoefficients() const noexcept { return coefficients.begin(); }
277
278 //==============================================================================
279 /** Scales the values of the FIR filter with the sum of the squared coefficients. */
280 void normalise() noexcept;
281
282 //==============================================================================
283 /** The raw coefficients.
284 You should leave these numbers alone unless you really know what you're doing.
285 */
286 Array<NumericType> coefficients;
287 };
288}
289
290} // namespace dsp
291} // namespace juce
292
293/** @}*/
Holds a resizable array of primitive or copy-by-value objects.
Definition: juce_Array.h:60
int size() const noexcept
Returns the current number of elements in the array.
Definition: juce_Array.h:219
ElementType * begin() noexcept
Returns a pointer to the first element in the array.
Definition: juce_Array.h:332
ElementType * getRawDataPointer() noexcept
Returns a pointer to the actual array data.
Definition: juce_Array.h:314
void resize(int targetNumItems)
This will enlarge or shrink the array to the given number of elements, by adding or removing items fr...
Definition: juce_Array.h:674
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
Allocates a specified amount of memory.
ElementType * getData() const noexcept
Returns a raw pointer to the allocated data.
A smart-pointer class which points to a reference-counted object.
A processing class that can perform FIR filtering on an audio signal, in the time domain.
Coefficients< NumericType >::Ptr coefficients
The coefficients of the FIR filter.
typename Coefficients< NumericType >::Ptr CoefficientsPtr
A typedef for a ref-counted pointer to the coefficients object.
void process(const ProcessContext &context) noexcept
Processes a block of samples.
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
The NumericType is the underlying primitive type used by the SampleType (which could be either a prim...
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Processes a single sample, without any locking.
Filter(CoefficientsPtr coefficientsToUse)
Creates a filter with a given set of coefficients.
void prepare(const ProcessSpec &spec) noexcept
Prepare this filter for processing.
Filter()
This will create a filter which will produce silence.
void reset()
Resets the filter's processing pipeline, ready to start a new stream of data.
This structure is passed into a DSP algorithm's prepare() method, and contains information about vari...
A set of coefficients for use in an FIRFilter object.
void normalise() noexcept
Scales the values of the FIR filter with the sum of the squared coefficients.
void getMagnitudeForFrequencyArray(double *frequencies, double *magnitudes, size_t numSamples, double sampleRate) const noexcept
Returns the magnitude frequency response of the filter for a given frequency array and sample rate.
size_t getFilterOrder() const noexcept
Returns the filter order associated with the coefficients.
Coefficients()
Creates a null set of coefficients (which will produce silence).
Coefficients(const NumericType *samples, size_t numSamples)
Creates a set of coefficients from an array of samples.
Coefficients(size_t size)
Creates a null set of coefficients of a given size.
double getMagnitudeForFrequency(double frequency, double sampleRate) const noexcept
Returns the magnitude frequency response of the filter for a given frequency and sample rate.
Array< NumericType > coefficients
The raw coefficients.
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
Returns the phase frequency response of the filter for a given frequency and sample rate.
NumericType * getRawCoefficients() noexcept
Returns a raw data pointer to the coefficients.
const NumericType * getRawCoefficients() const noexcept
Returns a raw data pointer to the coefficients.
void getPhaseForFrequencyArray(double *frequencies, double *phases, size_t numSamples, double sampleRate) const noexcept
Returns the phase frequency response of the filter for a given frequency array and sample rate.
This is a handy base class for the state of a processor (such as parameter values) which is typically...