60template <FloatType T,
int MaxRoutes = 16>
77 int addRoute(std::function<T()> source, std::function<
void(T)> target,
78 T depth = T(1), T base = T(0), T smoothMs = T(20))
82 if (numRoutes_ >= MaxRoutes || !source || !target)
return -1;
83 auto& r = routes_[
static_cast<size_t>(numRoutes_)];
84 r.source = std::move(source);
85 r.target = std::move(target);
86 r.depth.store(depth, std::memory_order_relaxed);
88 r.smoothMs = std::max(smoothMs, T(0));
98 if (route >= 0 && route < numRoutes_)
99 routes_[
static_cast<size_t>(route)].depth.store(depth, std::memory_order_relaxed);
105 for (
int i = 0; i < numRoutes_; ++i)
107 routes_[
static_cast<size_t>(i)].source =
nullptr;
108 routes_[
static_cast<size_t>(i)].target =
nullptr;
121 void update(
int numSamples,
double sampleRate)
noexcept
123 const double dt =
static_cast<double>(numSamples) / std::max(sampleRate, 1.0);
124 for (
int i = 0; i < numRoutes_; ++i)
126 auto& r = routes_[
static_cast<size_t>(i)];
127 const T depth = r.depth.load(std::memory_order_relaxed);
128 const T value = r.base + r.source() * depth;
132 if (!std::isfinite(value))
137 if (!r.primed || r.smoothMs <= T(0))
144 const double a = std::exp(-dt * 1000.0 /
static_cast<double>(r.smoothMs));
145 r.state =
static_cast<T
>(a *
static_cast<double>(r.state)
146 + (1.0 - a) *
static_cast<double>(value));
155 std::function<T()> source;
156 std::function<void(T)> target;
157 std::atomic<T> depth { T(1) };
164 std::array<Route, static_cast<size_t>(MaxRoutes)> routes_ {};
Fixed-capacity source-to-target router with per-route depth/smoothing.
void setDepth(int route, T depth) noexcept
Changes a route's depth. Control thread (relaxed atomic word, adopted by the next update()).
void update(int numSamples, double sampleRate) noexcept
Evaluates every route once. Call per audio block.
int addRoute(std::function< T()> source, std::function< void(T)> target, T depth=T(1), T base=T(0), T smoothMs=T(20))
Adds a route (call from setup/UI threads, not the audio callback).
void clear() noexcept
Removes all routes and releases their captures (setup threads only).
int getNumRoutes() const noexcept
Number of configured routes.
Main namespace for the DSPark framework.