Falcon
Loading...
Searching...
No Matches
filter.hpp
1// ---------------------------------------------------------------------
2// This file is part of falcon-core.
3//
4// Copyright (C) 2015, 2016, 2017 Neuro-Electronics Research Flanders
5//
6// Falcon-server is free software: you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation, either version 3 of the License, or
9// (at your option) any later version.
10//
11// Falcon-server is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16// You should have received a copy of the GNU General Public License
17// along with falcon-core. If not, see <http://www.gnu.org/licenses/>.
18// ---------------------------------------------------------------------
19
20#pragma once
21
22#include <yaml-cpp/yaml.h>
23
24#include <algorithm>
25#include <array>
26#include <cassert>
27#include <cctype>
28#include <cstring>
29#include <exception>
30#include <fstream>
31#include <map>
32#include <regex>
33#include <string>
34#include <vector>
35
36#include "gram_savitzky_golay.hpp"
37
38namespace dsp {
39namespace filter {
40
41class IFilter {
42 public:
43 IFilter(std::string description) : description_(description) {}
44
45 virtual ~IFilter();
46
47 std::string description() const;
48
49 virtual IFilter* clone() = 0;
50 virtual unsigned int order() const = 0;
51
52 unsigned int nchannels() const;
53 bool realized() const;
54 void realize(unsigned int nchannels, double init = 0.0);
55 void unrealize();
56
57 // single channel, single sample
58 virtual double process_channel(double, unsigned int channel) = 0;
59
60 // all channels, single sample
61 virtual void process_sample(std::vector<double>&, std::vector<double>&) = 0;
62 virtual void process_sample(std::vector<double>::iterator, std::vector<double>::iterator) = 0;
63 virtual void process_sample(double*, double*) = 0;
64
65 // single channel, multiple samples
66 virtual void process_channel(std::vector<double>&, std::vector<double>&,
67 unsigned int channel = 0) = 0;
68 virtual void process_channel(uint64_t nsamples, std::vector<double>::iterator,
69 std::vector<double>::iterator, unsigned int channel = 0) = 0;
70 virtual void process_channel(uint64_t nsamples, double*, double*, unsigned int channel) = 0;
71
72 // all channels, multiple samples
73 virtual void process_by_channel(std::vector<std::vector<double>>&,
74 std::vector<std::vector<double>>&) = 0; // samples<channels>
75 virtual void process_by_sample(std::vector<std::vector<double>>&,
76 std::vector<std::vector<double>>&) = 0; // channels<samples>
77 virtual void process_by_channel(uint64_t nsamples, double**,
78 double**) = 0; // samples<channels>
79 virtual void process_by_sample(uint64_t nsamples, double**,
80 double**) = 0; // channels<samples>
81 virtual void process_by_channel(uint64_t nsamples, std::vector<double>&,
82 std::vector<double>&) = 0; // samples<channels>
83 virtual void process_by_sample(uint64_t nsamples, std::vector<double>&,
84 std::vector<double>&) = 0; // channels<samples>
85
86 protected:
87 virtual bool realize_filter(unsigned int nchannels, double init) = 0;
88 virtual void unrealize_filter() {};
89
90 protected:
91 std::string description_;
92 bool realized_ = false;
93 unsigned int nchannels_ = 0;
94};
95
96class FirFilter : public IFilter {
97 public:
98 FirFilter(const std::vector<double>& coefficients, std::string description = "");
99 virtual IFilter* clone();
100
101 static FirFilter* FromStream(std::istream& stream, std::string description,
102 bool binary = false);
103
104 unsigned int order() const final;
105
106 std::size_t group_delay() const;
107
108 // single channel, single sample
109 double process_channel(double input, unsigned int channel = 0) final;
110
111 // all channels, single sample
112 void process_sample(std::vector<double>& input, std::vector<double>& output) final;
113 void process_sample(std::vector<double>::iterator input,
114 std::vector<double>::iterator output) final;
115 void process_sample(double* input, double* output) final;
116
117 // single channel, multiple samples
118 void process_channel(std::vector<double>& input, std::vector<double>& output,
119 unsigned int channel = 0) final;
120 void process_channel(uint64_t nsamples, std::vector<double>::iterator input,
121 std::vector<double>::iterator output, unsigned int channel = 0);
122 void process_channel(uint64_t nsamples, double* input, double* output,
123 unsigned int channel = 0);
124
125 // all channels, multiple samples
126 void process_by_channel(std::vector<std::vector<double>>& input,
127 std::vector<std::vector<double>>& output) final;
128 void process_by_sample(std::vector<std::vector<double>>& input,
129 std::vector<std::vector<double>>& output) final;
130 void process_by_channel(uint64_t nsamples, double** input, double** output) final;
131 void process_by_sample(uint64_t nsamples, double** input, double** output) final;
132
133 virtual void process_by_channel(uint64_t nsamples, std::vector<double>& input,
134 std::vector<double>& output);
135 virtual void process_by_sample(uint64_t nsamples, std::vector<double>& input,
136 std::vector<double>& output);
137
138 protected:
139 bool realize_filter(unsigned int nchannels, double init = 0.0) final;
140 void unrealize_filter() final;
141
142 protected:
143 std::vector<double> coefficients_;
144 double* pcoefficients_;
145 unsigned int ntaps_;
146
147 std::vector<std::vector<double>> registers_;
148 std::vector<double*> pregisters_;
149
150 double* preg_;
151};
152
153class SlopeFilter : public FirFilter {
154 public:
155 SlopeFilter(uint32_t window_size, uint32_t order, uint32_t derivative_order,
156 std::string description = "")
157 : FirFilter(gram_sg::compute_weights(window_size, window_size, order, derivative_order),
158 description),
159 window_size_(window_size),
160 order_(order),
161 derivative_order_(derivative_order) {};
162
163 static SlopeFilter* FromStream(std::istream& stream, std::string description, bool binary);
164
165 virtual IFilter* clone() { return new SlopeFilter(window_size_, order_, derivative_order_); };
166
167 protected:
168 size_t window_size_;
169 uint32_t order_;
170 uint32_t derivative_order_;
171
172 public:
173 static constexpr uint16_t DEFAULT_WINDOW_SIZE = 4;
174 static constexpr uint8_t DEFAULT_ORDER = 1;
175 static constexpr uint8_t DEFAULT_DERIVATIVE_ORDER = 1;
176};
177
178class BiquadFilter : public IFilter {
179 public:
180 BiquadFilter(double gain, std::vector<std::array<double, 6>>& coefficients,
181 std::string description = "");
182 virtual IFilter* clone();
183
184 static BiquadFilter* FromStream(std::istream& stream, std::string description, bool binary);
185
186 unsigned int order() const final;
187
188 // single channel, single sample
189 double process_channel(double x, unsigned int c = 0) final;
190
191 // all channels, single sample
192 void process_sample(std::vector<double>& input, std::vector<double>& output) final {};
193 void process_sample(std::vector<double>::iterator input,
194 std::vector<double>::iterator output) final;
195 void process_sample(double* input, double* output) final;
196
197 // single channel, multiple samples
198 void process_channel(std::vector<double>& input, std::vector<double>& output,
199 unsigned int channel = 0) final;
200 void process_channel(uint64_t nsamples, std::vector<double>::iterator input,
201 std::vector<double>::iterator output, unsigned int channel = 0) final;
202 void process_channel(uint64_t nsamples, double* input, double* output,
203 unsigned int channel = 0) final;
204
205 // all channels, multiple samples
206 void process_by_channel(std::vector<std::vector<double>>& input,
207 std::vector<std::vector<double>>& output) final;
208 void process_by_sample(std::vector<std::vector<double>>& input,
209 std::vector<std::vector<double>>& output) final;
210 void process_by_channel(uint64_t nsamples, double** input, double** output) final;
211 void process_by_sample(uint64_t nsamples, double** input, double** output) final;
212
213 virtual void process_by_channel(uint64_t nsamples, std::vector<double>& input,
214 std::vector<double>& output);
215 virtual void process_by_sample(uint64_t nsamples, std::vector<double>& input,
216 std::vector<double>& output);
217
218 protected:
219 bool realize_filter(unsigned int nchannels, double init = 0.0) final;
220 void unrealize_filter() final;
221
222 protected:
223 double gain_;
224 std::vector<std::array<double, 6>> coefficients_;
225
226 unsigned int nstages_;
227
228 std::vector<std::vector<std::array<double, 2>>> registers_;
229};
230
231std::map<std::string, std::string> parse_file_header(std::istream& stream);
232IFilter* construct_from_file(std::string file);
233
234IFilter* construct_from_yaml(const YAML::Node& node);
235
236} // namespace filter
237} // namespace dsp
Definition filter.hpp:41