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