diff --git a/src/dsp/processor/processor.h b/src/dsp/processor/processor.h index 78bd94d1..97c3fa6e 100644 --- a/src/dsp/processor/processor.h +++ b/src/dsp/processor/processor.h @@ -250,6 +250,8 @@ struct Processor : MoveableOnly, SampleRateSupport const ProcessorStorage &ps, float *fp, int *ip, bool needsMetadata); public: + bool bypassAnyway{false}; + size_t preReserveSize[16]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; size_t preReserveSingleInstanceSize[16]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/src/dsp/processor/routing.h b/src/dsp/processor/routing.h index 4670c628..00fb98dc 100644 --- a/src/dsp/processor/routing.h +++ b/src/dsp/processor/routing.h @@ -41,6 +41,9 @@ inline void runSingleProcessor(int i, float fpitch, Processor *processors[engine Mix &outLev, Endpoints *endpoints, bool &chainIsMono, float input[2][N], float output[2][N]) { + if (processors[i]->bypassAnyway) + return; + namespace mech = sst::basic_blocks::mechanics; float tempbuf alignas(16)[2][N]; diff --git a/src/engine/group.cpp b/src/engine/group.cpp index 69a89ad9..a3fe54f8 100644 --- a/src/engine/group.cpp +++ b/src/engine/group.cpp @@ -172,6 +172,15 @@ template void Group::processWithOS(scxt::engine::Engine &e) if (processors[0] || processors[1] || processors[2] || processors[3]) { + for (int i = 0; i < processorsPerZoneAndGroup; ++i) + { + if (processors[i]) + { + memcpy(&processorIntParams[i][0], processorStorage[i].intParams.data(), + sizeof(processorIntParams[i])); + processors[i]->bypassAnyway = !processorStorage[i].isActive; + } + } #define CALL_ROUTE(FNN) \ if constexpr (OS) \ diff --git a/src/voice/voice.cpp b/src/voice/voice.cpp index 2fda663e..7274a351 100644 --- a/src/voice/voice.cpp +++ b/src/voice/voice.cpp @@ -381,7 +381,51 @@ template bool Voice::processWithOS() } \ } - if (processors[0] || processors[1] || processors[2] || processors[3]) + /* + * This is all voice time type reset logic basically. + */ + bool hasProcs{false}; + for (int i = 0; i < processorsPerZoneAndGroup; ++i) + { + auto proct = processors[i] ? processors[i]->getType() : dsp::processor::proct_none; + if (zone->processorStorage[i].type != proct) + { + if (processors[i]) + dsp::processor::unspawnProcessor(processors[i]); + processors[i] = nullptr; + proct = zone->processorStorage[i].type; + } + + if (!processors[i] && zone->processorStorage[i].isActive && + zone->processorStorage[i].type != dsp::processor::proct_none) + { + processorType[i] = proct; + // this is copied below in the init. + processors[i] = dsp::processor::spawnProcessorInPlace( + processorType[i], zone->getEngine()->getMemoryPool().get(), + processorPlacementStorage[i], dsp::processor::processorMemoryBufferSize, + zone->processorStorage[i], endpoints->processorTarget[i].fp, processorIntParams[i], + forceOversample, false); + + processors[i]->setSampleRate(sampleRate * (forceOversample ? 2 : 1)); + processors[i]->setTempoPointer(&(zone->getEngine()->transport.tempo)); + + processors[i]->init(); + processors[i]->setKeytrack(zone->processorStorage[i].isKeytracked); + + processorConsumesMono[i] = monoGenerator && processors[i]->canProcessMono(); + } + if (processors[i]) + { + memcpy(&processorIntParams[i][0], zone->processorStorage[i].intParams.data(), + sizeof(processorIntParams[i])); + processors[i]->bypassAnyway = !zone->processorStorage[i].isActive; + } + + hasProcs = hasProcs || processors[i]; + } + + if (hasProcs) { switch (zone->outputInfo.procRouting) { @@ -689,6 +733,7 @@ void Voice::initializeProcessors() if ((processorIsActive[i] && processorType[i] != dsp::processor::proct_none) || (processorType[i] == dsp::processor::proct_none && !processorIsActive[i])) { + // this init code is partly copied above in the voice state toggle processors[i] = dsp::processor::spawnProcessorInPlace( processorType[i], zone->getEngine()->getMemoryPool().get(), processorPlacementStorage[i], dsp::processor::processorMemoryBufferSize,