From 45f7096ecea2a1593c75f2b27492e7f5f57d4b04 Mon Sep 17 00:00:00 2001 From: Paul Walker Date: Mon, 18 Nov 2024 15:23:45 -0500 Subject: [PATCH] Hook up legato mode from the voice manager This implements legato mode from the voice manager with the restart and restart-retrigger modes intact. Critically voice glide is not in place so its a bit odd but does what you want. --- libs/sst/sst-voicemanager | 2 +- .../components/GroupSettingsCard.cpp | 18 ++++++++++-- src/engine/engine.h | 6 +++- src/engine/engine_voice_responder.cpp | 28 +++++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/libs/sst/sst-voicemanager b/libs/sst/sst-voicemanager index 67942144..5f741a43 160000 --- a/libs/sst/sst-voicemanager +++ b/libs/sst/sst-voicemanager @@ -1 +1 @@ -Subproject commit 6794214460d3314c8993f25614749ce8fc147c67 +Subproject commit 5f741a43ec30e7393088a7d342ca5568419012ac diff --git a/src-ui/app/edit-screen/components/GroupSettingsCard.cpp b/src-ui/app/edit-screen/components/GroupSettingsCard.cpp index ca183852..0afddbbb 100644 --- a/src-ui/app/edit-screen/components/GroupSettingsCard.cpp +++ b/src-ui/app/edit-screen/components/GroupSettingsCard.cpp @@ -151,7 +151,15 @@ void GroupSettingsCard::rebuildFromInfo() if (info.vmPlayModeInt == (int32_t)engine::Engine::voiceManager_t::PlayMode::MONO_NOTES) { polyMenu->setEnabled(false); - polyModeMenu->setLabel("MONO"); + if (info.vmPlayModeFeaturesInt & + (int32_t)engine::Engine::voiceManager_t::MonoPlayModeFeatures::MONO_LEGATO) + { + polyModeMenu->setLabel("LEG"); + } + else + { + polyModeMenu->setLabel("MONO"); + } repaint(); } else @@ -232,9 +240,15 @@ void GroupSettingsCard::showPolyModeMenu() w->rebuildFromInfo(); w->sendToSerialization(messaging::client::UpdateGroupOutputInfoPolyphony{w->info}); }); - p.addItem("Legato", false, false, [w = juce::Component::SafePointer(this)]() { + p.addItem("Legato", true, false, [w = juce::Component::SafePointer(this)]() { if (!w) return; + w->info.vmPlayModeInt = (uint32_t)engine::Engine::voiceManager_t::PlayMode::MONO_NOTES; + w->info.vmPlayModeFeaturesInt = + (uint64_t)engine::Engine::voiceManager_t::MonoPlayModeFeatures::NATURAL_LEGATO; + + w->rebuildFromInfo(); + w->sendToSerialization(messaging::client::UpdateGroupOutputInfoPolyphony{w->info}); }); p.addSeparator(); p.addSectionHeader("Mono Release Priority"); diff --git a/src/engine/engine.h b/src/engine/engine.h index 1d07ba52..3a79f4ad 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -215,8 +215,12 @@ struct Engine : MoveableOnly, SampleRateSupport void terminateVoice(voice::Voice *v); void retriggerVoiceWithNewNoteID(voice::Voice *v, int32_t noteid, float velocity) { - SCLOG("Retrigger Voice Unimplemented") + SCLOG("Retrigger Voice Unimplemented"); + assert(false); } + void moveVoice(typename VMConfig::voice_t *, uint16_t, uint16_t, uint16_t, float); + void moveAndRetriggerVoice(typename VMConfig::voice_t *, uint16_t, uint16_t, uint16_t, + float); void setVoiceMIDIMPEChannelPitchBend(voice::Voice *v, uint16_t pb14bit); void setVoiceMIDIMPEChannelPressure(voice::Voice *v, int8_t val); diff --git a/src/engine/engine_voice_responder.cpp b/src/engine/engine_voice_responder.cpp index 1f3de6fb..bcd29320 100644 --- a/src/engine/engine_voice_responder.cpp +++ b/src/engine/engine_voice_responder.cpp @@ -269,6 +269,34 @@ void Engine::VoiceManagerResponder::setVoiceMIDIMPETimbre(voice::Voice *v, int8_ v->mpeTimbre = val / 127.0; } +void Engine::VoiceManagerResponder::moveVoice(VMConfig::voice_t *v, uint16_t port, uint16_t channel, + uint16_t key, float vel) +{ + auto dkey = v->key - v->originalMidiKey; + v->key = key; + v->originalMidiKey = key - dkey; + v->calculateVoicePitch(); +} + +void Engine::VoiceManagerResponder::moveAndRetriggerVoice(VMConfig::voice_t *v, uint16_t port, + uint16_t channel, uint16_t key, float vel) +{ + auto dkey = v->key - v->originalMidiKey; + v->key = key; + v->originalMidiKey = key - dkey; + v->calculateVoicePitch(); + v->isGated = true; + for (auto &eg : v->eg) + { + eg.attackFrom(eg.outBlock0); + } + for (auto &eg : v->egOS) + { + eg.attackFrom(eg.outBlock0); + } + SCLOG("TODO - Gate voice and Retrigger AEG and EG2"); +} + void Engine::MonoVoiceManagerResponder::setMIDIPitchBend(int16_t channel, int16_t pb14bit) { auto fv = (pb14bit - 8192) / 8192.f;