libsdr  0.1.0
A simple SDR library
firfilter.hh
1 #ifndef __SDR_FIRFILTER_HH__
2 #define __SDR_FIRFILTER_HH__
3 
4 #include "config.hh"
5 #include "node.hh"
6 #include "logger.hh"
7 
8 namespace sdr {
9 
13 {
14 public:
16  static inline void coeffs(std::vector<double> &alpha, double Fl, double Fu, double Fs)
17  {
18  size_t N = alpha.size();
19  double w = 2*M_PI*Fu/Fs;
20  double M = double(N)/2;
21  double norm = 0;
22  for (size_t i=0; i<N; i++) {
23  if (N == 2*i) { alpha[i] = 4*w/M_PI; }
24  else { alpha[i] = std::sin(w*(i-M))/(w*(i-M)); }
25  // apply window function
26  alpha[i] *= (0.42 - 0.5*cos((2*M_PI*i)/N) + 0.08*cos((4*M_PI*i)/N));
27  // Calc norm
28  norm += std::abs(alpha[i]);
29  }
30  // Normalize filter coeffs:
31  for (size_t i=0; i<N; i++) { alpha[i] /= norm; }
32  }
33 };
34 
35 
39 {
40 public:
42  static inline void coeffs(std::vector<double> &alpha, double Fl, double Fu, double Fs)
43  {
44  size_t N = alpha.size();
45  double w = 2*M_PI*Fl/Fs;
46  double M = double(N)/2;
47  double norm = 0;
48  for (size_t i=0; i<N; i++) {
49  if (N == 2*i) { alpha[i] = -std::sin(w*(i-M))/(w*(i-N)); }
50  else { alpha[i] = 1-4*w/M_PI; }
51  // apply window function
52  alpha[i] *= (0.42 - 0.5*cos((2*M_PI*i)/N) + 0.08*cos((4*M_PI*i)/N));
53  norm += std::abs(alpha[i]);
54  }
55  // Normalize filter coeffs:
56  for (size_t i=0; i<N; i++) { alpha[i] /= norm; }
57  }
58 };
59 
60 
64 {
65 public:
67  static inline void coeffs(std::vector<double> &alpha, double Fl, double Fu, double Fs)
68  {
69  size_t N = alpha.size();
70  double wl = 2*M_PI*Fl/Fs;
71  double wu = 2*M_PI*Fu/Fs;
72  double M = double(N)/2;
73  double norm = 0;
74  for (size_t i=0; i<N; i++) {
75  if (N == 2*i) { alpha[i] = 4*(wl-wu)/M_PI; }
76  else { alpha[i] = std::sin(wl*(i-M)/(wl*(i-M))) - std::sin(wu*(i-M)/(wu*(i-M))); }
77  // apply window function
78  alpha[i] *= (0.42 - 0.5*cos((2*M_PI*i)/N) + 0.08*cos((4*M_PI*i)/N));
79  norm += std::abs(alpha[i]);
80  }
81  // Normalize filter coeffs:
82  for (size_t i=0; i<N; i++) { alpha[i] /= norm; }
83  }
84 };
85 
86 
90 {
91 public:
93  static inline void coeffs(std::vector<double> &alpha, double Fl, double Fu, double Fs)
94  {
95  size_t N = alpha.size();
96  double wl = 2*M_PI*Fl/Fs;
97  double wu = 2*M_PI*Fl/Fs;
98  double M = double(N)/2;
99  double norm = 0;
100  for (size_t i=0; i<N; i++) {
101  if (N == 2*i) { alpha[i] = 1-4*(wl-wu)/M_PI; }
102  else { alpha[i] = std::sin(wu*(i-M)/(wu*(i-M))) - std::sin(wl*(i-M)/(wl*(i-M))); }
103  // apply window function
104  alpha[i] *= (0.42 - 0.5*cos((2*M_PI*i)/N) + 0.08*cos((4*M_PI*i)/N));
105  norm += std::abs(alpha[i]);
106  }
107  // Normalize filter coeffs:
108  for (size_t i=0; i<N; i++) { alpha[i] /= norm; }
109  }
110 };
111 
112 
116 template <class Scalar, class FilterCoeffs>
117 class FIRFilter: public Sink<Scalar>, public Source
118 {
119 public:
121  FIRFilter(size_t order, double Fl, double Fu)
122  : Sink<Scalar>(), Source(), _enabled(true), _order(std::max(size_t(1), order)), _Fl(Fl), _Fu(Fu),
123  _Fs(0), _alpha(_order, 0), _ring(_order), _ring_offset(0)
124  {
125  // pass...
126  }
127 
129  virtual ~FIRFilter() {
130  _ring.unref();
131  _buffer.unref();
132  }
133 
135  inline bool enabled() const { return _enabled; }
137  inline void enable(bool enable) { _enabled = enable; }
138 
140  inline size_t order() const { return _order; }
142  virtual void setOrder(size_t order) {
143  // Ensure order is larger 0:
144  order = std::max(size_t(1), order);
145  if (order == _order) { return; }
146  _order = order;
147  // Resize past and coeffs
148  _alpha.resize(_order);
150  _ring_offset = 0;
151  // Update coeffs:
152  FilterCoeffs::coeffs(_alpha, _Fl, _Fu, _Fs);
153  }
154 
156  inline double lowerFreq() const { return _Fl; }
158  inline void setLowerFreq(double Fl) {
159  _Fl = Fl;
160  FilterCoeffs::coeffs(_alpha, _Fl, _Fu, _Fs);
161  }
162 
164  inline double uppertFreq() const { return _Fl; }
166  inline void setUpperFreq(double Fu) {
167  _Fu = Fu;
168  FilterCoeffs::coeffs(_alpha, _Fl, _Fu, _Fs);
169  }
170 
172  virtual void config(const Config &src_cfg) {
173  // Requires type, sample-rate and buffer-size
174  if (!src_cfg.hasType() || !src_cfg.hasSampleRate() || !src_cfg.hasBufferSize()) { return; }
175  // check type
176  if (Config::typeId<Scalar>() != src_cfg.type()) {
177  ConfigError err;
178  err << "Can not configure FIRLowPass: Invalid type " << src_cfg.type()
179  << ", expected " << Config::typeId<Scalar>();
180  throw err;
181  }
182 
183  // Calc coeff
184  _Fs = src_cfg.sampleRate();
185  FilterCoeffs::coeffs(_alpha, _Fl, _Fu, _Fs);
186 
187  // unref buffer if non-empty
188  if (!_buffer.isEmpty()) { _buffer.unref(); }
189 
190  // allocate buffer
191  _buffer = Buffer<Scalar>(src_cfg.bufferSize());
192 
193  // Clear ring buffer
194  for (size_t i=0; i<_order; i++) { _ring[i] = 0; }
195  _ring_offset = 0;
196 
197  LogMessage msg(LOG_DEBUG);
198  msg << "Configured FIRFilter:" << std::endl
199  << " type " << src_cfg.type() << std::endl
200  << " sample rate " << _Fs << std::endl
201  << " buffer size " << src_cfg.bufferSize() << std::endl
202  << " order " << _order;
203  Logger::get().log(msg);
204 
205  // Propergate config
206  this->setConfig(Config(src_cfg.type(), src_cfg.sampleRate(), src_cfg.bufferSize(), 1));
207  }
208 
209 
211  virtual void process(const Buffer<Scalar> &buffer, bool allow_overwrite) {
212  // If emtpy
213  if (0 == buffer.size()) { /* drop buffer */ }
214  // If disabled -> pass
215  if (!_enabled) { this->send(buffer, allow_overwrite); return; }
216 
217  // Perform filtering in-place or out-of-place filtering
218  if (allow_overwrite) { _process(buffer, buffer); }
219  else if (_buffer.isUnused()) { _process(buffer, _buffer); }
220  else {
221 #ifdef SDR_DEBUG
222  LogMessage msg(LOG_WARNING);
223  msg << "FIR Filter: Drop buffer, output buffer still in use.";
224  Logger::get().log(msg);
225 #endif
226  }
227  }
228 
229 protected:
231  inline void _process(const Buffer<Scalar> &in, const Buffer<Scalar> &out)
232  {
233  for (size_t i=0; i<in.size(); i++) {
234  // Store input value into ring buffer
235  _ring[_ring_offset] = in[i]; _ring_offset++;
236  if (_ring_offset == _order) { _ring_offset=0; }
237  out[i] = 0;
238  // Apply filter on ring buffer
239  size_t idx = _ring_offset;
240  for (size_t j=0; j<_order; j++, idx++) {
241  if (idx == _order) { idx = 0; }
242  out[i] += _alpha[j]*_ring[idx];
243  }
244  }
245 
246  // Done.
247  this->send(out.head(in.size()), true);
248  }
249 
250 
251 protected:
253  bool _enabled;
255  size_t _order;
257  double _Fl;
259  double _Fu;
261  double _Fs;
263  std::vector<double> _alpha;
267  size_t _ring_offset;
270 };
271 
272 
275 template <class Scalar>
276 class FIRLowPass: public FIRFilter<Scalar, FIRLowPassCoeffs>
277 {
278 public:
280  FIRLowPass(size_t order, double Fc)
281  : FIRFilter<Scalar, FIRLowPassCoeffs>(order, 0, Fc) { }
283  virtual ~FIRLowPass() { }
285  inline double freq() const { return FIRFilter<Scalar, FIRLowPassCoeffs>::_Fu; }
288 };
289 
292 template <class Scalar>
293 class FIRHighPass: public FIRFilter<Scalar, FIRHighPassCoeffs>
294 {
295 public:
297  FIRHighPass(size_t order, double Fc)
298  : FIRFilter<Scalar, FIRHighPassCoeffs>(order, Fc, 0) { }
300  virtual ~FIRHighPass() { }
302  inline double freq() const { return FIRFilter<Scalar, FIRLowPassCoeffs>::_Fl; }
305 };
306 
307 
310 template <class Scalar>
311 class FIRBandPass: public FIRFilter<Scalar, FIRBandPassCoeffs>
312 {
313 public:
315  FIRBandPass(size_t order, double Fl, double Fu)
316  : FIRFilter<Scalar, FIRBandPassCoeffs>(order, Fl, Fu) { }
318  virtual ~FIRBandPass() { }
319 };
320 
323 template <class Scalar>
324 class FIRBandStop: public FIRFilter<Scalar, FIRBandStopCoeffs>
325 {
326 public:
328  FIRBandStop(size_t order, double Fl, double Fu)
329  : FIRFilter<Scalar, FIRBandStopCoeffs>(order, Fl, Fu) { }
331  virtual ~FIRBandStop() { }
332 };
333 
334 }
335 
336 #endif // FIRFILTER_HH
Band-stop FIR filter specialization.
Definition: firfilter.hh:324
virtual ~FIRBandStop()
Destructor.
Definition: firfilter.hh:331
A collection of configuration information that is send by a source to all connected sinks to properga...
Definition: node.hh:35
virtual ~FIRFilter()
Destructor.
Definition: firfilter.hh:129
Band-pass FIR filter specialization.
Definition: firfilter.hh:311
static void coeffs(std::vector< double > &alpha, double Fl, double Fu, double Fs)
Calculates the filter coefficients.
Definition: firfilter.hh:93
double _Fu
The upper edge frequency.
Definition: firfilter.hh:259
static void coeffs(std::vector< double > &alpha, double Fl, double Fu, double Fs)
Calculates the filter coefficients.
Definition: firfilter.hh:67
Implements the calculation of the filter coefficients for the use in the FIRFilter template class...
Definition: firfilter.hh:12
double _Fs
Current sample rate.
Definition: firfilter.hh:261
virtual void send(const RawBuffer &buffer, bool allow_overwrite=false)
Sends the given buffer to all connected sinks.
Definition: node.cc:67
void _process(const Buffer< Scalar > &in, const Buffer< Scalar > &out)
performs the actual computation
Definition: firfilter.hh:231
Typed sink.
Definition: node.hh:192
double freq() const
Returns the filter frequency.
Definition: firfilter.hh:302
Definition: autocast.hh:8
bool isEmpty() const
Returns true if the buffer is invalid/empty.
Definition: buffer.hh:77
Definition: operators.hh:9
FIRHighPass(size_t order, double Fc)
Constructor.
Definition: firfilter.hh:297
bool hasSampleRate() const
If true, the configuration has a sample rate.
Definition: node.hh:75
Generic source class.
Definition: node.hh:213
Implements the calculation of the filter coefficients for the use in the FIRFilter template class...
Definition: firfilter.hh:89
virtual ~FIRLowPass()
Destructor.
Definition: firfilter.hh:283
virtual ~FIRHighPass()
Destructor.
Definition: firfilter.hh:300
static void coeffs(std::vector< double > &alpha, double Fl, double Fu, double Fs)
Calculates the filter coefficients.
Definition: firfilter.hh:16
size_t size() const
Returns the number of elements of type T in this buffer.
Definition: buffer.hh:166
bool hasType() const
If true, the configuration has a type.
Definition: node.hh:69
double lowerFreq() const
Returns the lower edge frequency.
Definition: firfilter.hh:156
virtual void setConfig(const Config &config)
Stores the configuration and propergates it if the configuration has been changed.
Definition: node.cc:98
Buffer< Scalar > _ring
A "ring-buffer" used to perform the filtering.
Definition: firfilter.hh:265
Buffer< T > head(size_t n) const
Returns a new view on this buffer.
Definition: buffer.hh:237
FIRLowPass(size_t order, double Fc)
Constructor.
Definition: firfilter.hh:280
Implements the calculation of the filter coefficients for the use in the FIRFilter template class...
Definition: firfilter.hh:63
Implements the calculation of the filter coefficients for the use in the FIRFilter template class...
Definition: firfilter.hh:38
bool _enabled
If true, the filtering is enabled.
Definition: firfilter.hh:253
Generic FIR filter class.
Definition: firfilter.hh:117
void enable(bool enable)
Enable/Disable the filter.
Definition: firfilter.hh:137
FIRBandStop(size_t order, double Fl, double Fu)
Constructor.
Definition: firfilter.hh:328
virtual ~FIRBandPass()
Destructor.
Definition: firfilter.hh:318
void log(const LogMessage &message)
Logs a message.
Definition: logger.cc:100
Type type() const
Returns the type.
Definition: node.hh:71
double freq() const
Returns the filter frequency.
Definition: firfilter.hh:285
FIRBandPass(size_t order, double Fl, double Fu)
Constructor.
Definition: firfilter.hh:315
static void coeffs(std::vector< double > &alpha, double Fl, double Fu, double Fs)
Calculates the filter coefficients.
Definition: firfilter.hh:42
static Logger & get()
Returns the singleton instance of the logger.
Definition: logger.cc:89
The configuration error class.
Definition: exception.hh:24
A log message.
Definition: logger.hh:22
size_t bufferSize() const
Returns the max.
Definition: node.hh:83
size_t _ring_offset
Offset of the "ring-buffer".
Definition: firfilter.hh:267
virtual void setOrder(size_t order)
Sets the order of the filter and updates the filter coefficients.
Definition: firfilter.hh:142
size_t order() const
Returns the order of the filter.
Definition: firfilter.hh:140
double uppertFreq() const
Returns the upper edge frequency.
Definition: firfilter.hh:164
Buffer< Scalar > _buffer
The output buffer, unused if filtering is performed in-place.
Definition: firfilter.hh:269
size_t _order
The order of the filter.
Definition: firfilter.hh:255
virtual void config(const Config &src_cfg)
Configures the filter.
Definition: firfilter.hh:172
bool enabled() const
Returns true if the filter is enabled.
Definition: firfilter.hh:135
void setFreq(double freq)
Sets the filter frequency.
Definition: firfilter.hh:304
std::vector< double > _alpha
The current filter coefficients.
Definition: firfilter.hh:263
void unref()
Dereferences the buffer.
Definition: buffer.cc:63
High-pass FIR filter specialization.
Definition: firfilter.hh:293
bool isUnused() const
We assume here that buffers are owned by one object: A buffer is therefore "unused" if the owner hold...
Definition: buffer.hh:87
void setFreq(double freq)
Sets the filter frequency.
Definition: firfilter.hh:287
void setLowerFreq(double Fl)
Sets the lower edge frequency.
Definition: firfilter.hh:158
double _Fl
The lower edge frequency.
Definition: firfilter.hh:257
void setUpperFreq(double Fu)
Sets the upper edge frequency.
Definition: firfilter.hh:166
Low-pass FIR filter specialization.
Definition: firfilter.hh:276
bool hasBufferSize() const
If true, the configuration has a buffer size.
Definition: node.hh:81
double sampleRate() const
Returns the sample rate.
Definition: node.hh:77
virtual void process(const Buffer< Scalar > &buffer, bool allow_overwrite)
Performs the filtering.
Definition: firfilter.hh:211
FIRFilter(size_t order, double Fl, double Fu)
Constructor.
Definition: firfilter.hh:121