OpenShot Audio Library | OpenShotAudio  0.3.3
juce_FIRFilter.h
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 
35 namespace FIR
36 {
37  template <typename NumericType>
38  struct Coefficients;
39 
40  //==============================================================================
54  template <typename SampleType>
55  class Filter
56  {
57  public:
61  using NumericType = typename SampleTypeHelpers::ElementType<SampleType>::Type;
62 
65 
66  //==============================================================================
69 
71  Filter (CoefficientsPtr coefficientsToUse) : coefficients (std::move (coefficientsToUse)) { reset(); }
72 
73  Filter (const Filter&) = default;
74  Filter (Filter&&) = default;
75  Filter& operator= (const Filter&) = default;
76  Filter& operator= (Filter&&) = default;
77 
78  //==============================================================================
80  inline void prepare (const ProcessSpec& spec) noexcept
81  {
82  // This class can only process mono signals. Use the ProcessorDuplicator class
83  // to apply this filter on a multi-channel audio stream.
84  jassert (spec.numChannels == 1);
85  ignoreUnused (spec);
86  reset();
87  }
88 
94  void reset()
95  {
96  if (coefficients != nullptr)
97  {
98  auto newSize = coefficients->getFilterOrder() + 1;
99 
100  if (newSize != size)
101  {
102  memory.malloc (1 + jmax (newSize, size, static_cast<size_t> (128)));
103 
104  fifo = snapPointerToAlignment (memory.getData(), sizeof (SampleType));
105  size = newSize;
106  }
107 
108  for (size_t i = 0; i < size; ++i)
109  fifo[i] = SampleType {0};
110  }
111  }
112 
113  //==============================================================================
121 
122  //==============================================================================
124  template <typename ProcessContext>
125  void process (const ProcessContext& context) noexcept
126  {
127  static_assert (std::is_same<typename ProcessContext::SampleType, SampleType>::value,
128  "The sample-type of the FIR filter must match the sample-type supplied to this process callback");
129  check();
130 
131  auto&& inputBlock = context.getInputBlock();
132  auto&& outputBlock = context.getOutputBlock();
133 
134  // This class can only process mono signals. Use the ProcessorDuplicator class
135  // to apply this filter on a multi-channel audio stream.
136  jassert (inputBlock.getNumChannels() == 1);
137  jassert (outputBlock.getNumChannels() == 1);
138 
139  auto numSamples = inputBlock.getNumSamples();
140  auto* src = inputBlock .getChannelPointer (0);
141  auto* dst = outputBlock.getChannelPointer (0);
142 
143  auto* fir = coefficients->getRawCoefficients();
144  size_t p = pos;
145 
146  if (context.isBypassed)
147  {
148  for (size_t i = 0; i < numSamples; ++i)
149  {
150  fifo[p] = dst[i] = src[i];
151  p = (p == 0 ? size - 1 : p - 1);
152  }
153  }
154  else
155  {
156  for (size_t i = 0; i < numSamples; ++i)
157  dst[i] = processSingleSample (src[i], fifo, fir, size, p);
158  }
159 
160  pos = p;
161  }
162 
163 
167  SampleType JUCE_VECTOR_CALLTYPE processSample (SampleType sample) noexcept
168  {
169  check();
170  return processSingleSample (sample, fifo, coefficients->getRawCoefficients(), size, pos);
171  }
172 
173  private:
174  //==============================================================================
175  HeapBlock<SampleType> memory;
176  SampleType* fifo = nullptr;
177  size_t pos = 0, size = 0;
178 
179  //==============================================================================
180  void check()
181  {
182  jassert (coefficients != nullptr);
183 
184  if (size != (coefficients->getFilterOrder() + 1))
185  reset();
186  }
187 
188  static SampleType JUCE_VECTOR_CALLTYPE processSingleSample (SampleType sample, SampleType* buf,
189  const NumericType* fir, size_t m, size_t& p) noexcept
190  {
191  SampleType out (0);
192 
193  buf[p] = sample;
194 
195  size_t k;
196  for (k = 0; k < m - p; ++k)
197  out += buf[(p + k)] * fir[k];
198 
199  for (size_t j = 0; j < p; ++j)
200  out += buf[j] * fir[j + k];
201 
202  p = (p == 0 ? m - 1 : p - 1);
203 
204  return out;
205  }
206 
207 
208  JUCE_LEAK_DETECTOR (Filter)
209  };
210 
211  //==============================================================================
219  template <typename NumericType>
220  struct Coefficients : public ProcessorState
221  {
222  //==============================================================================
224  Coefficients() : coefficients ({ NumericType() }) {}
225 
227  Coefficients (size_t size) { coefficients.resize ((int) size); }
228 
230  Coefficients (const NumericType* samples, size_t numSamples) : coefficients (samples, (int) numSamples) {}
231 
232  Coefficients (const Coefficients&) = default;
233  Coefficients (Coefficients&&) = default;
234  Coefficients& operator= (const Coefficients&) = default;
235  Coefficients& operator= (Coefficients&&) = default;
236 
241 
242  //==============================================================================
244  size_t getFilterOrder() const noexcept { return static_cast<size_t> (coefficients.size()) - 1; }
245 
249  double getMagnitudeForFrequency (double frequency, double sampleRate) const noexcept;
250 
254  void getMagnitudeForFrequencyArray (double* frequencies, double* magnitudes,
255  size_t numSamples, double sampleRate) const noexcept;
256 
260  double getPhaseForFrequency (double frequency, double sampleRate) const noexcept;
261 
265  void getPhaseForFrequencyArray (double* frequencies, double* phases,
266  size_t numSamples, double sampleRate) const noexcept;
267 
269  NumericType* getRawCoefficients() noexcept { return coefficients.getRawDataPointer(); }
270 
272  const NumericType* getRawCoefficients() const noexcept { return coefficients.begin(); }
273 
274  //==============================================================================
276  void normalise() noexcept;
277 
278  //==============================================================================
282  Array<NumericType> coefficients;
283  };
284 }
285 
286 } // namespace dsp
287 } // namespace juce
int size() const noexcept
Definition: juce_Array.h:215
ElementType * begin() noexcept
Definition: juce_Array.h:328
ElementType * getRawDataPointer() noexcept
Definition: juce_Array.h:310
void resize(int targetNumItems)
Definition: juce_Array.h:670
void malloc(SizeType newNumElements, size_t elementSize=sizeof(ElementType))
ElementType * getData() const noexcept
Coefficients< NumericType >::Ptr coefficients
typename Coefficients< NumericType >::Ptr CoefficientsPtr
void process(const ProcessContext &context) noexcept
typename SampleTypeHelpers::ElementType< SampleType >::Type NumericType
SampleType JUCE_VECTOR_CALLTYPE processSample(SampleType sample) noexcept
Filter(CoefficientsPtr coefficientsToUse)
void prepare(const ProcessSpec &spec) noexcept
void getMagnitudeForFrequencyArray(double *frequencies, double *magnitudes, size_t numSamples, double sampleRate) const noexcept
NumericType * getRawCoefficients() noexcept
size_t getFilterOrder() const noexcept
Coefficients(const NumericType *samples, size_t numSamples)
double getMagnitudeForFrequency(double frequency, double sampleRate) const noexcept
Array< NumericType > coefficients
double getPhaseForFrequency(double frequency, double sampleRate) const noexcept
const NumericType * getRawCoefficients() const noexcept
void getPhaseForFrequencyArray(double *frequencies, double *phases, size_t numSamples, double sampleRate) const noexcept