iir1
Layout.h
1 
36 #ifndef IIR1_LAYOUT_H
37 #define IIR1_LAYOUT_H
38 
39 #include "Common.h"
40 #include "MathSupplement.h"
41 
47 namespace Iir {
48 
49  static const char errPoleisNaN[] = "Pole to add is NaN.";
50  static const char errZeroisNaN[] = "Zero to add is NaN.";
51 
52  static const char errCantAdd2ndOrder[] = "Can't add 2nd order after a 1st order filter.";
53 
54  static const char errPolesNotComplexConj[] = "Poles not complex conjugate.";
55  static const char errZerosNotComplexConj[] = "Zeros not complex conjugate.";
56 
57  static const char pairIndexOutOfBounds[] = "Pair index out of bounds.";
58 
62  class IIR_EXPORT LayoutBase
63  {
64  public:
65  LayoutBase ()
66  : m_numPoles (0)
67  , m_maxPoles (0)
68  , m_pair (nullptr)
69  {
70  }
71 
72  LayoutBase (int maxPoles, PoleZeroPair* pairs)
73  : m_numPoles (0)
74  , m_maxPoles (maxPoles)
75  , m_pair (pairs)
76  {
77  }
78 
79  void setStorage (const LayoutBase& other)
80  {
81  m_numPoles = 0;
82  m_maxPoles = other.m_maxPoles;
83  m_pair = other.m_pair;
84  }
85 
86  void reset ()
87  {
88  m_numPoles = 0;
89  }
90 
91  int getNumPoles () const
92  {
93  return m_numPoles;
94  }
95 
96  int getMaxPoles () const
97  {
98  return m_maxPoles;
99  }
100 
101  void add (const complex_t& pole, const complex_t& zero)
102  {
103  if (m_numPoles&1)
104  throw_invalid_argument(errCantAdd2ndOrder);
105  if (Iir::is_nan(pole))
106  throw_invalid_argument(errPoleisNaN);
107  if (Iir::is_nan(zero))
108  throw_invalid_argument(errZeroisNaN);
109  m_pair[m_numPoles/2] = PoleZeroPair (pole, zero);
110  ++m_numPoles;
111  }
112 
113  void addPoleZeroConjugatePairs (const complex_t& pole,
114  const complex_t& zero)
115  {
116  if (m_numPoles&1)
117  throw_invalid_argument(errCantAdd2ndOrder);
118  if (Iir::is_nan(pole))
119  throw_invalid_argument(errPoleisNaN);
120  if (Iir::is_nan(zero))
121  throw_invalid_argument(errZeroisNaN);
122  m_pair[m_numPoles/2] = PoleZeroPair (
123  pole, zero, std::conj (pole), std::conj (zero));
124  m_numPoles += 2;
125  }
126 
127  void add (const ComplexPair& poles, const ComplexPair& zeros)
128  {
129  if (m_numPoles&1)
130  throw_invalid_argument(errCantAdd2ndOrder);
131  if (!poles.isMatchedPair ())
132  throw_invalid_argument(errPolesNotComplexConj);
133  if (!zeros.isMatchedPair ())
134  throw_invalid_argument(errZerosNotComplexConj);
135  m_pair[m_numPoles/2] = PoleZeroPair (poles.first, zeros.first,
136  poles.second, zeros.second);
137  m_numPoles += 2;
138  }
139 
140  const PoleZeroPair& getPair (int pairIndex) const
141  {
142  if ((pairIndex < 0) || (pairIndex >= (m_numPoles+1)/2))
143  throw_invalid_argument(pairIndexOutOfBounds);
144  return m_pair[pairIndex];
145  }
146 
147  const PoleZeroPair& operator[] (int pairIndex) const
148  {
149  return getPair (pairIndex);
150  }
151 
152  double getNormalW () const
153  {
154  return m_normalW;
155  }
156 
157  double getNormalGain () const
158  {
159  return m_normalGain;
160  }
161 
162  void setNormal (double w, double g)
163  {
164  m_normalW = w;
165  m_normalGain = g;
166  }
167 
168  private:
169  int m_numPoles = 0;
170  int m_maxPoles = 0;
171  PoleZeroPair* m_pair = nullptr;
172  double m_normalW = 0;
173  double m_normalGain = 1;
174  };
175 
176 //------------------------------------------------------------------------------
177 
181  template <int MaxPoles>
182  class Layout
183  {
184  public:
185  operator LayoutBase ()
186  {
187  return LayoutBase (MaxPoles, m_pairs);
188  }
189 
190  private:
191  PoleZeroPair m_pairs[(MaxPoles+1)/2] = {};
192  };
193 
194 }
195 
196 #endif
Definition: Layout.h:63
Definition: Layout.h:183
Definition: Biquad.cpp:40
Definition: Types.h:48
bool isMatchedPair() const
Definition: Types.h:72
Definition: Types.h:93