3 #include "waveguide/frequency_domain_envelope.h" 5 #include "core/cosine_interp.h" 6 #include "core/filter_coefficients.h" 8 #include "itpp/signal/filter_design.h" 14 template <
typename It>
15 auto to_itpp_vec(It b, It e) {
16 const auto size = std::distance(b, e);
19 for (
auto i = 0; b != e; ++b, ++i) {
27 template <
size_t... Ix>
28 auto to_array(
const itpp::vec& x, std::index_sequence<Ix...>) {
29 return std::array<double,
sizeof...(Ix)>{{x[Ix]...}};
33 auto to_array(
const itpp::vec& x) {
35 throw std::runtime_error{
36 "ITPP vec cannot be converted to array with specified size."};
39 return to_array(x, std::make_index_sequence<I>{});
46 constexpr
auto make_interp_point(
const frequency_domain_envelope::point& pt) {
51 return ret{pt.frequency, pt.amplitude};
54 template <
typename It>
55 constexpr
auto make_interp_iterator(It it) {
56 return util::make_mapping_iterator_adapter(std::move(it),
64 auto arbitrary_magnitude_filter(frequency_domain_envelope env) {
65 remove_outside_frequency_range(env, util::make_range(0.0, 1.0));
66 env.insert(frequency_domain_envelope::point{0.0, 0.0});
67 env.insert(frequency_domain_envelope::point{1.0, 0.0});
69 const auto new_envelope = [&] {
70 const auto npts = 256;
71 frequency_domain_envelope ret;
72 for (
auto i = 0; i != npts; ++i) {
73 const auto frequency = i / (npts - 1.0);
74 ret.insert(frequency_domain_envelope::point{
76 interp(make_interp_iterator(env.cbegin()),
77 make_interp_iterator(env.cend()),
79 core::linear_interp_functor{})});
87 detail::to_itpp_vec(make_frequency_iterator(new_envelope.cbegin()),
88 make_frequency_iterator(new_envelope.cend())),
89 detail::to_itpp_vec(make_amplitude_iterator(new_envelope.cbegin()),
90 make_amplitude_iterator(new_envelope.cend())),
93 return core::make_filter_coefficients(detail::to_array<N + 1>(b),
94 detail::to_array<N + 1>(a));
Definition: capsule_base.h:9