21 static_assert(std::is_floating_point_v<SampleType>);
22 static_assert(MaxPorts >= 2);
23 static_assert(MaxPorts <= 4);
31 if (count >= 2 && count <= MaxPorts)
35 [[nodiscard]] std::size_t
port_count() const noexcept {
return port_count_; }
38 if (port_index >= MaxPorts)
40 const auto value =
static_cast<double>(
impedance);
41 if (!std::isfinite(value))
46 [[nodiscard]] SampleType
impedance(std::size_t port_index)
const noexcept {
47 return port_index < MaxPorts ? static_cast<SampleType>(impedances_[port_index])
56 [[nodiscard]]
bool scatter(
const SampleType* incoming, SampleType* outgoing,
57 std::size_t count)
noexcept {
58 if (incoming ==
nullptr || outgoing ==
nullptr || count != port_count_)
61 std::array<long double, MaxPorts> input{};
62 long double weighted_pressure = 0.0L;
63 long double reciprocal_sum = 0.0L;
64 for (std::size_t
i = 0;
i < count; ++
i) {
65 const auto value =
static_cast<long double>(incoming[
i]);
66 if (!std::isfinite(value)) {
67 publish_previous(outgoing, count);
71 const auto reciprocal = 1.0L /
static_cast<long double>(impedances_[
i]);
72 weighted_pressure += value * reciprocal;
73 reciprocal_sum += reciprocal;
75 if (!(reciprocal_sum > 0.0L) || !std::isfinite(weighted_pressure) ||
76 !std::isfinite(reciprocal_sum)) {
77 publish_previous(outgoing, count);
81 const auto junction_pressure = 2.0L * weighted_pressure / reciprocal_sum;
82 std::array<SampleType, MaxPorts> replacement{};
83 for (std::size_t
i = 0;
i < count; ++
i) {
84 const auto value = junction_pressure - input[
i];
85 if (!finite_sample(value)) {
86 publish_previous(outgoing, count);
89 replacement[
i] =
static_cast<SampleType
>(value);
91 for (std::size_t
i = 0;
i < count; ++
i) {
92 outgoing[
i] = replacement[
i];
93 last_output_[
i] = replacement[
i];
98 void reset() noexcept { last_output_.fill(SampleType{}); }
101 [[nodiscard]]
static bool finite_sample(
long double value)
noexcept {
102 const auto limit =
static_cast<long double>(std::numeric_limits<SampleType>::max());
103 return std::isfinite(value) && value <= limit && value >= -limit;
106 void publish_previous(SampleType* outgoing, std::size_t count)
const noexcept {
107 for (std::size_t
i = 0;
i < count; ++
i)
108 outgoing[
i] = last_output_[
i];
111 std::array<double, MaxPorts> impedances_{};
112 std::array<SampleType, MaxPorts> last_output_{};
113 std::size_t port_count_ = 2;
A bounded N-port pressure-wave scattering junction.
Definition waveguide_junction.hpp:20
float impedance(std::size_t port_index) const noexcept
Definition waveguide_junction.hpp:46
static constexpr double minimum_impedance
Definition waveguide_junction.hpp:26
void reset() noexcept
Definition waveguide_junction.hpp:98
std::size_t port_count() const noexcept
Definition waveguide_junction.hpp:35
void set_impedance(std::size_t port_index, SampleType impedance) noexcept
Definition waveguide_junction.hpp:37
bool scatter(const SampleType *incoming, SampleType *outgoing, std::size_t count) noexcept
Scatters one incoming pressure wave per active port.
Definition waveguide_junction.hpp:56
void set_port_count(std::size_t count) noexcept
Definition waveguide_junction.hpp:30
WaveguideJunctionT()
Definition waveguide_junction.hpp:28
Definition additive_bank.hpp:218
WaveguideJunctionT< double > WaveguideJunction64
Definition waveguide_junction.hpp:117
@ i
Definition formant_filter_bank.hpp:20
WaveguideJunctionT< float > WaveguideJunction
Definition waveguide_junction.hpp:116