From 69387304e0ba406748c1ff5611398c9ccbd65b6b Mon Sep 17 00:00:00 2001 From: Paul Date: Sat, 2 Nov 2019 16:43:19 -0400 Subject: [PATCH] Handle Sustain Pedal correctly in MPE mode (#1269) In note-per-channel mode notes would ask the wrong channel for their sustain pedal status; so devices which put that controller on channel 0 (since it is monophonic) would result in no sustain in channel-per-note modes. Fix that by making the holdBuffer the appropriate data structure etc. Closes #1268 --- src/common/SurgeSynthesizer.cpp | 44 ++++++++++++++------------------- src/common/SurgeSynthesizer.h | 3 ++- 2 files changed, 20 insertions(+), 27 deletions(-) diff --git a/src/common/SurgeSynthesizer.cpp b/src/common/SurgeSynthesizer.cpp index 3d12b2068cb..aaa30927675 100644 --- a/src/common/SurgeSynthesizer.cpp +++ b/src/common/SurgeSynthesizer.cpp @@ -536,21 +536,17 @@ void SurgeSynthesizer::releaseNote(char channel, char key, char velocity) } } - // if(channelmask&1) - { - if (!channelState[channel].hold) - releaseNotePostHoldCheck(0, channel, key, velocity); - else - holdbuffer[0].push_back(key); // hold pedal is down, add to bufffer - } - // if(channelmask&2) + bool noHold = ! channelState[channel].hold; + if( mpeEnabled ) + noHold = noHold && ! channelState[0].hold; + + for( int s=0; s<2; ++s ) { - if (!channelState[channel].hold) - releaseNotePostHoldCheck(1, channel, key, velocity); + if (noHold) + releaseNotePostHoldCheck(s, channel, key, velocity); else - holdbuffer[1].push_back(key); // hold pedal is down, add to bufffer + holdbuffer[s].push_back(std::make_pair(channel,key)); // hold pedal is down, add to bufffer } - } void SurgeSynthesizer::releaseNotePostHoldCheck(int scene, char channel, char key, char velocity) @@ -1064,25 +1060,21 @@ void SurgeSynthesizer::channelController(char channel, int cc, int value) void SurgeSynthesizer::purgeHoldbuffer(int scene) { int z; - list::iterator iter = holdbuffer[scene].begin(); - while (1) + std::list> retainBuffer; + for( auto hp : holdbuffer[scene] ) { - if (iter == holdbuffer[scene].end()) - break; - z = *iter; - if (/*voice_state[z].active && */ !channelState[0].hold) + auto channel = hp.first; + auto key = hp.second; + if (!channelState[0].hold && ! channelState[channel].hold ) { - // voices[z]->release(127); - releaseNotePostHoldCheck(scene, 0, z, 127); - list::iterator del = iter; - iter++; - holdbuffer[scene].erase(del); + releaseNotePostHoldCheck(scene, channel, key, 127); } else - iter++; + { + retainBuffer.push_back(hp); + } } - - // note: Must remove entries when notes kill themselves as well + holdbuffer[scene] = retainBuffer; } void SurgeSynthesizer::allNotesOff() diff --git a/src/common/SurgeSynthesizer.h b/src/common/SurgeSynthesizer.h index 86854489e74..a04b4415031 100644 --- a/src/common/SurgeSynthesizer.h +++ b/src/common/SurgeSynthesizer.h @@ -10,6 +10,7 @@ struct QuadFilterChainState; #include +#include #include #if TARGET_AUDIOUNIT @@ -217,7 +218,7 @@ class alignas(16) SurgeSynthesizer // hold pedal stuff - std::list holdbuffer[2]; + std::list> holdbuffer[2]; void purgeHoldbuffer(int scene); quadr_osc sinus; int demo_counter = 0;