Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
waveguide_reed_exciter.hpp
Go to the documentation of this file.
1#pragma once
2
5
6#include <algorithm>
7#include <cmath>
8#include <limits>
9#include <type_traits>
10
11namespace pulp::signal {
12
22template <typename SampleType = float> class ReedExciterT {
23 static_assert(std::is_floating_point_v<SampleType>);
24 using CalculationType = std::common_type_t<SampleType, double>;
25
26 public:
27 static constexpr SampleType minimum_closing_pressure = SampleType{0.05};
28 static constexpr SampleType maximum_closing_pressure = SampleType{1};
29 static constexpr SampleType default_closing_pressure = SampleType{0.35};
30 static constexpr SampleType minimum_flow_gain = SampleType{0.01};
31 static constexpr SampleType maximum_flow_gain = SampleType{4};
32 static constexpr SampleType default_flow_gain = SampleType{1};
33 static constexpr SampleType minimum_bore_impedance = SampleType{1.0e-6};
34 static constexpr SampleType maximum_bore_impedance = std::numeric_limits<SampleType>::max();
35 static constexpr SampleType default_bore_impedance = SampleType{1};
36
37 void set_closing_pressure(SampleType value) noexcept {
38 set_finite_clamped(value, closing_pressure_, minimum_closing_pressure,
40 }
41
42 void set_flow_gain(SampleType value) noexcept {
43 set_finite_clamped(value, flow_gain_, minimum_flow_gain, maximum_flow_gain);
44 }
45
46 void set_bore_impedance(SampleType value) noexcept {
47 set_finite_clamped(value, bore_impedance_, minimum_bore_impedance, maximum_bore_impedance);
48 }
49
50 [[nodiscard]] SampleType closing_pressure() const noexcept {
51 return closing_pressure_;
52 }
53 [[nodiscard]] SampleType flow_gain() const noexcept {
54 return flow_gain_;
55 }
56 [[nodiscard]] SampleType bore_impedance() const noexcept {
57 return bore_impedance_;
58 }
59
64 [[nodiscard]] SampleType process(SampleType mouth_pressure, SampleType bore_incident) noexcept {
65 if (!finite(mouth_pressure) || !finite(bore_incident))
66 return last_finite_output_;
67
68 const auto mouth = std::clamp(static_cast<CalculationType>(mouth_pressure),
69 CalculationType{}, CalculationType{1});
70 const auto incident = static_cast<CalculationType>(bore_incident);
71 const auto pressure_difference = mouth - incident;
72 const auto opening = std::clamp(
73 CalculationType{1} -
74 pressure_difference / static_cast<CalculationType>(closing_pressure_),
75 CalculationType{}, CalculationType{1});
76 const auto signed_root = pressure_difference < 0.0 ? -std::sqrt(-pressure_difference)
77 : std::sqrt(pressure_difference);
78 const auto flow = static_cast<CalculationType>(flow_gain_) * opening * signed_root;
79 const auto output = incident - static_cast<CalculationType>(bore_impedance_) * flow;
80 const auto limit = static_cast<CalculationType>(std::numeric_limits<SampleType>::max());
81 if (!std::isfinite(output) || output > limit || output < -limit)
82 return last_finite_output_;
83
84 last_finite_output_ = static_cast<SampleType>(output);
85 return last_finite_output_;
86 }
87
88 void reset() noexcept {
89 last_finite_output_ = SampleType{};
90 }
91
92 private:
93 [[nodiscard]] static bool finite(SampleType value) noexcept {
94 return std::isfinite(value);
95 }
96
97 static void set_finite_clamped(SampleType value, SampleType& destination, SampleType minimum,
98 SampleType maximum) noexcept {
99 if (finite(value))
100 destination = std::clamp(value, minimum, maximum);
101 }
102
103 SampleType closing_pressure_ = default_closing_pressure;
104 SampleType flow_gain_ = default_flow_gain;
105 SampleType bore_impedance_ = default_bore_impedance;
106 SampleType last_finite_output_{};
107};
108
111
112} // namespace pulp::signal
A normalized pressure-controlled reed valve.
Definition waveguide_reed_exciter.hpp:22
static constexpr float default_closing_pressure
Definition waveguide_reed_exciter.hpp:29
void set_bore_impedance(SampleType value) noexcept
Definition waveguide_reed_exciter.hpp:46
static constexpr float maximum_flow_gain
Definition waveguide_reed_exciter.hpp:31
void set_flow_gain(SampleType value) noexcept
Definition waveguide_reed_exciter.hpp:42
SampleType bore_impedance() const noexcept
Definition waveguide_reed_exciter.hpp:56
static constexpr float minimum_bore_impedance
Definition waveguide_reed_exciter.hpp:33
static constexpr float maximum_closing_pressure
Definition waveguide_reed_exciter.hpp:28
SampleType closing_pressure() const noexcept
Definition waveguide_reed_exciter.hpp:50
static constexpr float maximum_bore_impedance
Definition waveguide_reed_exciter.hpp:34
void reset() noexcept
Definition waveguide_reed_exciter.hpp:88
SampleType flow_gain() const noexcept
Definition waveguide_reed_exciter.hpp:53
SampleType process(SampleType mouth_pressure, SampleType bore_incident) noexcept
Evaluates the explicit bounded valve equation.
Definition waveguide_reed_exciter.hpp:64
void set_closing_pressure(SampleType value) noexcept
Definition waveguide_reed_exciter.hpp:37
static constexpr float default_flow_gain
Definition waveguide_reed_exciter.hpp:32
static constexpr float minimum_closing_pressure
Definition waveguide_reed_exciter.hpp:27
static constexpr float minimum_flow_gain
Definition waveguide_reed_exciter.hpp:30
static constexpr float default_bore_impedance
Definition waveguide_reed_exciter.hpp:35
Definition additive_bank.hpp:218
ReedExciterT< float > ReedExciter
Definition waveguide_reed_exciter.hpp:109
@ maximum
Definition spectrum_trace.hpp:34
ReedExciterT< double > ReedExciter64
Definition waveguide_reed_exciter.hpp:110