OpenShot Library | OpenShotAudio  0.2.1
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 
31 namespace juce
32 {
33 namespace dsp
34 {
35 
36 /**
37  Classes for FIR filter processing.
38 */
39 namespace 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  //==============================================================================
179  HeapBlock<SampleType> memory;
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>
224  struct Coefficients : public ProcessorState
225  {
226  //==============================================================================
227  /** Creates a null set of coefficients (which will produce silence). */
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  */
287  };
288 }
289 
290 } // namespace dsp
291 } // namespace juce
292 
293 /** @}*/
Coefficients(const NumericType *samples, size_t numSamples)
Creates a set of coefficients from an array of samples.
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Processes a single sample, without any locking.
void prepare(const ProcessSpec &spec) noexcept
Prepare this filter for processing.
A set of coefficients for use in an FIRFilter object.
size_t getFilterOrder() const noexcept
Returns the filter order associated with the coefficients.
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.
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
The NumericType is the underlying primitive type used by the SampleType (which could be either a prim...
A processing class that can perform FIR filtering on an audio signal, in the time domain...
STL namespace.
Filter()
This will create a filter which will produce silence.
Coefficients< NumericType >::Ptr coefficients
The coefficients of the FIR filter.
Coefficients(size_t size)
Creates a null set of coefficients of a given size.
const NumericType * getRawCoefficients() const noexcept
Returns a raw data pointer to the coefficients.
NumericType * getRawCoefficients() noexcept
Returns a raw data pointer to the coefficients.
Coefficients()
Creates a null set of coefficients (which will produce silence).
void reset()
Resets the filter&#39;s processing pipeline, ready to start a new stream of data.
void process(const ProcessContext &context) noexcept
Processes a block of samples.
Array< NumericType > coefficients
The raw coefficients.
This is a handy base class for the state of a processor (such as parameter values) which is typically...
This structure is passed into a DSP algorithm&#39;s prepare() method, and contains information about vari...
A smart-pointer class which points to a reference-counted object.
Filter(CoefficientsPtr coefficientsToUse)
Creates a filter with a given set of coefficients.
typename Coefficients< NumericType >::Ptr CoefficientsPtr
A typedef for a ref-counted pointer to the coefficients object.