Open Ephys GUI
 All Classes Functions Variables
Legendre.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_LEGENDRE_H
37 #define DSPFILTERS_LEGENDRE_H
38 
39 #include "Common.h"
40 #include "Cascade.h"
41 #include "Design.h"
42 #include "Filter.h"
43 #include "PoleFilter.h"
44 #include "RootFinder.h"
45 
46 namespace Dsp {
47 
48 /*
49  * Filters with Legendre / "Optimum-L" response characteristics
50  *
51  */
52 
53 namespace Legendre {
54 
55 // Numerical computation of Legendre "Optimum-L" polynomials
56 
58 {
59 public:
60  void solve (int n);
61 
62  double* coef()
63  {
64  return m_w;
65  }
66 
67 private:
68  void legendre (double* p, int n);
69 
70 protected:
71  int m_maxN;
72  double* m_w;
73  double* m_a;
74  double* m_p;
75  double* m_s;
76  double* m_v;
77  double* m_aa;
78  double* m_bb;
79 };
80 
81 template <int maxN>
83 {
84 public:
86  {
87  m_maxN = maxN;
88  m_w = m_ws;
89  m_a = m_as;
90  m_p = m_ps;
91  m_s = m_ss;
92  m_v = m_vs;
93  m_aa = m_aas;
94  m_bb = m_bbs;
95  }
96 
97  void solve (int n)
98  {
99  assert (n <= maxN);
100  PolynomialFinderBase::solve (n);
101  }
102 
103 private:
104  double m_ws [2 * maxN + 1];
105  double m_as [ maxN + 1];
106  double m_ps [2 * maxN + 1];
107  double m_ss [2 * maxN + 1];
108  double m_vs [2 * maxN + 4];
109  double m_aas [ maxN + 1];
110  double m_bbs [ maxN + 1];
111 };
112 
113 //------------------------------------------------------------------------------
114 
115 // A Workspace is necessary to construct the polynomial and find its roots
116 
118 {
120  RootFinderBase* rootsBase)
121  : poly (*polyBase)
122  , roots (*rootsBase)
123  {
124  }
125 
126  PolynomialFinderBase& poly;
127  RootFinderBase& roots;
128 
129 private:
131  WorkspaceBase& operator= (WorkspaceBase&);
132 };
133 
134 template <int MaxOrder>
136 {
137  Workspace ()
138  : WorkspaceBase (&m_poly, &m_roots)
139  {
140  }
141 
142 private:
145 };
146 
147 //------------------------------------------------------------------------------
148 
149 // Half-band analog prototypes (s-plane)
150 
151 class AnalogLowPass : public LayoutBase
152 {
153 public:
154  AnalogLowPass ();
155 
156  void design (const int numPoles, WorkspaceBase* w);
157 
158 private:
159  int m_numPoles;
160 };
161 
162 //------------------------------------------------------------------------------
163 
164 // Factored implementations to reduce template instantiations
165 
166 struct LowPassBase : PoleFilterBase <AnalogLowPass>
167 {
168  void setup (int order,
169  double sampleRate,
170  double cutoffFrequency,
171  WorkspaceBase* w);
172 };
173 
174 struct HighPassBase : PoleFilterBase <AnalogLowPass>
175 {
176  void setup (int order,
177  double sampleRate,
178  double cutoffFrequency,
179  WorkspaceBase* w);
180 };
181 
182 struct BandPassBase : PoleFilterBase <AnalogLowPass>
183 {
184  void setup (int order,
185  double sampleRate,
186  double centerFrequency,
187  double widthFrequency,
188  WorkspaceBase* w);
189 };
190 
191 struct BandStopBase : PoleFilterBase <AnalogLowPass>
192 {
193  void setup (int order,
194  double sampleRate,
195  double centerFrequency,
196  double widthFrequency,
197  WorkspaceBase* w);
198 };
199 
200 //------------------------------------------------------------------------------
201 
202 //
203 // Raw filters
204 //
205 
206 template <int MaxOrder>
207 struct LowPass : PoleFilter <LowPassBase, MaxOrder>
208 {
209  void setup (int order,
210  double sampleRate,
211  double cutoffFrequency)
212  {
214  LowPassBase::setup (order,
215  sampleRate,
216  cutoffFrequency,
217  &w);
218  }
219 };
220 
221 template <int MaxOrder>
222 struct HighPass : PoleFilter <HighPassBase, MaxOrder>
223 {
224  void setup (int order,
225  double sampleRate,
226  double cutoffFrequency)
227  {
229  HighPassBase::setup (order,
230  sampleRate,
231  cutoffFrequency,
232  &w);
233  }
234 };
235 
236 template <int MaxOrder>
237 struct BandPass : PoleFilter <BandPassBase, MaxOrder, MaxOrder*2>
238 {
239  void setup (int order,
240  double sampleRate,
241  double centerFrequency,
242  double widthFrequency)
243  {
245  BandPassBase::setup (order,
246  sampleRate,
247  centerFrequency,
248  widthFrequency,
249  &w);
250  }
251 };
252 
253 template <int MaxOrder>
254 struct BandStop : PoleFilter <BandStopBase, MaxOrder, MaxOrder*2>
255 {
256  void setup (int order,
257  double sampleRate,
258  double centerFrequency,
259  double widthFrequency)
260  {
262  BandStopBase::setup (order,
263  sampleRate,
264  centerFrequency,
265  widthFrequency,
266  &w);
267  }
268 };
269 
270 //------------------------------------------------------------------------------
271 
272 //
273 // Gui-friendly Design layer
274 //
275 
276 namespace Design {
277 
279 {
280  enum
281  {
282  NumParams = 3
283  };
284 
285  static int getNumParams ()
286  {
287  return 3;
288  }
289 
290  static const ParamInfo getParamInfo_2 ()
291  {
292  return ParamInfo::defaultCutoffFrequencyParam ();
293  }
294 };
295 
296 template <class FilterClass>
297 struct TypeI : TypeIBase, FilterClass
298 {
299  void setParams (const Params& params)
300  {
301  FilterClass::setup (int(params[1]), params[0], params[2]);
302  }
303 };
304 
306 {
307  enum
308  {
309  NumParams = 4
310  };
311 
312  static int getNumParams ()
313  {
314  return 4;
315  }
316 
317  static const ParamInfo getParamInfo_2 ()
318  {
319  return ParamInfo::defaultCenterFrequencyParam ();
320  }
321 
322  static const ParamInfo getParamInfo_3 ()
323  {
324  return ParamInfo::defaultBandwidthHzParam ();
325  }
326 };
327 
328 template <class FilterClass>
329 struct TypeII : TypeIIBase, FilterClass
330 {
331  void setParams (const Params& params)
332  {
333  FilterClass::setup (int(params[1]), params[0], params[2], params[3]);
334  }
335 };
336 
337 // Factored kind and name
338 
340 {
341  static Kind getKind () { return kindLowPass; }
342  static const char* getName() { return "Legendre Low Pass"; }
343 };
344 
346 {
347  static Kind getKind () { return kindHighPass; }
348  static const char* getName() { return "Legendre High Pass"; }
349 };
350 
352 {
353  static Kind getKind () { return kindHighPass; }
354  static const char* getName() { return "Legendre Band Pass"; }
355 };
356 
358 {
359  static Kind getKind () { return kindHighPass; }
360  static const char* getName() { return "Legendre Band Stop"; }
361 };
362 
363 // This glues on the Order parameter
364 template <int MaxOrder,
365  template <class> class TypeClass,
366  template <int> class FilterClass>
367 struct OrderBase : TypeClass <FilterClass <MaxOrder> >
368 {
369  const ParamInfo getParamInfo_1 () const
370  {
371  return ParamInfo (idOrder, "Order", "Order",
372  1, MaxOrder, 2,
373  &ParamInfo::Int_toControlValue,
374  &ParamInfo::Int_toNativeValue,
375  &ParamInfo::Int_toString);
376 
377  }
378 };
379 
380 //------------------------------------------------------------------------------
381 
382 //
383 // Design filters
384 //
385 
386 template <int MaxOrder>
387 struct LowPass : OrderBase <MaxOrder, TypeI, Legendre::LowPass>,
389 {
390 };
391 
392 template <int MaxOrder>
393 struct HighPass : OrderBase <MaxOrder, TypeI, Legendre::HighPass>,
395 {
396 };
397 
398 template <int MaxOrder>
399 struct BandPass : OrderBase <MaxOrder, TypeII, Legendre::BandPass>,
401 {
402 };
403 
404 template <int MaxOrder>
405 struct BandStop : OrderBase <MaxOrder, TypeII, Legendre::BandStop>,
407 {
408 };
409 
410 }
411 
412 }
413 
414 }
415 
416 #endif
417