Restore the bank fold and usage publish to the resume path, guard setActive against repeats, and make the meter fold's bound literal
The resume also hands back to a full reload when the fold moves the loaded capture's decode source, so the refs table and the audio cannot skew.
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
// meter_accumulate.h — the master meter's ACCUMULATE half: the audio thread's block-rate fold
|
||||
// into the two windows the UI drains, and the drain that starts the next window. The ballistics
|
||||
// that run on what comes out are meter_ballistics'. Header-only — the folds sit on the audio
|
||||
// thread's per-block path. Templated on the accumulator ONLY so the drain-inside-the-fold
|
||||
// interleave below can be pinned deterministically instead of raced for.
|
||||
// thread's per-block path. The folds are templated on the accumulator ONLY so the
|
||||
// drain-inside-the-fold interleave below can be pinned deterministically instead of raced for.
|
||||
|
||||
#pragma once
|
||||
|
||||
@@ -30,36 +30,39 @@ inline constexpr float kMeterGainIdentity = 1.f;
|
||||
// would then drop the block outright: it decided against storing by comparing with a window the
|
||||
// UI has since taken, so that block's reading enters neither the old window nor the new one.
|
||||
// The CAS retries against whatever the consume left, which makes `acc >= blockPeak` hold on
|
||||
// exit however the two interleave. Bounded — the audio thread is this accumulator's only other
|
||||
// writer, so one interfering consume costs one retry. Relaxed throughout: the accumulators are
|
||||
// advisory and order no other state. Block rate, never per frame.
|
||||
// exit however the two interleave. STRONG, so the loop is bounded by the interference it is
|
||||
// written against: the audio thread is the only writer besides the UI's single consume, and
|
||||
// weak's permitted spurious failure would make an unbounded retry count reachable with no
|
||||
// interference at all. Three calls per block, so the strong form costs nothing measurable.
|
||||
// Relaxed throughout: the accumulators are advisory and order no other state. `Accumulator` is
|
||||
// templated only so a test can pin the interleave; it must behave as std::atomic<float>.
|
||||
template <class Accumulator>
|
||||
inline void foldPeak(Accumulator& acc, float blockPeak) {
|
||||
float seen = acc.load(std::memory_order_relaxed);
|
||||
while (!acc.compare_exchange_weak(seen, seen > blockPeak ? seen : blockPeak,
|
||||
std::memory_order_relaxed,
|
||||
std::memory_order_relaxed)) {
|
||||
while (!acc.compare_exchange_strong(seen, seen > blockPeak ? seen : blockPeak,
|
||||
std::memory_order_relaxed,
|
||||
std::memory_order_relaxed)) {
|
||||
}
|
||||
}
|
||||
|
||||
template <class Accumulator>
|
||||
inline void foldMinGain(Accumulator& acc, float blockMinGain) {
|
||||
float seen = acc.load(std::memory_order_relaxed);
|
||||
while (!acc.compare_exchange_weak(seen, seen < blockMinGain ? seen : blockMinGain,
|
||||
std::memory_order_relaxed,
|
||||
std::memory_order_relaxed)) {
|
||||
while (!acc.compare_exchange_strong(seen, seen < blockMinGain ? seen : blockMinGain,
|
||||
std::memory_order_relaxed,
|
||||
std::memory_order_relaxed)) {
|
||||
}
|
||||
}
|
||||
|
||||
// Takes what the window accumulated and reinstalls the identity element, which IS what starts
|
||||
// the next window — so exactly one reader may consume (the shell's MasterBusMeter states who).
|
||||
template <class Accumulator>
|
||||
inline float consumePeak(Accumulator& acc) {
|
||||
// Concrete: only the folds have the interleave a test seam buys, and a template over one
|
||||
// instantiation models nothing.
|
||||
inline float consumePeak(std::atomic<float>& acc) {
|
||||
return acc.exchange(kMeterPeakIdentity, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
template <class Accumulator>
|
||||
inline float consumeMinGain(Accumulator& acc) {
|
||||
inline float consumeMinGain(std::atomic<float>& acc) {
|
||||
return acc.exchange(kMeterGainIdentity, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user