Open Ephys GUI
 All Classes Functions Variables
Filter.h
1 /*******************************************************************************
2 
3 "A Collection of Useful C++ Classes for Digital Signal Processing"
4  By Vincent Falco
5 
6 Official project location:
7 http://code.google.com/p/dspfilterscpp/
8 
9 See Documentation.cpp for contact information, notes, and bibliography.
10 
11 --------------------------------------------------------------------------------
12 
13 License: MIT License (http://www.opensource.org/licenses/mit-license.php)
14 Copyright (c) 2009 by Vincent Falco
15 
16 Permission is hereby granted, free of charge, to any person obtaining a copy
17 of this software and associated documentation files (the "Software"), to deal
18 in the Software without restriction, including without limitation the rights
19 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
20 copies of the Software, and to permit persons to whom the Software is
21 furnished to do so, subject to the following conditions:
22 
23 The above copyright notice and this permission notice shall be included in
24 all copies or substantial portions of the Software.
25 
26 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
29 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
30 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
31 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
32 THE SOFTWARE.
33 
34 *******************************************************************************/
35 
36 #ifndef DSPFILTERS_FILTER_H
37 #define DSPFILTERS_FILTER_H
38 
39 #include "Common.h"
40 #include "MathSupplement.h"
41 #include "Params.h"
42 #include "State.h"
43 #include "Types.h"
44 
45 namespace Dsp {
46 
47 /*
48  * Filter
49  *
50  * Full abstraction of a digital IIR filter.
51  * Supports run-time introspection and modulation of filter
52  * parameters.
53  *
54  */
55 class Filter
56 {
57 public:
58  virtual ~Filter();
59 
60  virtual Kind getKind () const = 0;
61 
62  virtual const std::string getName () const = 0;
63 
64  virtual int getNumParams () const = 0;
65 
66  virtual ParamInfo getParamInfo (int index) const = 0;
67 
68  Params getDefaultParams() const;
69 
70  const Params& getParams() const
71  {
72  return m_params;
73  }
74 
75  double getParam (int paramIndex) const
76  {
77  assert (paramIndex >= 0 && paramIndex <= getNumParams());
78  return m_params[paramIndex];
79  }
80 
81  void setParam (int paramIndex, double nativeValue)
82  {
83  assert (paramIndex >= 0 && paramIndex <= getNumParams());
84  m_params[paramIndex] = nativeValue;
85  doSetParams (m_params);
86  }
87 
88  int findParamId (int paramId);
89 
90  void setParamById (int paramId, double nativeValue);
91 
92  void setParams (const Params& parameters)
93  {
94  m_params = parameters;
95  doSetParams (parameters);
96  }
97 
98  // This makes a best-effort to pick up the values
99  // of matching parameters from another set. It uses
100  // the ParamID information to make the match.
101  void copyParamsFrom (Dsp::Filter const* other);
102 
103  virtual std::vector<PoleZeroPair> getPoleZeros() const = 0;
104 
105  virtual complex_t response (double normalizedFrequency) const = 0;
106 
107  virtual int getNumChannels() = 0;
108  virtual void reset () = 0;
109  virtual void process (int numSamples, float* const* arrayOfChannels) = 0;
110  virtual void process (int numSamples, double* const* arrayOfChannels) = 0;
111 
112 protected:
113  virtual void doSetParams (const Params& parameters) = 0;
114 
115 private:
116  Params m_params;
117 };
118 
119 //------------------------------------------------------------------------------
120 
121 /*
122  * FilterDesign
123  *
124  * This container holds a filter Design (Gui-friendly layer) and
125  * optionally combines it with the necessary state information to
126  * process channel data.
127  *
128  */
129 
130 // Factored to reduce template instantiations
131 template <class DesignClass>
132 class FilterDesignBase : public Filter
133 {
134 public:
135  Kind getKind () const
136  {
137  return m_design.getKind ();
138  }
139 
140  const std::string getName () const
141  {
142  return m_design.getName ();
143  }
144 
145  int getNumParams () const
146  {
147  return DesignClass::NumParams;
148  }
149 
150  Params getDefaultParams() const
151  {
152  return m_design.getDefaultParams();
153  }
154 
155  ParamInfo getParamInfo (int index) const
156  {
157  switch (index)
158  {
159  case 0: return m_design.getParamInfo_0 ();
160  case 1: return m_design.getParamInfo_1 ();
161  case 2: return m_design.getParamInfo_2 ();
162  case 3: return m_design.getParamInfo_3 ();
163  case 4: return m_design.getParamInfo_4 ();
164  case 5: return m_design.getParamInfo_5 ();
165  case 6: return m_design.getParamInfo_6 ();
166  case 7: return m_design.getParamInfo_7 ();
167  };
168 
169  return ParamInfo();
170  }
171 
172  std::vector<PoleZeroPair> getPoleZeros() const
173  {
174  return m_design.getPoleZeros();
175  }
176 
177  complex_t response (double normalizedFrequency) const
178  {
179  return m_design.response (normalizedFrequency);
180  }
181 
182 protected:
183  void doSetParams (const Params& parameters)
184  {
185  m_design.setParams (parameters);
186  }
187 
188 protected:
189  DesignClass m_design;
190 };
191 
192 
193 
194 template <class DesignClass,
195  int Channels = 0,
196  class StateType = DirectFormII>
197 class FilterDesign : public FilterDesignBase <DesignClass>
198 {
199 public:
200  FilterDesign ()
201  {
202  }
203 
204  int getNumChannels()
205  {
206  return Channels;
207  }
208 
209  void reset ()
210  {
211  m_state.reset();
212  }
213 
214  void process (int numSamples, float* const* arrayOfChannels)
215  {
216  m_state.process (numSamples, arrayOfChannels,
218  }
219 
220  void process (int numSamples, double* const* arrayOfChannels)
221  {
222  m_state.process (numSamples, arrayOfChannels,
224  }
225 
226 protected:
227  ChannelsState <Channels,
228  typename DesignClass::template State <StateType> > m_state;
229 };
230 
231 //------------------------------------------------------------------------------
232 
233 /*
234  * This container combines a raw filter with state information
235  * so it can process channels. In order to set up the filter you
236  * must call a setup function directly. Smooth changes are
237  * not supported, but this class has a smaller footprint.
238  *
239  */
240 template <class FilterClass,
241  int Channels = 0,
242  class StateType = DirectFormII>
243 class SimpleFilter : public FilterClass
244 {
245 public:
246  int getNumChannels()
247  {
248  return Channels;
249  }
250 
251  void reset ()
252  {
253  m_state.reset();
254  }
255 
256  template <typename Sample>
257  void process (int numSamples, Sample* const* arrayOfChannels)
258  {
259  m_state.process (numSamples, arrayOfChannels, *((FilterClass*)this));
260  }
261 
262 protected:
263  ChannelsState <Channels,
264  typename FilterClass::template State <StateType> > m_state;
265 };
266 
267 }
268 
269 #endif