From c9d31d6e5870cf95861f3411b8cb78d26aab9c95 Mon Sep 17 00:00:00 2001 From: Paul Date: Mon, 26 Aug 2024 14:07:44 -0400 Subject: [PATCH] Make findZone non-allocating (#1191) Closes #1146 --- src/engine/engine.h | 16 +++++++++------- src/engine/engine_voice_responder.cpp | 17 ++++++++--------- 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/src/engine/engine.h b/src/engine/engine.h index f42aca7d..14cf4f89 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -129,11 +129,10 @@ struct Engine : MoveableOnly, SampleRateSupport int16_t key{-1}; int32_t noteid{-1}; }; - std::vector findZone(int16_t channel, int16_t key, int32_t noteId, - int16_t velocity) + size_t findZone(int16_t channel, int16_t key, int32_t noteId, int16_t velocity, + std::array &res) { - // TODO: This allocates which is a bummer - std::vector res; + size_t idx{0}; for (const auto &[pidx, part] : sst::cpputils::enumerate(*patch)) { if (!part->configuration.mute && @@ -147,14 +146,15 @@ struct Engine : MoveableOnly, SampleRateSupport if (zone->mapping.keyboardRange.includes(key) && zone->mapping.velocityRange.includes(velocity)) { - res.push_back( - {(size_t)pidx, (size_t)gidx, (size_t)zidx, channel, key, noteId}); + res[idx] = {(size_t)pidx, (size_t)gidx, (size_t)zidx, + channel, key, noteId}; + idx++; } } } } } - return res; + return idx; } tuning::MidikeyRetuner midikeyRetuner; @@ -168,6 +168,8 @@ struct Engine : MoveableOnly, SampleRateSupport struct VoiceManagerResponder { Engine &engine; + std::array findZoneWorkingBuffer; + VoiceManagerResponder(Engine &e) : engine(e) {} std::function voiceEndCallback{nullptr}; diff --git a/src/engine/engine_voice_responder.cpp b/src/engine/engine_voice_responder.cpp index 0b5431eb..3651ebe1 100644 --- a/src/engine/engine_voice_responder.cpp +++ b/src/engine/engine_voice_responder.cpp @@ -35,9 +35,10 @@ int32_t Engine::VoiceManagerResponder::voiceCountForInitializationAction( { // TODO: We can optimize this so we don't have to find twice in the future auto useKey = engine.midikeyRetuner.remapKeyTo(channel, key); - auto nts = engine.findZone(channel, useKey, noteId, std::clamp((int)(velocity * 128), 0, 127)); + auto nts = engine.findZone(channel, useKey, noteId, std::clamp((int)(velocity * 128), 0, 127), + findZoneWorkingBuffer); - return nts.size(); + return nts; } int32_t Engine::VoiceManagerResponder::initializeMultipleVoices( @@ -45,11 +46,12 @@ int32_t Engine::VoiceManagerResponder::initializeMultipleVoices( uint16_t channel, uint16_t key, int32_t noteId, float velocity, float retune) { auto useKey = engine.midikeyRetuner.remapKeyTo(channel, key); - auto nts = engine.findZone(channel, useKey, noteId, std::clamp((int)(velocity * 128), 0, 127)); + auto nts = engine.findZone(channel, useKey, noteId, std::clamp((int)(velocity * 128), 0, 127), + findZoneWorkingBuffer); - int idx{0}; - for (const auto &path : nts) + for (auto idx = 0; idx < nts; ++idx) { + const auto &path = findZoneWorkingBuffer[idx]; auto &z = engine.zoneByPath(path); auto nbSampleLoadedInZone = z->getNumSampleLoaded(); @@ -64,7 +66,6 @@ int32_t Engine::VoiceManagerResponder::initializeMultipleVoices( v->attack(); } voiceInitWorkingBuffer[idx] = v; - idx++; } else if (z->sampleData.variantPlaybackMode == Zone::UNISON) { @@ -79,7 +80,6 @@ int32_t Engine::VoiceManagerResponder::initializeMultipleVoices( v->attack(); } voiceInitWorkingBuffer[idx] = v; - idx++; } } else @@ -152,12 +152,11 @@ int32_t Engine::VoiceManagerResponder::initializeMultipleVoices( v->attack(); } voiceInitWorkingBuffer[idx] = v; - idx++; } } } engine.midiNoteStateCounter++; - return idx; + return nts; } void Engine::VoiceManagerResponder::releaseVoice(voice::Voice *v, float velocity) { v->release(); }