Wayverb
attenuator.h
1 #pragma once
2 
3 #include "waveguide/postprocessor/directional_receiver.h"
4 
5 #include "core/attenuator/null.h"
6 
7 #include "utilities/map_to_vector.h"
8 
9 namespace wayverb {
10 namespace waveguide {
11 
13 template <typename Method>
14 auto attenuate(const Method& method,
15  float Z,
16  const postprocessor::directional_receiver::output& i) {
17  using std::sqrt;
18  using std::copysign;
19  using std::pow;
20  const auto att = attenuation(method, -i.intensity);
21  const auto intensity = glm::length(i.intensity) * pow(att, 2.0f);
22  return copysign(sqrt(intensity * Z), i.pressure); // scaled method
23 }
24 
26 inline auto attenuate(const core::attenuator::null&,
27  float /*Z*/,
28  const postprocessor::directional_receiver::output& i) {
29  return i.pressure;
30 }
31 
32 template <typename Method>
33 struct attenuate_mapper final {
34  Method method;
35  float Z;
36 
37  template <typename T>
38  auto operator()(const T& t) const {
39  return attenuate(method, Z, t);
40  }
41 };
42 
43 template <typename Method>
44 auto make_attenuate_mapper(Method method, float Z) {
45  if (Z < 300 || 500 <= Z) {
46  throw std::runtime_error{"Acoustic impedance outside expected range."};
47  }
48  return attenuate_mapper<Method>{std::move(method), Z};
49 }
50 
51 template <typename It, typename Method>
52 auto make_attenuator_iterator(It it, const Method& method, float Z) {
53  return make_mapping_iterator_adapter(std::move(it),
54  make_attenuate_mapper(method, Z));
55 }
56 
57 } // namespace waveguide
58 } // namespace wayverb
Definition: capsule_base.h:9
Definition: attenuator.h:33