refactor(engine): add thread-safe control capture and sub-block MIDI
Introduce a CriticalSection controlLock separating control-thread state (matrix, macros, controlLfos) from audio-thread snapshots (audioMatrix, audioMacros, lfos). captureControls() copies under lock at the start of each processBlock; the audio thread never touches control state directly. Cache parameter values in an unordered_map keyed by string_view to avoid per-sample APVTS lookups. Prebuild wavetables in the constructor instead of lazy allocation. Resize mixBuffer only in prepare(), not per block. Render MIDI events at their sample positions using sub-block rendering with renderUntil(), so notes start at the correct sub-sample offset. Make RaveController non-destructive: replace APVTS mutation with a static apply() that boosts the RenderContext and FX slots for the current block only. Remove the snapshot/restore machinery. Make currentProgram atomic. Validate state I/O: check XML tag, clamp program index, sanitize LFO shape data, and use beginChangeGesture/endChangeGesture for RAVE toggle. Reset parameters to defaults before loading preset values.
This commit is contained in:
+7
-14
@@ -1,29 +1,22 @@
|
||||
#pragma once
|
||||
|
||||
#include <JuceHeader.h>
|
||||
#include "Params.h"
|
||||
|
||||
namespace serum
|
||||
{
|
||||
|
||||
struct RenderContext;
|
||||
struct FxSlotParams;
|
||||
|
||||
// ===========================================================================
|
||||
// RAVE — one-shot "make it huge" control. Toggling on snapshots the current
|
||||
// values of the affected parameters and pushes unison, width, drive, OTT and
|
||||
// reverb to their boosted settings; toggling off restores the snapshot.
|
||||
// RAVE — non-destructive "make it huge" control. While enabled, rendering
|
||||
// boosts unison, width, drive, OTT and reverb in the current block's snapshots;
|
||||
// the underlying parameters remain unchanged when toggling on or off.
|
||||
// ===========================================================================
|
||||
class RaveController
|
||||
{
|
||||
public:
|
||||
void setEnabled (bool enabled, juce::AudioProcessorValueTreeState& apvts);
|
||||
bool isEnabled() const noexcept { return enabled; }
|
||||
void resetSnapshot();
|
||||
|
||||
private:
|
||||
bool enabled = false;
|
||||
std::vector<std::pair<juce::String, float>> snapshot;
|
||||
|
||||
void snapshotParam (const juce::String& id, juce::AudioProcessorValueTreeState& apvts);
|
||||
void setParam (const juce::String& id, float value, juce::AudioProcessorValueTreeState& apvts);
|
||||
static void apply (RenderContext& context, FxSlotParams* slots, int numSlots) noexcept;
|
||||
};
|
||||
|
||||
} // namespace serum
|
||||
|
||||
Reference in New Issue
Block a user