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