Skip to content

Commit

Permalink
Handle Sustain Pedal correctly in MPE mode (#1269)
Browse files Browse the repository at this point in the history
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
  • Loading branch information
baconpaul authored Nov 2, 2019
1 parent 85010dd commit 6938730
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 27 deletions.
44 changes: 18 additions & 26 deletions src/common/SurgeSynthesizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -1064,25 +1060,21 @@ void SurgeSynthesizer::channelController(char channel, int cc, int value)
void SurgeSynthesizer::purgeHoldbuffer(int scene)
{
int z;
list<int>::iterator iter = holdbuffer[scene].begin();
while (1)
std::list<std::pair<int,int>> 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<int>::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()
Expand Down
3 changes: 2 additions & 1 deletion src/common/SurgeSynthesizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
struct QuadFilterChainState;

#include <list>
#include <utility>
#include <atomic>

#if TARGET_AUDIOUNIT
Expand Down Expand Up @@ -217,7 +218,7 @@ class alignas(16) SurgeSynthesizer

// hold pedal stuff

std::list<int> holdbuffer[2];
std::list<std::pair<int,int>> holdbuffer[2];
void purgeHoldbuffer(int scene);
quadr_osc sinus;
int demo_counter = 0;
Expand Down

0 comments on commit 6938730

Please sign in to comment.