3 #include "waveguide/arbitrary_magnitude_filter.h" 4 #include "waveguide/cl/filter_structs.h" 5 #include "waveguide/filters.h" 6 #include "waveguide/stable.h" 8 #include "core/cosine_interp.h" 9 #include "core/filter_coefficients.h" 10 #include "core/surfaces.h" 12 #include "hrtf/multiband.h" 14 #include "utilities/for_each.h" 15 #include "utilities/map.h" 20 template <
size_t... Ix>
21 constexpr
auto to_raw_impedance_coefficients(
22 const coefficients<
sizeof...(Ix) - 1>& c, std::index_sequence<Ix...>) {
23 return coefficients_canonical{{c.a[Ix] + c.b[Ix]...},
24 {c.a[Ix] - c.b[Ix]...}};
27 template <
size_t order>
28 constexpr
auto to_raw_impedance_coefficients(
const coefficients<order>& c) {
29 return to_raw_impedance_coefficients(c,
30 std::make_index_sequence<order + 1>{});
34 template <
size_t order>
35 auto to_impedance_coefficients(
const coefficients<order>& c) {
36 auto ret = detail::to_raw_impedance_coefficients(c);
39 const auto norm = 1.0 / ret.a[0];
40 const auto do_normalize = [&](
auto& i) {
41 util::for_each([&](
auto& i) { i *= norm; }, i);
52 template <
size_t... Ix>
53 constexpr
auto make_coefficients_canonical(
54 const core::filter_coefficients<
sizeof...(Ix) - 1,
sizeof...(Ix) - 1>&
56 std::index_sequence<Ix...>) {
57 return coefficients_canonical{{std::get<Ix>(coeffs.b)...},
58 {std::get<Ix>(coeffs.a)...}};
61 constexpr
auto make_coefficients_canonical(
62 const core::filter_coefficients<coefficients_canonical::order,
63 coefficients_canonical::order>&
65 return make_coefficients_canonical(
67 std::make_index_sequence<coefficients_canonical::order + 1>{});
72 inline auto to_flat_coefficients(
double absorption) {
73 return to_impedance_coefficients(coefficients_canonical{
74 {core::absorption_to_pressure_reflectance(absorption)}, {1}});
80 auto compute_reflectance_filter_coefficients(T&& absorption,
82 const auto band_centres =
83 util::map([](
auto i) {
return i * 2; },
84 hrtf_data::hrtf_band_centres(sample_rate));
85 const auto reflectance = util::map(
87 return core::absorption_to_pressure_reflectance(i);
91 constexpr
auto lim = 1000;
92 for (
auto delay = 0; delay != lim; ++delay) {
93 const auto reflectance_coeffs = make_coefficients_canonical(
94 arbitrary_magnitude_filter<coefficients_canonical::order>(
95 make_frequency_domain_envelope(band_centres,
98 if (is_stable(reflectance_coeffs.a)) {
99 return reflectance_coeffs;
103 throw std::runtime_error{
"Unable to generate stable boundary filter."};
Definition: capsule_base.h:9