diff --git a/NAM/container.cpp b/NAM/container.cpp index 8d6b6fe2..2a103f4b 100644 --- a/NAM/container.cpp +++ b/NAM/container.cpp @@ -51,7 +51,8 @@ ContainerModel::ContainerModel(std::vector submodels, const double exp void ContainerModel::process(NAM_SAMPLE** input, NAM_SAMPLE** output, const int num_frames) { - _active_model().process(input, output, num_frames); + const size_t active_index = _active_index.load(std::memory_order_acquire); + _submodels[active_index].model->process(input, output, num_frames); } void ContainerModel::prewarm() @@ -69,7 +70,7 @@ void ContainerModel::Reset(const double sampleRate, const int maxBufferSize) void ContainerModel::SetSlimmableSize(const double val) { - auto active_index = _submodels.size() - 1; + size_t active_index = _submodels.size() - 1; for (size_t i = 0; i < _submodels.size(); ++i) { if (val < _submodels[i].max_value) @@ -78,7 +79,17 @@ void ContainerModel::SetSlimmableSize(const double val) break; } } - if (active_index == _active_index) // No change to active model, so nothing to do + + // Fast path: no change to active model. + if (active_index == _active_index.load(std::memory_order_acquire)) + { + return; + } + + // Plugin host can deliver param changes from both UI/controller and processor paths. + // Serialize reset+prewarm so only one thread can perform model activation at a time. + std::lock_guard lock(_slim_set_mutex); + if (active_index == _active_index.load(std::memory_order_acquire)) { return; } @@ -87,7 +98,7 @@ void ContainerModel::SetSlimmableSize(const double val) _submodels[active_index].model->ResetAndPrewarm(sr, GetMaxBufferSize()); // Finally set when we're ready: - _active_index = active_index; + _active_index.store(active_index, std::memory_order_release); } // ============================================================================= diff --git a/NAM/container.h b/NAM/container.h index d69f03d0..dccc9149 100644 --- a/NAM/container.h +++ b/NAM/container.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include #include @@ -42,9 +44,8 @@ class ContainerModel : public DSP, public SlimmableModel private: std::vector _submodels; - size_t _active_index = 0; - - DSP& _active_model() { return *_submodels[_active_index].model; } + std::atomic _active_index{0}; + std::mutex _slim_set_mutex; }; // Config / registration