From d0b03d39e849e012ea0b3ee4238d71b00f16d55b Mon Sep 17 00:00:00 2001 From: EvilDragon Date: Sat, 10 Sep 2022 18:01:23 +0200 Subject: [PATCH] Add option to use MIDI channels 2 and 3 to play scenes individually (#6606) Closes #4657 --- src/common/SurgeSynthesizer.cpp | 37 ++++++++++++++++++++++------- src/common/UserDefaults.cpp | 3 +++ src/common/UserDefaults.h | 1 + src/surge-xt/gui/SurgeGUIEditor.cpp | 11 +++++++++ 4 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/common/SurgeSynthesizer.cpp b/src/common/SurgeSynthesizer.cpp index 3187e426a00..e2aac1525ba 100644 --- a/src/common/SurgeSynthesizer.cpp +++ b/src/common/SurgeSynthesizer.cpp @@ -298,42 +298,53 @@ SurgeSynthesizer::~SurgeSynthesizer() } } +// A voice is routed to a particular scene if channelmask & n. +// So, "1" means scene A, "2" means scene B and "3" (= 2 | 1) means both. int SurgeSynthesizer::calculateChannelMask(int channel, int key) { - /* - ** Just because I always forget - ** - ** A voice is routed to scene n if channelmask & n. So "1" means scene A, "2" means scene B and - *"3" (= 2 | 1 ) = both. - */ + bool useMIDICh2Ch3 = Surge::Storage::getUserDefaultValue( + &storage, Surge::Storage::UseCh2Ch3ToPlayScenesIndividually, true); + int channelmask = channel; - if ((channel == 0) || (channel > 2) || mpeEnabled || - storage.getPatch().scenemode.val.i == sm_chsplit || storage.mapChannelToOctave) + if (((channel == 0 || channel > 2) && useMIDICh2Ch3) || + (channel >= 0 && channel < 16 && !useMIDICh2Ch3) || mpeEnabled || + storage.mapChannelToOctave || storage.getPatch().scenemode.val.i == sm_chsplit) { switch (storage.getPatch().scenemode.val.i) { case sm_single: - // case sm_morph: if (storage.getPatch().scene_active.val.i == 1) + { channelmask = 2; + } else + { channelmask = 1; + } break; case sm_dual: channelmask = 3; break; case sm_split: if (key < storage.getPatch().splitpoint.val.i) + { channelmask = 1; + } else + { channelmask = 2; + } break; case sm_chsplit: if (channel < ((int)(storage.getPatch().splitpoint.val.i / 8) + 1)) + { channelmask = 1; + } else + { channelmask = 2; + } break; } @@ -341,9 +352,13 @@ int SurgeSynthesizer::calculateChannelMask(int channel, int key) else if (storage.getPatch().scenemode.val.i == sm_single) { if (storage.getPatch().scene_active.val.i == 1) + { channelmask = 2; + } else + { channelmask = 1; + } } return channelmask; @@ -353,7 +368,9 @@ void SurgeSynthesizer::playNote(char channel, char key, char velocity, char detu int32_t host_noteid) { if (halt_engine) + { return; + } if (storage.oddsound_mts_client && storage.oddsound_mts_active) { @@ -402,6 +419,8 @@ void SurgeSynthesizer::playNote(char channel, char key, char velocity, char detu int channelmask = calculateChannelMask(channel, key); + printf("channelmask %d\n", channelmask); + // TODO: FIX SCENE ASSUMPTION if (channelmask & 1) { diff --git a/src/common/UserDefaults.cpp b/src/common/UserDefaults.cpp index 9a0f9de4fbe..75dc1229260 100644 --- a/src/common/UserDefaults.cpp +++ b/src/common/UserDefaults.cpp @@ -36,6 +36,9 @@ std::string defaultKeyToString(DefaultKey k) case MPEPitchBendRange: r = "mpePitchBendRange"; break; + case UseCh2Ch3ToPlayScenesIndividually: + r = "useCh2Ch3ToPlayScenesIndividually"; + break; case RestoreMSEGSnapFromPatch: r = "restoreMSEGSnapFromPatch"; break; diff --git a/src/common/UserDefaults.h b/src/common/UserDefaults.h index 3b33c2190ce..a7b1e1320f2 100644 --- a/src/common/UserDefaults.h +++ b/src/common/UserDefaults.h @@ -70,6 +70,7 @@ enum DefaultKey MPEPitchBendRange, PitchSmoothingMode, + UseCh2Ch3ToPlayScenesIndividually, SmoothingMode, MonoPedalMode, diff --git a/src/surge-xt/gui/SurgeGUIEditor.cpp b/src/surge-xt/gui/SurgeGUIEditor.cpp index b94dff89009..ec8eea53d59 100644 --- a/src/surge-xt/gui/SurgeGUIEditor.cpp +++ b/src/surge-xt/gui/SurgeGUIEditor.cpp @@ -4374,6 +4374,17 @@ juce::PopupMenu SurgeGUIEditor::makeMidiMenu(const juce::Point &where) auto mmom = makeMonoModeOptionsMenu(where, true); midiSubMenu.addSubMenu(Surge::GUI::toOSCase("Sustain Pedal In Mono Mode"), mmom); + bool useMIDICh2Ch3 = Surge::Storage::getUserDefaultValue( + &(this->synth->storage), Surge::Storage::UseCh2Ch3ToPlayScenesIndividually, true); + + midiSubMenu.addItem( + Surge::GUI::toOSCase("Use MIDI Channels 2 and 3 to Play Scenes Individually"), true, + useMIDICh2Ch3, [this, useMIDICh2Ch3]() { + Surge::Storage::updateUserDefaultValue( + &(this->synth->storage), Surge::Storage::UseCh2Ch3ToPlayScenesIndividually, + !useMIDICh2Ch3); + }); + midiSubMenu.addSeparator(); midiSubMenu.addItem(Surge::GUI::toOSCase("Save MIDI Mapping As..."), [this, where]() {