From b486f3fc62efa44ff0d1ee74163505968231d616 Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Thu, 12 Sep 2024 20:53:31 -0400 Subject: [PATCH] Int and Power on Runnign Voices and Groups for procs 1. Int values snap every block from zone (voice) and group (group) meaning running voices experience and reset int params 2. The power/bypass button works on voices and groups for processors. this does change the voice allocation pattern slightly in that we init a processor on voice on whether active or not since we don't want to do mid-init power on for a bypassed processor which becomes unbypassed, but we don't run it, just init it 3. Add the gnarly per-block logic to deal with processor type changes in running voices, not just running groups. Closes #957 --- src/dsp/processor/processor.h | 2 ++ src/dsp/processor/routing.h | 3 +++ src/engine/group.cpp | 9 ++++++++ src/voice/voice.cpp | 41 +++++++++++++++++++++++++++++++++++ 4 files changed, 55 insertions(+) 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..27c867cb 100644 --- a/src/voice/voice.cpp +++ b/src/voice/voice.cpp @@ -383,6 +383,46 @@ template bool Voice::processWithOS() if (processors[0] || processors[1] || processors[2] || processors[3]) { + /* + * This is all voice time type reset logic basically. + */ + 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; + } + } switch (zone->outputInfo.procRouting) { case engine::HasGroupZoneProcessors::procRoute_linear: @@ -689,6 +729,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,