MCL
A C++ library mirroring some of the most common Matlab functions.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
firfilter.h
Go to the documentation of this file.
1 /*
2  MCL
3  Copyright (c) 2012-18, Enzo De Sena
4  All rights reserved.
5 
6  Authors: Enzo De Sena, enzodesena@gmail.com
7  */
8 
9 #ifndef MCL_FIRFILTER_H
10 #define MCL_FIRFILTER_H
11 
12 #include <vector>
13 
14 #include "mcltypes.h"
15 #include "digitalfilter.h"
16 #include "vectorop.h"
17 
18 namespace mcl {
20 class FirFilter : public DigitalFilter {
21 public:
23  FirFilter() noexcept;
24 
26  FirFilter(const std::vector<Real> B) noexcept;
27 
35  virtual Real Filter(const Real input_sample) noexcept;
36 
37  virtual void Filter(const Real* __restrict input_data, const Int num_samples,
38  Real* __restrict output_data) noexcept;
39 
41 
53  void SetImpulseResponse(const std::vector<Real>& impulse_response,
54  const Int update_length = 0) noexcept;
55 
57  void Reset() noexcept;
58 
60  std::vector<Real> impulse_response() noexcept;
61 
63  static FirFilter GainFilter(const Real gain) noexcept;
64 
66  static bool Test();
67 
68  static void SpeedTests();
69 
70  virtual ~FirFilter() {}
71 
72 private:
73 #ifdef MCL_APPLE_ACCELERATE
74  Real FilterAppleDsp(Real input_sample) noexcept;
75  void FilterAppleDsp(const Real* __restrict input_data, const Int num_samples,
76  Real* __restrict output_data) noexcept;
77 #endif
78 
79  template<class T>
80  void GetExtendedInput(const Real* __restrict input_data, const Int num_samples,
81  T* __restrict extended_input_data) {
82 
83  // Stage 1
84  for (Int i=0; i<counter_; ++i) {
85  extended_input_data[i] = delay_line_[counter_-i-1];
86  }
87 
88  // Stage 2
89  // Starting from counter_ in padded_data
90  // Ending in counter_+(length_-counter_-1)
91  for (Int i=counter_; i<(length_-1); ++i) {
92  extended_input_data[i] = delay_line_[length_-1-(i-counter_)];
93  }
94 
95  // Stage 3
96  // Append input signal
97  for (Int i=(length_-1); i<(length_-1+num_samples); ++i) {
98  extended_input_data[i] = input_data[i-(length_-1)];
99  }
100  }
101 
102  Real FilterStraight(Real input_sample) noexcept;
103 
104  std::vector<Real> FilterSequential(const std::vector<Real>& input) noexcept;
105 
110  void UpdateCoefficients() noexcept;
111 
112  std::vector<Real> impulse_response_;
113  std::vector<Real> impulse_response_old_;
114  Int update_index_;
115  Int update_length_;
116 
117  bool updating_;
118 
119  /* This is the current vector of coefficients. When the filter is updating
120  this will in general be different from impulse_response_. */
121  std::vector<Real> coefficients_;
122  std::vector<Real> delay_line_;
123  Int counter_;
124  Int length_;
125 };
126 
127 
128 class GainFilter : public DigitalFilter {
129 public:
130  GainFilter(const Real gain) : gain_(gain) {}
131 
132  virtual Real Filter(const Real input) noexcept {
133  return input*gain_;
134  }
135 
136  virtual void Filter(const Real* input_data, const Int num_samples,
137  Real* output_data) noexcept {
138  Multiply(input_data, num_samples, gain_, output_data);
139  }
140 
141  virtual void Reset() {}
142 private:
143  Real gain_;
144 };
145 
147 public:
149 
150  virtual Real Filter(const Real input) noexcept {
151  return input;
152  }
153 
154  virtual void Filter(const Real* input_data, const Int num_samples,
155  Real* output_data) noexcept {
156  for (Int i=0; i<num_samples; ++i) {
157  output_data[i] = input_data[i];
158  }
159  }
160 
161  virtual void Reset() {}
162 };
163 
164 } // namespace mcl
165 
166 
167 #endif