Pulp 1.88.0
Cross-platform audio plugin framework
Loading...
Searching...
No Matches
mod_matrix.hpp
Go to the documentation of this file.
1#pragma once
2
25
26#include <array>
27#include <algorithm>
28#include <cmath>
29#include <cstddef>
30#include <span>
31
32namespace pulp::signal {
33
35template <int MaxSlots = 32, typename SampleType = float>
36struct ModMatrixT {
37 static constexpr int kMaxSlots = MaxSlots;
38
43 struct Slot {
44 int source = -1;
45 int dest = -1;
46 int via = -1;
47 SampleType depth = SampleType{0};
48 };
49
50 std::array<Slot, MaxSlots> slots{};
51
52 void clear() { slots.fill(Slot{}); }
53
54 void clear_slot(int index) {
55 if (index < 0 || index >= MaxSlots) return;
56 slots[static_cast<std::size_t>(index)] = Slot{};
57 }
58
60 bool set_slot(int index, int source, int dest, SampleType depth, int via = -1) {
61 if (index < 0 || index >= MaxSlots) return false;
62 auto& slot = slots[static_cast<std::size_t>(index)];
63 slot.source = source;
64 slot.dest = dest;
65 slot.depth = depth;
66 slot.via = via;
67 return true;
68 }
69
83 void evaluate(std::span<const SampleType> sources, std::span<SampleType> dests) const {
84 const auto source_count = static_cast<int>(sources.size());
85 const auto dest_count = static_cast<int>(dests.size());
86 for (const auto& slot : slots) {
87 // Two integer compares reject an inactive slot before any load of
88 // the source arrays, which is what keeps an unused matrix free.
89 if (slot.source < 0 || slot.dest < 0) continue;
90 if (slot.depth == SampleType{0}) continue;
91 if (slot.source >= source_count || slot.dest >= dest_count) continue;
92 SampleType value = sources[static_cast<std::size_t>(slot.source)] * slot.depth;
93 if (slot.via >= 0 && slot.via < source_count)
94 value *= sources[static_cast<std::size_t>(slot.via)];
95 dests[static_cast<std::size_t>(slot.dest)] += value;
96 }
97 }
98
100 int active_count() const {
101 int count = 0;
102 for (const auto& slot : slots)
103 if (slot.source >= 0 && slot.dest >= 0 && slot.depth != SampleType{0}) ++count;
104 return count;
105 }
106};
107
110
116template <std::size_t NumSources, std::size_t NumDestinations,
117 typename SampleType = float>
119public:
120 static constexpr std::size_t kMaxRoutes = NumSources * NumDestinations;
121 static constexpr std::size_t num_sources = NumSources;
122 static constexpr std::size_t num_destinations = NumDestinations;
123
124 bool add_route(std::size_t source, std::size_t destination, SampleType depth) {
125 if (source >= NumSources || destination >= NumDestinations || count_ >= kMaxRoutes)
126 return false;
127 routes_[count_++] = Route{source, destination,
128 std::clamp(depth, SampleType{-1}, SampleType{1})};
129 return true;
130 }
131
132 void clear() { count_ = 0; }
133 std::size_t route_count() const { return count_; }
134
135 void set_source(std::size_t source, SampleType value) {
136 if (source < NumSources) sources_[source] = value;
137 }
138
139 SampleType source(std::size_t index) const {
140 return index < NumSources ? sources_[index] : SampleType{0};
141 }
142
143 void reset() {
144 sources_.fill(SampleType{0});
145 destinations_.fill(SampleType{0});
146 }
147
148 void process() {
149 destinations_.fill(SampleType{0});
150 for (std::size_t i = 0; i < count_; ++i) {
151 const Route& route = routes_[i];
152 destinations_[route.destination] += sources_[route.source] * route.depth;
153 }
154 }
155
156 SampleType get(std::size_t destination) const {
157 return destination < NumDestinations ? destinations_[destination] : SampleType{0};
158 }
159
160 SampleType worst_case_for(std::size_t destination) const {
161 SampleType sum{0};
162 for (std::size_t i = 0; i < count_; ++i)
163 if (routes_[i].destination == destination) sum += std::abs(routes_[i].depth);
164 return sum;
165 }
166
167private:
168 struct Route {
169 std::size_t source = 0;
170 std::size_t destination = 0;
171 SampleType depth = SampleType{0};
172 };
173
174 std::array<Route, kMaxRoutes> routes_{};
175 std::array<SampleType, NumSources> sources_{};
176 std::array<SampleType, NumDestinations> destinations_{};
177 std::size_t count_ = 0;
178};
179
184namespace round2 {
185template <std::size_t NumSources, std::size_t NumDestinations,
186 typename SampleType = float>
188} // namespace round2
189
190} // namespace pulp::signal
Dense Round-2 matrix facade.
Definition mod_matrix.hpp:118
SampleType source(std::size_t index) const
Definition mod_matrix.hpp:139
void reset()
Definition mod_matrix.hpp:143
static constexpr std::size_t num_destinations
Definition mod_matrix.hpp:122
std::size_t route_count() const
Definition mod_matrix.hpp:133
bool add_route(std::size_t source, std::size_t destination, SampleType depth)
Definition mod_matrix.hpp:124
void clear()
Definition mod_matrix.hpp:132
static constexpr std::size_t num_sources
Definition mod_matrix.hpp:121
void process()
Definition mod_matrix.hpp:148
void set_source(std::size_t source, SampleType value)
Definition mod_matrix.hpp:135
static constexpr std::size_t kMaxRoutes
Definition mod_matrix.hpp:120
SampleType get(std::size_t destination) const
Definition mod_matrix.hpp:156
SampleType worst_case_for(std::size_t destination) const
Definition mod_matrix.hpp:160
Migration namespace for the unshipped Round-2 spelling whose template arity conflicts with the establ...
Definition mod_matrix.hpp:184
DenseModMatrixT< NumSources, NumDestinations, SampleType > ModMatrixT
Definition mod_matrix.hpp:187
Definition additive_bank.hpp:218
ModMatrixT< 32, float > ModMatrix
Definition mod_matrix.hpp:108
ModMatrixT< 32, double > ModMatrix64
Definition mod_matrix.hpp:109
@ i
Definition formant_filter_bank.hpp:20
One routing.
Definition mod_matrix.hpp:43
int dest
Definition mod_matrix.hpp:45
int via
Definition mod_matrix.hpp:46
SampleType depth
Definition mod_matrix.hpp:47
int source
Definition mod_matrix.hpp:44
Definition mod_matrix.hpp:36
static constexpr int kMaxSlots
Definition mod_matrix.hpp:37
void clear()
Definition mod_matrix.hpp:52
std::array< Slot, MaxSlots > slots
Definition mod_matrix.hpp:50
void clear_slot(int index)
Definition mod_matrix.hpp:54
int active_count() const
Number of slots currently carrying a routing.
Definition mod_matrix.hpp:100
void evaluate(std::span< const SampleType > sources, std::span< SampleType > dests) const
Accumulate every active routing into dests.
Definition mod_matrix.hpp:83
bool set_slot(int index, int source, int dest, SampleType depth, int via=-1)
Definition mod_matrix.hpp:60