Line data Source code
1 : /**
2 : * \file Chebyshev2Filter.hxx
3 : */
4 :
5 : #include "Chebyshev2Filter.h"
6 : #include <ATK/EQ/helpers.h>
7 :
8 : #include <boost/math/constants/constants.hpp>
9 : #include <boost/math/special_functions/asinh.hpp>
10 :
11 : namespace Chebyshev2Utilities
12 : {
13 : template<typename DataType>
14 92 : void create_chebyshev2_analog_coefficients(int order, DataType ripple, EQUtilities::ZPK<DataType>& zpk)
15 : {
16 92 : zpk.z.clear(); // no zeros for this filter type
17 92 : zpk.p.clear();
18 :
19 92 : DataType de = static_cast<DataType>(1.0 / std::sqrt(std::pow(10, (0.1 * ripple)) - 1));
20 92 : DataType mu = static_cast<DataType>(boost::math::asinh(1.0 / de) / order);
21 :
22 188 : for(gsl::index i = -order+1; i < order; i += 2)
23 : {
24 96 : std::complex<DataType> p1 = -std::complex<DataType>(std::cos(i * boost::math::constants::pi<DataType>() / (2 * order)), std::sin(i * boost::math::constants::pi<DataType>() / (2 * order)));
25 96 : std::complex<DataType> p2 = std::complex<DataType>(std::sinh(mu) * p1.real(), std::cosh(mu) * p1.imag());
26 :
27 96 : zpk.p.push_back(std::complex<DataType>(1, 0) / p2);
28 :
29 96 : if(i == 0)
30 : {
31 56 : continue;
32 : }
33 :
34 40 : zpk.z.push_back(std::complex<DataType>(0, 1 / std::sin(i * boost::math::constants::pi<DataType>() / (2 * order))));
35 : }
36 :
37 92 : std::complex<DataType> f = 1;
38 188 : for(gsl::index i = 0; i < zpk.p.size(); ++i)
39 : {
40 96 : f *= - zpk.p[i];
41 : }
42 132 : for(gsl::index i = 0; i < zpk.z.size(); ++i)
43 : {
44 40 : f /= - zpk.z[i];
45 : }
46 92 : zpk.k = f.real();
47 92 : }
48 :
49 : template<typename DataType, typename Container>
50 46 : void create_default_chebyshev2_coeffs(size_t order, DataType ripple, DataType Wn, Container& coefficients_in, Container& coefficients_out)
51 : {
52 92 : EQUtilities::ZPK<DataType> zpk;
53 :
54 46 : int fs = 2;
55 46 : create_chebyshev2_analog_coefficients(static_cast<int>(order), ripple, zpk);
56 46 : EQUtilities::populate_lp_coeffs(Wn, fs, order, zpk, coefficients_in, coefficients_out);
57 46 : }
58 :
59 : template<typename DataType, typename Container>
60 23 : void create_bp_chebyshev2_coeffs(size_t order, DataType ripple, DataType wc1, DataType wc2, Container& coefficients_in, Container& coefficients_out)
61 : {
62 46 : EQUtilities::ZPK<DataType> zpk;
63 :
64 23 : int fs = 2;
65 23 : create_chebyshev2_analog_coefficients(static_cast<int>(order/2), ripple, zpk);
66 23 : EQUtilities::populate_bp_coeffs(wc1, wc2, fs, order, zpk, coefficients_in, coefficients_out);
67 23 : }
68 :
69 : template<typename DataType, typename Container>
70 23 : void create_bs_chebyshev2_coeffs(size_t order, DataType ripple, DataType wc1, DataType wc2, Container& coefficients_in, Container& coefficients_out)
71 : {
72 46 : EQUtilities::ZPK<DataType> zpk;
73 :
74 23 : int fs = 2;
75 23 : create_chebyshev2_analog_coefficients(static_cast<int>(order/2), ripple, zpk);
76 23 : EQUtilities::populate_bs_coeffs(wc1, wc2, fs, order, zpk, coefficients_in, coefficients_out);
77 23 : }
78 : }
79 :
80 : namespace ATK
81 : {
82 : template <typename DataType>
83 9 : Chebyshev2LowPassCoefficients<DataType>::Chebyshev2LowPassCoefficients(gsl::index nb_channels)
84 9 : :Parent(nb_channels, nb_channels)
85 : {
86 9 : }
87 :
88 : template <typename DataType_>
89 5 : void Chebyshev2LowPassCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
90 : {
91 5 : this->ripple = ripple;
92 5 : setup();
93 5 : }
94 :
95 : template <typename DataType_>
96 1 : typename Chebyshev2LowPassCoefficients<DataType_>::CoeffDataType Chebyshev2LowPassCoefficients<DataType_>::get_ripple() const
97 : {
98 1 : return ripple;
99 : }
100 :
101 : template <typename DataType_>
102 6 : void Chebyshev2LowPassCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
103 : {
104 6 : if(cut_frequency <= 0)
105 : {
106 1 : throw std::out_of_range("Frequency can't be negative");
107 : }
108 5 : this->cut_frequency = cut_frequency;
109 5 : setup();
110 5 : }
111 :
112 : template <typename DataType_>
113 1 : typename Chebyshev2LowPassCoefficients<DataType_>::CoeffDataType Chebyshev2LowPassCoefficients<DataType_>::get_cut_frequency() const
114 : {
115 1 : return cut_frequency;
116 : }
117 :
118 : template <typename DataType>
119 6 : void Chebyshev2LowPassCoefficients<DataType>::set_order(unsigned int order)
120 : {
121 6 : if(order == 0)
122 : {
123 1 : throw std::out_of_range("Order can't be null");
124 : }
125 5 : in_order = out_order = order;
126 5 : setup();
127 5 : }
128 :
129 : template <typename DataType>
130 1 : unsigned int Chebyshev2LowPassCoefficients<DataType>::get_order() const
131 : {
132 1 : return in_order;
133 : }
134 :
135 : template <typename DataType>
136 23 : void Chebyshev2LowPassCoefficients<DataType>::setup()
137 : {
138 23 : Parent::setup();
139 23 : coefficients_in.assign(in_order+1, 0);
140 23 : coefficients_out.assign(out_order, 0);
141 :
142 23 : Chebyshev2Utilities::create_default_chebyshev2_coeffs(in_order, ripple, 2 * cut_frequency / input_sampling_rate, coefficients_in, coefficients_out);
143 23 : }
144 :
145 : template <typename DataType>
146 9 : Chebyshev2HighPassCoefficients<DataType>::Chebyshev2HighPassCoefficients(gsl::index nb_channels)
147 9 : :Parent(nb_channels, nb_channels)
148 : {
149 9 : }
150 :
151 : template <typename DataType_>
152 6 : void Chebyshev2HighPassCoefficients<DataType_>::set_cut_frequency(CoeffDataType cut_frequency)
153 : {
154 6 : if(cut_frequency <= 0)
155 : {
156 1 : throw std::out_of_range("Frequency can't be negative");
157 : }
158 5 : this->cut_frequency = cut_frequency;
159 5 : setup();
160 5 : }
161 :
162 : template <typename DataType_>
163 1 : typename Chebyshev2HighPassCoefficients<DataType_>::CoeffDataType Chebyshev2HighPassCoefficients<DataType_>::get_cut_frequency() const
164 : {
165 1 : return cut_frequency;
166 : }
167 :
168 : template <typename DataType_>
169 5 : void Chebyshev2HighPassCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
170 : {
171 5 : this->ripple = ripple;
172 5 : setup();
173 5 : }
174 :
175 : template <typename DataType_>
176 1 : typename Chebyshev2HighPassCoefficients<DataType_>::CoeffDataType Chebyshev2HighPassCoefficients<DataType_>::get_ripple() const
177 : {
178 1 : return ripple;
179 : }
180 :
181 : template <typename DataType>
182 6 : void Chebyshev2HighPassCoefficients<DataType>::set_order(unsigned int order)
183 : {
184 6 : if(order == 0)
185 : {
186 1 : throw std::out_of_range("Order can't be null");
187 : }
188 5 : in_order = out_order = order;
189 5 : setup();
190 5 : }
191 :
192 : template <typename DataType>
193 1 : unsigned int Chebyshev2HighPassCoefficients<DataType>::get_order() const
194 : {
195 1 : return in_order;
196 : }
197 :
198 : template <typename DataType>
199 23 : void Chebyshev2HighPassCoefficients<DataType>::setup()
200 : {
201 23 : Parent::setup();
202 23 : coefficients_in.assign(in_order+1, 0);
203 23 : coefficients_out.assign(out_order, 0);
204 :
205 23 : Chebyshev2Utilities::create_default_chebyshev2_coeffs(in_order, ripple, (input_sampling_rate - 2 * cut_frequency) / input_sampling_rate, coefficients_in, coefficients_out);
206 51 : for(gsl::index i = in_order - 1; i >= 0; i -= 2)
207 : {
208 28 : coefficients_in[i] = - coefficients_in[i];
209 28 : coefficients_out[i] = - coefficients_out[i];
210 : }
211 23 : }
212 :
213 : template <typename DataType>
214 10 : Chebyshev2BandPassCoefficients<DataType>::Chebyshev2BandPassCoefficients(gsl::index nb_channels)
215 10 : :Parent(nb_channels, nb_channels)
216 : {
217 10 : }
218 :
219 : template <typename DataType_>
220 7 : void Chebyshev2BandPassCoefficients<DataType_>::set_cut_frequencies(std::pair<CoeffDataType, CoeffDataType> cut_frequencies)
221 : {
222 7 : if(cut_frequencies.first <= 0 || cut_frequencies.second <= 0)
223 : {
224 2 : throw std::out_of_range("Frequencies can't be negative");
225 : }
226 5 : this->cut_frequencies = cut_frequencies;
227 5 : setup();
228 5 : }
229 :
230 : template <typename DataType_>
231 3 : void Chebyshev2BandPassCoefficients<DataType_>::set_cut_frequencies(CoeffDataType f0, CoeffDataType f1)
232 : {
233 3 : set_cut_frequencies(std::make_pair(f0, f1));
234 1 : }
235 :
236 : template <typename DataType_>
237 2 : std::pair<typename Chebyshev2BandPassCoefficients<DataType_>::CoeffDataType, typename Chebyshev2BandPassCoefficients<DataType_>::CoeffDataType> Chebyshev2BandPassCoefficients<DataType_>::get_cut_frequencies() const
238 : {
239 2 : return cut_frequencies;
240 : }
241 :
242 : template <typename DataType_>
243 5 : void Chebyshev2BandPassCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
244 : {
245 5 : this->ripple = ripple;
246 5 : setup();
247 5 : }
248 :
249 : template <typename DataType_>
250 1 : typename Chebyshev2BandPassCoefficients<DataType_>::CoeffDataType Chebyshev2BandPassCoefficients<DataType_>::get_ripple() const
251 : {
252 1 : return ripple;
253 : }
254 :
255 : template <typename DataType>
256 6 : void Chebyshev2BandPassCoefficients<DataType>::set_order(unsigned int order)
257 : {
258 6 : if(order == 0)
259 : {
260 1 : throw std::out_of_range("Order can't be null");
261 : }
262 5 : in_order = out_order = 2 * order;
263 5 : setup();
264 5 : }
265 :
266 : template <typename DataType>
267 1 : unsigned int Chebyshev2BandPassCoefficients<DataType>::get_order() const
268 : {
269 1 : return in_order / 2;
270 : }
271 :
272 : template <typename DataType>
273 23 : void Chebyshev2BandPassCoefficients<DataType>::setup()
274 : {
275 23 : Parent::setup();
276 23 : coefficients_in.assign(in_order+1, 0);
277 23 : coefficients_out.assign(out_order, 0);
278 :
279 23 : Chebyshev2Utilities::create_bp_chebyshev2_coeffs(in_order, ripple, 2 * cut_frequencies.first / input_sampling_rate, 2 * cut_frequencies.second / input_sampling_rate, coefficients_in, coefficients_out);
280 23 : }
281 :
282 : template <typename DataType>
283 10 : Chebyshev2BandStopCoefficients<DataType>::Chebyshev2BandStopCoefficients(gsl::index nb_channels)
284 10 : :Parent(nb_channels, nb_channels)
285 : {
286 10 : }
287 :
288 : template <typename DataType_>
289 7 : void Chebyshev2BandStopCoefficients<DataType_>::set_cut_frequencies(std::pair<CoeffDataType, CoeffDataType> cut_frequencies)
290 : {
291 7 : if(cut_frequencies.first <= 0 || cut_frequencies.second <= 0)
292 : {
293 2 : throw std::out_of_range("Frequencies can't be negative");
294 : }
295 5 : this->cut_frequencies = cut_frequencies;
296 5 : setup();
297 5 : }
298 :
299 : template <typename DataType_>
300 3 : void Chebyshev2BandStopCoefficients<DataType_>::set_cut_frequencies(CoeffDataType f0, CoeffDataType f1)
301 : {
302 3 : set_cut_frequencies(std::make_pair(f0, f1));
303 1 : }
304 :
305 : template <typename DataType_>
306 2 : std::pair<typename Chebyshev2BandStopCoefficients<DataType_>::CoeffDataType, typename Chebyshev2BandStopCoefficients<DataType_>::CoeffDataType> Chebyshev2BandStopCoefficients<DataType_>::get_cut_frequencies() const
307 : {
308 2 : return cut_frequencies;
309 : }
310 :
311 : template <typename DataType_>
312 5 : void Chebyshev2BandStopCoefficients<DataType_>::set_ripple(CoeffDataType ripple)
313 : {
314 5 : this->ripple = ripple;
315 5 : setup();
316 5 : }
317 :
318 : template <typename DataType_>
319 1 : typename Chebyshev2BandStopCoefficients<DataType_>::CoeffDataType Chebyshev2BandStopCoefficients<DataType_>::get_ripple() const
320 : {
321 1 : return ripple;
322 : }
323 :
324 : template <typename DataType>
325 6 : void Chebyshev2BandStopCoefficients<DataType>::set_order(unsigned int order)
326 : {
327 6 : if(order == 0)
328 : {
329 1 : throw std::out_of_range("Order can't be null");
330 : }
331 5 : in_order = out_order = 2 * order;
332 5 : setup();
333 5 : }
334 :
335 : template <typename DataType>
336 1 : unsigned int Chebyshev2BandStopCoefficients<DataType>::get_order() const
337 : {
338 1 : return in_order / 2;
339 : }
340 :
341 : template <typename DataType>
342 23 : void Chebyshev2BandStopCoefficients<DataType>::setup()
343 : {
344 23 : Parent::setup();
345 23 : coefficients_in.assign(in_order+1, 0);
346 23 : coefficients_out.assign(out_order, 0);
347 :
348 23 : Chebyshev2Utilities::create_bs_chebyshev2_coeffs(in_order, ripple, 2 * cut_frequencies.first / input_sampling_rate, 2 * cut_frequencies.second / input_sampling_rate, coefficients_in, coefficients_out);
349 23 : }
350 : }
|