From 33679ce51dd284530f8745210232a7ec38149c0d Mon Sep 17 00:00:00 2001 From: Nikodemus Siivola Date: Sun, 5 Jan 2025 13:57:50 +0200 Subject: [PATCH] envelopes 3 & 4 - pressing any of the envelope 1 or 2 segments while the same segment is already active opens the corresponding env 3 or 4 segment --- src/definitions_cxx.hpp | 4 +- src/deluge/gui/l10n/english.json | 14 ++++++ src/deluge/gui/l10n/g_english.cpp | 12 +++++ src/deluge/gui/l10n/g_seven_segment.cpp | 2 + src/deluge/gui/l10n/seven_segment.json | 2 + src/deluge/gui/l10n/strings.h | 12 +++++ .../menu_item/generate/dmenus/envelopes.py | 2 +- src/deluge/gui/menu_item/generate/g_menus.inc | 2 + src/deluge/gui/menu_item/source_selection.cpp | 15 ++++-- src/deluge/gui/ui/menus.cpp | 28 ++++++++--- src/deluge/gui/ui/menus.h | 8 +-- src/deluge/gui/ui/sound_editor.cpp | 5 +- src/deluge/modulation/params/param.cpp | 49 +++++++++++++++---- src/deluge/modulation/params/param.h | 8 +++ src/deluge/processing/sound/sound.cpp | 10 ++-- src/deluge/util/functions.cpp | 28 ++++++++++- 16 files changed, 165 insertions(+), 36 deletions(-) diff --git a/src/definitions_cxx.hpp b/src/definitions_cxx.hpp index c02b54e6e8..fde2c23ef3 100644 --- a/src/definitions_cxx.hpp +++ b/src/definitions_cxx.hpp @@ -272,7 +272,7 @@ constexpr int32_t kFlangerMinTime = (3 << 16); constexpr int32_t kFlangerAmplitude = (kModFXMaxDelay - kFlangerMinTime); constexpr int32_t kFlangerOffset = ((kModFXMaxDelay + kFlangerMinTime) >> 1); -constexpr int32_t kNumEnvelopes = 2; +constexpr int32_t kNumEnvelopes = 4; constexpr int32_t kNumLFOs = 2; constexpr int32_t kNumModulators = 2; @@ -307,6 +307,8 @@ enum class PatchSource : uint8_t { SIDECHAIN, ENVELOPE_0, ENVELOPE_1, + ENVELOPE_2, + ENVELOPE_3, LFO_LOCAL, X, Y, diff --git a/src/deluge/gui/l10n/english.json b/src/deluge/gui/l10n/english.json index 142aa5741b..40d48ad35b 100644 --- a/src/deluge/gui/l10n/english.json +++ b/src/deluge/gui/l10n/english.json @@ -31,6 +31,8 @@ "STRING_FOR_PATCH_SOURCE_LFO_LOCAL": "LFO2", "STRING_FOR_PATCH_SOURCE_ENVELOPE_0": "Envelope 1", "STRING_FOR_PATCH_SOURCE_ENVELOPE_1": "Envelope 2", + "STRING_FOR_PATCH_SOURCE_ENVELOPE_2": "Envelope 3", + "STRING_FOR_PATCH_SOURCE_ENVELOPE_3": "Envelope 4", "STRING_FOR_PATCH_SOURCE_VELOCITY": "Velocity", "STRING_FOR_PATCH_SOURCE_NOTE": "Note", "STRING_FOR_PATCH_SOURCE_SIDECHAIN": "Sidechain", @@ -91,6 +93,16 @@ "STRING_FOR_PARAM_LOCAL_ENV_1_SUSTAIN": "Env2 sustain", "STRING_FOR_PARAM_LOCAL_ENV_1_RELEASE": "Env2 release", + "STRING_FOR_PARAM_LOCAL_ENV_2_ATTACK": "Env3 attack", + "STRING_FOR_PARAM_LOCAL_ENV_2_DECAY": "Env3 decay", + "STRING_FOR_PARAM_LOCAL_ENV_2_SUSTAIN": "Env3 sustain", + "STRING_FOR_PARAM_LOCAL_ENV_2_RELEASE": "Env3 release", + + "STRING_FOR_PARAM_LOCAL_ENV_3_ATTACK": "Env4 attack", + "STRING_FOR_PARAM_LOCAL_ENV_3_DECAY": "Env4 decay", + "STRING_FOR_PARAM_LOCAL_ENV_3_SUSTAIN": "Env4 sustain", + "STRING_FOR_PARAM_LOCAL_ENV_3_RELEASE": "Env4 release", + "STRING_FOR_PARAM_GLOBAL_LFO_FREQ": "LFO1 rate", "STRING_FOR_PARAM_LOCAL_LFO_LOCAL_FREQ": "LFO2 rate", @@ -393,6 +405,8 @@ "STRING_FOR_DEV_MENU_G": "Dev Menu G", "STRING_FOR_ENVELOPE_1": "Envelope 1", "STRING_FOR_ENVELOPE_2": "Envelope 2", + "STRING_FOR_ENVELOPE_3": "Envelope 3", + "STRING_FOR_ENVELOPE_4": "Envelope 4", "STRING_FOR_VOLUME_LEVEL": "Volume", "STRING_FOR_AMOUNT_LEVEL": "Level", "STRING_FOR_REPEAT_MODE": "Repeat mode", diff --git a/src/deluge/gui/l10n/g_english.cpp b/src/deluge/gui/l10n/g_english.cpp index 8a0cb1cce1..03c8788603 100644 --- a/src/deluge/gui/l10n/g_english.cpp +++ b/src/deluge/gui/l10n/g_english.cpp @@ -43,6 +43,8 @@ PLACE_SDRAM_DATA Language english{ {STRING_FOR_PATCH_SOURCE_LFO_LOCAL, "LFO2"}, {STRING_FOR_PATCH_SOURCE_ENVELOPE_0, "Envelope 1"}, {STRING_FOR_PATCH_SOURCE_ENVELOPE_1, "Envelope 2"}, + {STRING_FOR_PATCH_SOURCE_ENVELOPE_2, "Envelope 3"}, + {STRING_FOR_PATCH_SOURCE_ENVELOPE_3, "Envelope 4"}, {STRING_FOR_PATCH_SOURCE_VELOCITY, "Velocity"}, {STRING_FOR_PATCH_SOURCE_NOTE, "Note"}, {STRING_FOR_PATCH_SOURCE_SIDECHAIN, "Sidechain"}, @@ -89,6 +91,14 @@ PLACE_SDRAM_DATA Language english{ {STRING_FOR_PARAM_LOCAL_ENV_1_DECAY, "Env2 decay"}, {STRING_FOR_PARAM_LOCAL_ENV_1_SUSTAIN, "Env2 sustain"}, {STRING_FOR_PARAM_LOCAL_ENV_1_RELEASE, "Env2 release"}, + {STRING_FOR_PARAM_LOCAL_ENV_2_ATTACK, "Env3 attack"}, + {STRING_FOR_PARAM_LOCAL_ENV_2_DECAY, "Env3 decay"}, + {STRING_FOR_PARAM_LOCAL_ENV_2_SUSTAIN, "Env3 sustain"}, + {STRING_FOR_PARAM_LOCAL_ENV_2_RELEASE, "Env3 release"}, + {STRING_FOR_PARAM_LOCAL_ENV_3_ATTACK, "Env4 attack"}, + {STRING_FOR_PARAM_LOCAL_ENV_3_DECAY, "Env4 decay"}, + {STRING_FOR_PARAM_LOCAL_ENV_3_SUSTAIN, "Env4 sustain"}, + {STRING_FOR_PARAM_LOCAL_ENV_3_RELEASE, "Env4 release"}, {STRING_FOR_PARAM_GLOBAL_LFO_FREQ, "LFO1 rate"}, {STRING_FOR_PARAM_LOCAL_LFO_LOCAL_FREQ, "LFO2 rate"}, {STRING_FOR_PARAM_GLOBAL_MOD_FX_DEPTH, "Mod-FX depth"}, @@ -352,6 +362,8 @@ PLACE_SDRAM_DATA Language english{ {STRING_FOR_DEV_MENU_G, "Dev Menu G"}, {STRING_FOR_ENVELOPE_1, "Envelope 1"}, {STRING_FOR_ENVELOPE_2, "Envelope 2"}, + {STRING_FOR_ENVELOPE_3, "Envelope 3"}, + {STRING_FOR_ENVELOPE_4, "Envelope 4"}, {STRING_FOR_VOLUME_LEVEL, "Volume"}, {STRING_FOR_AMOUNT_LEVEL, "Level"}, {STRING_FOR_REPEAT_MODE, "Repeat mode"}, diff --git a/src/deluge/gui/l10n/g_seven_segment.cpp b/src/deluge/gui/l10n/g_seven_segment.cpp index 6d0d0c38fa..e9ba63d1a6 100644 --- a/src/deluge/gui/l10n/g_seven_segment.cpp +++ b/src/deluge/gui/l10n/g_seven_segment.cpp @@ -41,6 +41,8 @@ PLACE_SDRAM_DATA Language seven_segment{ {STRING_FOR_PATCH_SOURCE_LFO_LOCAL, "LFO2"}, {STRING_FOR_PATCH_SOURCE_ENVELOPE_0, "ENV1"}, {STRING_FOR_PATCH_SOURCE_ENVELOPE_1, "ENV2"}, + {STRING_FOR_PATCH_SOURCE_ENVELOPE_2, "ENV3"}, + {STRING_FOR_PATCH_SOURCE_ENVELOPE_3, "ENV4"}, {STRING_FOR_PATCH_SOURCE_VELOCITY, "VELOCITY"}, {STRING_FOR_PATCH_SOURCE_NOTE, "NOTE"}, {STRING_FOR_PATCH_SOURCE_SIDECHAIN, "SIDE"}, diff --git a/src/deluge/gui/l10n/seven_segment.json b/src/deluge/gui/l10n/seven_segment.json index 84931b2169..4dc5c31f3b 100644 --- a/src/deluge/gui/l10n/seven_segment.json +++ b/src/deluge/gui/l10n/seven_segment.json @@ -30,6 +30,8 @@ "STRING_FOR_PATCH_SOURCE_LFO_LOCAL": "LFO2", "STRING_FOR_PATCH_SOURCE_ENVELOPE_0": "ENV1", "STRING_FOR_PATCH_SOURCE_ENVELOPE_1": "ENV2", + "STRING_FOR_PATCH_SOURCE_ENVELOPE_2": "ENV3", + "STRING_FOR_PATCH_SOURCE_ENVELOPE_3": "ENV4", "STRING_FOR_PATCH_SOURCE_VELOCITY": "VELOCITY", "STRING_FOR_PATCH_SOURCE_NOTE": "NOTE", "STRING_FOR_PATCH_SOURCE_SIDECHAIN": "SIDE", diff --git a/src/deluge/gui/l10n/strings.h b/src/deluge/gui/l10n/strings.h index bfec18cdd2..e0b6789d0a 100644 --- a/src/deluge/gui/l10n/strings.h +++ b/src/deluge/gui/l10n/strings.h @@ -37,6 +37,8 @@ enum class String : size_t { STRING_FOR_PATCH_SOURCE_LFO_LOCAL, STRING_FOR_PATCH_SOURCE_ENVELOPE_0, STRING_FOR_PATCH_SOURCE_ENVELOPE_1, + STRING_FOR_PATCH_SOURCE_ENVELOPE_2, + STRING_FOR_PATCH_SOURCE_ENVELOPE_3, STRING_FOR_PATCH_SOURCE_VELOCITY, STRING_FOR_PATCH_SOURCE_NOTE, STRING_FOR_PATCH_SOURCE_SIDECHAIN, @@ -78,6 +80,14 @@ enum class String : size_t { STRING_FOR_PARAM_LOCAL_ENV_1_DECAY, STRING_FOR_PARAM_LOCAL_ENV_1_SUSTAIN, STRING_FOR_PARAM_LOCAL_ENV_1_RELEASE, + STRING_FOR_PARAM_LOCAL_ENV_2_ATTACK, + STRING_FOR_PARAM_LOCAL_ENV_2_DECAY, + STRING_FOR_PARAM_LOCAL_ENV_2_SUSTAIN, + STRING_FOR_PARAM_LOCAL_ENV_2_RELEASE, + STRING_FOR_PARAM_LOCAL_ENV_3_ATTACK, + STRING_FOR_PARAM_LOCAL_ENV_3_DECAY, + STRING_FOR_PARAM_LOCAL_ENV_3_SUSTAIN, + STRING_FOR_PARAM_LOCAL_ENV_3_RELEASE, STRING_FOR_PARAM_GLOBAL_LFO_FREQ, STRING_FOR_PARAM_GLOBAL_VOLUME_POST_FX, STRING_FOR_PARAM_GLOBAL_VOLUME_POST_REVERB_SEND, @@ -375,6 +385,8 @@ enum class String : size_t { STRING_FOR_DEV_MENU_G, STRING_FOR_ENVELOPE_1, STRING_FOR_ENVELOPE_2, + STRING_FOR_ENVELOPE_3, + STRING_FOR_ENVELOPE_4, STRING_FOR_VOLUME_LEVEL, STRING_FOR_AMOUNT_LEVEL, STRING_FOR_REPEAT_MODE, diff --git a/src/deluge/gui/menu_item/generate/dmenus/envelopes.py b/src/deluge/gui/menu_item/generate/dmenus/envelopes.py index de144f7e6d..1f5999a5ef 100644 --- a/src/deluge/gui/menu_item/generate/dmenus/envelopes.py +++ b/src/deluge/gui/menu_item/generate/dmenus/envelopes.py @@ -45,5 +45,5 @@ [attack, decay, sustain, release], name=f"STRING_FOR_ENVELOPE_{i+1}", ) - for i in range(2) + for i in range(4) ] diff --git a/src/deluge/gui/menu_item/generate/g_menus.inc b/src/deluge/gui/menu_item/generate/g_menus.inc index 96d95a4770..6f237e34f8 100644 --- a/src/deluge/gui/menu_item/generate/g_menus.inc +++ b/src/deluge/gui/menu_item/generate/g_menus.inc @@ -64,6 +64,8 @@ std::array child5 = { }; submenu::Envelope env0Menu{STRING_FOR_ENVELOPE_1, child5, 0}; submenu::Envelope env1Menu{STRING_FOR_ENVELOPE_2, child5, 1}; +submenu::Envelope env2Menu{STRING_FOR_ENVELOPE_3, child5, 2}; +submenu::Envelope env3Menu{STRING_FOR_ENVELOPE_4, child5, 3}; osc::Type oscTypeMenu{STRING_FOR_TYPE, STRING_FOR_OSC_TYPE_MENU_TITLE}; osc::source::Volume sourceVolumeMenu{STRING_FOR_VOLUME_LEVEL, STRING_FOR_OSC_LEVEL_MENU_TITLE, params::LOCAL_OSC_A_VOLUME}; osc::source::WaveIndex sourceWaveIndexMenu{STRING_FOR_WAVE_INDEX, STRING_FOR_OSC_WAVE_IND_MENU_TITLE, params::LOCAL_OSC_A_WAVE_INDEX}; diff --git a/src/deluge/gui/menu_item/source_selection.cpp b/src/deluge/gui/menu_item/source_selection.cpp index 11c92e2860..e7e1d2bbea 100644 --- a/src/deluge/gui/menu_item/source_selection.cpp +++ b/src/deluge/gui/menu_item/source_selection.cpp @@ -27,9 +27,10 @@ namespace deluge::gui::menu_item { const PatchSource sourceMenuContents[] = { - PatchSource::ENVELOPE_0, PatchSource::ENVELOPE_1, PatchSource::LFO_GLOBAL, PatchSource::LFO_LOCAL, - PatchSource::VELOCITY, PatchSource::NOTE, PatchSource::SIDECHAIN, PatchSource::RANDOM, - PatchSource::X, PatchSource::Y, PatchSource::AFTERTOUCH, + PatchSource::ENVELOPE_0, PatchSource::ENVELOPE_1, PatchSource::ENVELOPE_2, PatchSource::ENVELOPE_3, + PatchSource::LFO_GLOBAL, PatchSource::LFO_LOCAL, PatchSource::VELOCITY, PatchSource::NOTE, + PatchSource::SIDECHAIN, PatchSource::RANDOM, PatchSource::X, PatchSource::Y, + PatchSource::AFTERTOUCH, }; uint8_t SourceSelection::shouldDrawDotOnValue() { @@ -96,6 +97,14 @@ void SourceSelection::drawValue() { text = STRING_FOR_PATCH_SOURCE_ENVELOPE_1; break; + case PatchSource::ENVELOPE_2: + text = STRING_FOR_PATCH_SOURCE_ENVELOPE_2; + break; + + case PatchSource::ENVELOPE_3: + text = STRING_FOR_PATCH_SOURCE_ENVELOPE_3; + break; + case PatchSource::SIDECHAIN: text = STRING_FOR_PATCH_SOURCE_SIDECHAIN; break; diff --git a/src/deluge/gui/ui/menus.cpp b/src/deluge/gui/ui/menus.cpp index 1f5eed26b2..5077efae2a 100644 --- a/src/deluge/gui/ui/menus.cpp +++ b/src/deluge/gui/ui/menus.cpp @@ -1279,6 +1279,8 @@ menu_item::Submenu soundEditorRootMenu{ &modulator1Menu, &env0Menu, &env1Menu, + &env2Menu, + &env3Menu, &lfo1Menu, &lfo2Menu, &voiceMenu, @@ -1289,6 +1291,16 @@ menu_item::Submenu soundEditorRootMenu{ }, }; +LayeredShortcut envMenuA{{&env0Menu, &env2Menu}}; +LayeredShortcut envMenuB{{&env1Menu, &env3Menu}}; + +// These look funny since they contain the same item twice, but they work through the virtue of +// patchIndex, the same way vanilla envelope menus work. +LayeredShortcut envReleaseMenus{{&envReleaseMenu, &envReleaseMenu}}; +LayeredShortcut envSustainMenus{{&envSustainMenu, &envSustainMenu}}; +LayeredShortcut envDecayMenus{{&envDecayMenu, &envDecayMenu}}; +LayeredShortcut envAttackMenus{{&envAttackMenu, &envAttackMenu}}; + menu_item::note::IteranceDivisor noteCustomIteranceDivisor{STRING_FOR_ITERANCE_DIVISOR}; menu_item::note::IteranceStepToggle noteCustomIteranceStep1{STRING_FOR_ITERATION_STEP_1, STRING_FOR_ITERATION_STEP_1, 0}; @@ -1555,8 +1567,8 @@ MenuItem* paramShortcutsForSounds[][kDisplayHeight] = { {&modulatorVolume, &modulatorTransposeMenu, comingSoonMenu, comingSoonMenu, &modulatorPhaseMenu, &modulatorFeedbackMenu, &modulatorDestMenu, nullptr }, {&volumeMenu, &masterTransposeMenu, &vibratoMenu, &panMenu, &synthModeMenu, &srrMenu, &bitcrushMenu, &clippingMenu }, {&portaMenu, &polyphonyMenu, &priorityMenu, &unisonDetuneMenu, &numUnisonToStereoSpreadMenu, nullptr, nullptr, &foldMenu }, - {&envReleaseMenu, &envSustainMenu, &envDecayMenu, &envAttackMenu, &lpfMorphMenu, &lpfModeMenu, &lpfResMenu, &lpfFreqMenu }, - {&envReleaseMenu, &envSustainMenu, &envDecayMenu, &envAttackMenu, &hpfMorphMenu, &hpfModeMenu, &hpfResMenu, &hpfFreqMenu }, + {&envReleaseMenus, &envSustainMenus, &envDecayMenus, &envAttackMenus, &lpfMorphMenu, &lpfModeMenu, &lpfResMenu, &lpfFreqMenu }, + {&envReleaseMenus, &envSustainMenus, &envDecayMenus, &envAttackMenus, &hpfMorphMenu, &hpfModeMenu, &hpfResMenu, &hpfFreqMenu }, {&sidechainReleaseMenu, &sidechainSyncMenu, &sidechainVolumeShortcutMenu, &sidechainAttackMenu, &sidechainShapeMenu, &sidechainSendMenu, &bassMenu, &bassFreqMenu }, {&arpRateMenu, &arpSyncMenu, &arpGateMenu, &arpOctavesMenu, &arpPresetModeMenu, &nameEditMenu, &trebleMenu, &trebleFreqMenu }, {&lfo1RateMenu, &lfo1SyncMenu, &lfo1TypeMenu, &modFXTypeMenu, &modFXOffsetMenu, &modFXFeedbackMenu, &modFXDepthMenu, &modFXRateMenu }, @@ -1564,7 +1576,7 @@ MenuItem* paramShortcutsForSounds[][kDisplayHeight] = { {&delayRateMenu, &delaySyncMenu, &delayAnalogMenu, &delayFeedbackMenu, &delayPingPongMenu, nullptr, nullptr, nullptr }, {nullptr, &arpSpreadVelocityMenu, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }, }; -Submenu* parentsForSoundShortcuts[][kDisplayHeight] = { +MenuItem* parentsForSoundShortcuts[][kDisplayHeight] = { {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, @@ -1573,8 +1585,8 @@ Submenu* parentsForSoundShortcuts[][kDisplayHeight] = { {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, - {&env0Menu, &env0Menu, &env0Menu, &env0Menu, &lpfMenu, &lpfMenu, &lpfMenu, &lpfMenu, }, - {&env1Menu, &env1Menu, &env1Menu, &env1Menu, &hpfMenu, &hpfMenu, &hpfMenu, &hpfMenu, }, + {&envMenuA, &envMenuA, &envMenuA, &envMenuA, &lpfMenu, &lpfMenu, &lpfMenu, &lpfMenu, }, + {&envMenuB, &envMenuB, &envMenuB, &envMenuB, &hpfMenu, &hpfMenu, &hpfMenu, &hpfMenu, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, @@ -1601,7 +1613,7 @@ MenuItem* paramShortcutsForAudioClips[][kDisplayHeight] = { {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, }; -Submenu* parentsForAudioShortcuts[][kDisplayHeight] = { +MenuItem* parentsForAudioShortcuts[][kDisplayHeight] = { {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, @@ -1638,7 +1650,7 @@ MenuItem* paramShortcutsForSongView[][kDisplayHeight] = { {&globalDelayRateMenu, &delaySyncMenu, &delayAnalogMenu, &globalDelayFeedbackMenu, &delayPingPongMenu, nullptr, nullptr, nullptr }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }, }; -Submenu* parentsForSongShortcuts[][kDisplayHeight] = { +MenuItem* parentsForSongShortcuts[][kDisplayHeight] = { {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, @@ -1675,7 +1687,7 @@ MenuItem* paramShortcutsForKitGlobalFX[][kDisplayHeight] = { {&globalDelayRateMenu, &delaySyncMenu, &delayAnalogMenu, &globalDelayFeedbackMenu, &delayPingPongMenu, nullptr, nullptr, nullptr }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr }, }; -Submenu* parentsForKitGlobalFXShortcuts[][kDisplayHeight] = { +MenuItem* parentsForKitGlobalFXShortcuts[][kDisplayHeight] = { {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, {nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, }, diff --git a/src/deluge/gui/ui/menus.h b/src/deluge/gui/ui/menus.h index 7e63faab2c..9ab7a6ca30 100644 --- a/src/deluge/gui/ui/menus.h +++ b/src/deluge/gui/ui/menus.h @@ -89,10 +89,10 @@ extern MenuItem* paramShortcutsForAudioClips[kDisplayWidth][kDisplayHeight]; extern MenuItem* paramShortcutsForSongView[kDisplayWidth][kDisplayHeight]; extern MenuItem* paramShortcutsForKitGlobalFX[kDisplayWidth][kDisplayHeight]; -extern deluge::gui::menu_item::Submenu* parentsForSoundShortcuts[kDisplayWidth][kDisplayHeight]; -extern deluge::gui::menu_item::Submenu* parentsForAudioShortcuts[kDisplayWidth][kDisplayHeight]; -extern deluge::gui::menu_item::Submenu* parentsForSongShortcuts[kDisplayWidth][kDisplayHeight]; -extern deluge::gui::menu_item::Submenu* parentsForKitGlobalFXShortcuts[kDisplayWidth][kDisplayHeight]; +extern MenuItem* parentsForSoundShortcuts[kDisplayWidth][kDisplayHeight]; +extern MenuItem* parentsForAudioShortcuts[kDisplayWidth][kDisplayHeight]; +extern MenuItem* parentsForSongShortcuts[kDisplayWidth][kDisplayHeight]; +extern MenuItem* parentsForKitGlobalFXShortcuts[kDisplayWidth][kDisplayHeight]; void setOscillatorNumberForTitles(int32_t); void setModulatorNumberForTitles(int32_t); diff --git a/src/deluge/gui/ui/sound_editor.cpp b/src/deluge/gui/ui/sound_editor.cpp index f1fa072eca..344aceaf69 100644 --- a/src/deluge/gui/ui/sound_editor.cpp +++ b/src/deluge/gui/ui/sound_editor.cpp @@ -1128,14 +1128,15 @@ ActionResult SoundEditor::potentialShortcutPadAction(int32_t x, int32_t y, bool // This works on 7-seg as well. int32_t layerNumber = 0; MenuItem* newItem = item->actual(); - MenuItem* oldItem = getCurrentMenuItem()->actual(); - if (oldItem == newItem) { + MenuItem* oldItem = getCurrentMenuItem(); + if (oldItem->actual() == newItem) { if (parent == nullptr) { // No parent, same item == same shortcut twice. layerNumber = item->nextLayer(); } else if (parent == oldItem) { // Same parent, same item == same shortcut twice. + // NB: not oldItem->actual(), but the container! layerNumber = parent->nextLayer(); } } diff --git a/src/deluge/modulation/params/param.cpp b/src/deluge/modulation/params/param.cpp index 5184d6e4d3..78ad2e60b9 100644 --- a/src/deluge/modulation/params/param.cpp +++ b/src/deluge/modulation/params/param.cpp @@ -20,6 +20,7 @@ #include "gui/l10n/l10n.h" #include "gui/l10n/strings.h" #include "model/settings/runtime_feature_settings.h" +#include "util/container/enum_to_string_map.hpp" #include namespace deluge::modulation::params { @@ -131,6 +132,8 @@ char const* getPatchedParamShortName(ParamType type) { [LOCAL_HPF_RESONANCE] = "HPF reso", [LOCAL_ENV_0_SUSTAIN] = "Env1 sus", [LOCAL_ENV_1_SUSTAIN] = "Env2 sus", + [LOCAL_ENV_2_SUSTAIN] = "Env3 sus", + [LOCAL_ENV_3_SUSTAIN] = "Env4 sus", [LOCAL_LPF_MORPH] = "LPF Morph", [LOCAL_HPF_MORPH] = "HPF Morph", [LOCAL_OSC_A_PHASE_WIDTH] = "Osc1 PW", @@ -148,10 +151,16 @@ char const* getPatchedParamShortName(ParamType type) { [LOCAL_LFO_LOCAL_FREQ] = "LFO2 rate", [LOCAL_ENV_0_ATTACK] = "Env1attack", [LOCAL_ENV_1_ATTACK] = "Env2attack", + [LOCAL_ENV_2_ATTACK] = "Env3attack", + [LOCAL_ENV_3_ATTACK] = "Env4attack", [LOCAL_ENV_0_DECAY] = "Env1 decay", [LOCAL_ENV_1_DECAY] = "Env2 decay", + [LOCAL_ENV_2_DECAY] = "Env3 decay", + [LOCAL_ENV_3_DECAY] = "Env4 decay", [LOCAL_ENV_0_RELEASE] = "Env1 rel", [LOCAL_ENV_1_RELEASE] = "Env2 rel", + [LOCAL_ENV_2_RELEASE] = "Env3 rel", + [LOCAL_ENV_3_RELEASE] = "Env4 rel", [GLOBAL_VOLUME_POST_FX] = "POSTFXLVL", [GLOBAL_VOLUME_POST_REVERB_SEND] = "Side level", [GLOBAL_REVERB_AMOUNT] = "Reverb amt", @@ -192,6 +201,8 @@ char const* getPatchedParamDisplayName(int32_t p) { [LOCAL_HPF_RESONANCE] = STRING_FOR_PARAM_LOCAL_HPF_RESONANCE, [LOCAL_ENV_0_SUSTAIN] = STRING_FOR_PARAM_LOCAL_ENV_0_SUSTAIN, [LOCAL_ENV_1_SUSTAIN] = STRING_FOR_PARAM_LOCAL_ENV_1_SUSTAIN, + [LOCAL_ENV_2_SUSTAIN] = STRING_FOR_PARAM_LOCAL_ENV_2_SUSTAIN, + [LOCAL_ENV_3_SUSTAIN] = STRING_FOR_PARAM_LOCAL_ENV_3_SUSTAIN, [LOCAL_LPF_MORPH] = STRING_FOR_PARAM_LOCAL_LPF_MORPH, [LOCAL_HPF_MORPH] = STRING_FOR_PARAM_LOCAL_HPF_MORPH, [LOCAL_OSC_A_PHASE_WIDTH] = STRING_FOR_PARAM_LOCAL_OSC_A_PHASE_WIDTH, @@ -209,10 +220,16 @@ char const* getPatchedParamDisplayName(int32_t p) { [LOCAL_LFO_LOCAL_FREQ] = STRING_FOR_PARAM_LOCAL_LFO_LOCAL_FREQ, [LOCAL_ENV_0_ATTACK] = STRING_FOR_PARAM_LOCAL_ENV_0_ATTACK, [LOCAL_ENV_1_ATTACK] = STRING_FOR_PARAM_LOCAL_ENV_1_ATTACK, + [LOCAL_ENV_2_ATTACK] = STRING_FOR_PARAM_LOCAL_ENV_2_ATTACK, + [LOCAL_ENV_3_ATTACK] = STRING_FOR_PARAM_LOCAL_ENV_3_ATTACK, [LOCAL_ENV_0_DECAY] = STRING_FOR_PARAM_LOCAL_ENV_0_DECAY, [LOCAL_ENV_1_DECAY] = STRING_FOR_PARAM_LOCAL_ENV_1_DECAY, + [LOCAL_ENV_2_DECAY] = STRING_FOR_PARAM_LOCAL_ENV_2_DECAY, + [LOCAL_ENV_3_DECAY] = STRING_FOR_PARAM_LOCAL_ENV_3_DECAY, [LOCAL_ENV_0_RELEASE] = STRING_FOR_PARAM_LOCAL_ENV_0_RELEASE, [LOCAL_ENV_1_RELEASE] = STRING_FOR_PARAM_LOCAL_ENV_1_RELEASE, + [LOCAL_ENV_2_RELEASE] = STRING_FOR_PARAM_LOCAL_ENV_2_RELEASE, + [LOCAL_ENV_3_RELEASE] = STRING_FOR_PARAM_LOCAL_ENV_3_RELEASE, [GLOBAL_VOLUME_POST_FX] = STRING_FOR_PARAM_GLOBAL_VOLUME_POST_FX, [GLOBAL_VOLUME_POST_REVERB_SEND] = STRING_FOR_PARAM_GLOBAL_VOLUME_POST_REVERB_SEND, [GLOBAL_REVERB_AMOUNT] = STRING_FOR_PARAM_GLOBAL_REVERB_AMOUNT, @@ -597,27 +614,39 @@ constexpr char const* paramNameForFileConst(Kind const kind, ParamType const par case LOCAL_ENV_0_ATTACK: return "env1Attack"; - - case LOCAL_ENV_0_DECAY: - return "env1Decay"; - - case LOCAL_ENV_0_SUSTAIN: - return "env1Sustain"; - - case LOCAL_ENV_0_RELEASE: - return "env1Release"; - case LOCAL_ENV_1_ATTACK: return "env2Attack"; + case LOCAL_ENV_2_ATTACK: + return "env3Attack"; + case LOCAL_ENV_3_ATTACK: + return "env4Attack"; + case LOCAL_ENV_0_DECAY: + return "env1Decay"; case LOCAL_ENV_1_DECAY: return "env2Decay"; + case LOCAL_ENV_2_DECAY: + return "env3Decay"; + case LOCAL_ENV_3_DECAY: + return "env4Decay"; + case LOCAL_ENV_0_SUSTAIN: + return "env1Sustain"; case LOCAL_ENV_1_SUSTAIN: return "env2Sustain"; + case LOCAL_ENV_2_SUSTAIN: + return "env3Sustain"; + case LOCAL_ENV_3_SUSTAIN: + return "env4Sustain"; + case LOCAL_ENV_0_RELEASE: + return "env1Release"; case LOCAL_ENV_1_RELEASE: return "env2Release"; + case LOCAL_ENV_2_RELEASE: + return "env3Release"; + case LOCAL_ENV_3_RELEASE: + return "env4Release"; case LOCAL_MODULATOR_0_FEEDBACK: return "modulator1Feedback"; diff --git a/src/deluge/modulation/params/param.h b/src/deluge/modulation/params/param.h index a6cd6bdfa1..082fceb6fc 100644 --- a/src/deluge/modulation/params/param.h +++ b/src/deluge/modulation/params/param.h @@ -83,6 +83,8 @@ enum Local : ParamType { LOCAL_HPF_RESONANCE, LOCAL_ENV_0_SUSTAIN, LOCAL_ENV_1_SUSTAIN, + LOCAL_ENV_2_SUSTAIN, + LOCAL_ENV_3_SUSTAIN, LOCAL_LPF_MORPH, LOCAL_HPF_MORPH, @@ -106,10 +108,16 @@ enum Local : ParamType { LOCAL_LFO_LOCAL_FREQ, LOCAL_ENV_0_ATTACK, LOCAL_ENV_1_ATTACK, + LOCAL_ENV_2_ATTACK, + LOCAL_ENV_3_ATTACK, LOCAL_ENV_0_DECAY, LOCAL_ENV_1_DECAY, + LOCAL_ENV_2_DECAY, + LOCAL_ENV_3_DECAY, LOCAL_ENV_0_RELEASE, LOCAL_ENV_1_RELEASE, + LOCAL_ENV_2_RELEASE, + LOCAL_ENV_3_RELEASE, /// Special value used to chain in to the Global params. LOCAL_LAST, diff --git a/src/deluge/processing/sound/sound.cpp b/src/deluge/processing/sound/sound.cpp index d4ebf127a4..b1bd878c15 100644 --- a/src/deluge/processing/sound/sound.cpp +++ b/src/deluge/processing/sound/sound.cpp @@ -1341,11 +1341,11 @@ PatchCableAcceptance Sound::maySourcePatchToParam(PatchSource s, uint8_t p, Para return PatchCableAcceptance::DISALLOWED; case params::LOCAL_VOLUME: - return (s != PatchSource::ENVELOPE_0 - // No envelopes allowed to be patched to volume - this is hardcoded elsewhere - && s != PatchSource::ENVELOPE_1 - // Don't let the sidechain patch to local volume - it's supposed to go to global volume - && s != PatchSource::SIDECHAIN) + return ( + // No envelopes allowed to be patched to volume - this is hardcoded elsewhere + (s < PatchSource::ENVELOPE_0 || PatchSource::ENVELOPE_3 < s) + // Don't let the sidechain patch to local volume - it's supposed to go to global volume + && s != PatchSource::SIDECHAIN) ? PatchCableAcceptance::ALLOWED : PatchCableAcceptance::DISALLOWED; diff --git a/src/deluge/util/functions.cpp b/src/deluge/util/functions.cpp index f463678dae..a5e396a40e 100644 --- a/src/deluge/util/functions.cpp +++ b/src/deluge/util/functions.cpp @@ -56,6 +56,8 @@ int32_t getParamRange(int32_t p) { switch (p) { case params::LOCAL_ENV_0_ATTACK: case params::LOCAL_ENV_1_ATTACK: + case params::LOCAL_ENV_2_ATTACK: + case params::LOCAL_ENV_3_ATTACK: return 536870912 * 1.5; case params::GLOBAL_DELAY_RATE: @@ -118,18 +120,26 @@ int32_t getParamNeutralValue(int32_t p) { case params::LOCAL_ENV_0_ATTACK: case params::LOCAL_ENV_1_ATTACK: + case params::LOCAL_ENV_2_ATTACK: + case params::LOCAL_ENV_3_ATTACK: return 4096; // attackRateTable[userValue]; case params::LOCAL_ENV_0_RELEASE: case params::LOCAL_ENV_1_RELEASE: + case params::LOCAL_ENV_2_RELEASE: + case params::LOCAL_ENV_3_RELEASE: return 140 << 9; // releaseRateTable[userValue]; case params::LOCAL_ENV_0_DECAY: case params::LOCAL_ENV_1_DECAY: + case params::LOCAL_ENV_2_DECAY: + case params::LOCAL_ENV_3_DECAY: return 70 << 9; // releaseRateTable[userValue] >> 1; case params::LOCAL_ENV_0_SUSTAIN: case params::LOCAL_ENV_1_SUSTAIN: + case params::LOCAL_ENV_2_SUSTAIN: + case params::LOCAL_ENV_3_SUSTAIN: case params::GLOBAL_DELAY_FEEDBACK: return 1073741824; // 536870912; @@ -234,10 +244,12 @@ int32_t getFinalParameterValueExp(int32_t paramNeutralValue, int32_t patchedValu int32_t getFinalParameterValueExpWithDumbEnvelopeHack(int32_t paramNeutralValue, int32_t patchedValue, int32_t p) { // TODO: this is horribly hard-coded, but works for now - if (p >= params::LOCAL_ENV_0_DECAY && p <= params::LOCAL_ENV_1_RELEASE) { + if (params::LOCAL_ENV_0_DECAY <= p && p <= params::LOCAL_ENV_3_RELEASE) { + D_PRINTLN(" release rate hack %d", p); return multiply_32x32_rshift32(paramNeutralValue, lookupReleaseRate(patchedValue)); } - if (p == params::LOCAL_ENV_0_ATTACK || p == params::LOCAL_ENV_1_ATTACK) { + if (params::LOCAL_ENV_0_ATTACK <= p && p <= params::LOCAL_ENV_3_ATTACK) { + D_PRINTLN(" sign flip %d", p); patchedValue = -patchedValue; } @@ -323,6 +335,12 @@ char const* getSourceDisplayNameForOLED(PatchSource s) { case PatchSource::ENVELOPE_1: return l10n::get(STRING_FOR_PATCH_SOURCE_ENVELOPE_1); + case PatchSource::ENVELOPE_2: + return l10n::get(STRING_FOR_PATCH_SOURCE_ENVELOPE_2); + + case PatchSource::ENVELOPE_3: + return l10n::get(STRING_FOR_PATCH_SOURCE_ENVELOPE_3); + case PatchSource::VELOCITY: return l10n::get(STRING_FOR_PATCH_SOURCE_VELOCITY); @@ -374,6 +392,12 @@ char const* sourceToStringShort(PatchSource source) { case PatchSource::ENVELOPE_1: return "env2"; + case PatchSource::ENVELOPE_2: + return "env3"; + + case PatchSource::ENVELOPE_3: + return "env4"; + case PatchSource::VELOCITY: return "velo";