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
Iir::LayoutBase
Definition: Layout.h:63
Iir::Layout
Definition: Layout.h:183
Iir
Definition: Biquad.cpp:40
Iir::ComplexPair
Definition: Types.h:48
Iir::ComplexPair::isMatchedPair
bool isMatchedPair() const
Definition: Types.h:72
Iir::PoleZeroPair
Definition: Types.h:93