Skip to content

Commit 4d50d27

Browse files
committed
Route MIDI Poly/Channel Pressure to aftertouch, not pitchBend
The 0xA0 (Poly Key Pressure) and 0xD0 (Channel Pressure) handlers in handleMidi() were both calling setFromInt on ParameterID::pitchBend, even though the inline comments said 'Aftertouch'. Looks like a copy-paste of the 0xE0 (pitch bend) case that never got its parameter ID corrected. Effect today: pressure values were silently misrouted into the pitchBend parameter. The mismatch was nearly inaudible because the pitchBend scale is [-8192, 8191] (14-bit) but data[2] is 0-127, so the misrouted values produced only a tiny upward pitch drift. Two coordinated fixes: 1. Route both 0xA0 and 0xD0 to ParameterID::aftertouch. Scales are already aligned: Scales::aftertouch is (0.0, 127.0) — exactly the MIDI value range. 2. Relax the early-return size guard from \`!= 3\` to \`< 2\`. Channel Pressure is a 2-byte message (status + value, no data[2]). The old strict-3 guard silently dropped every 0xD0 event before it could reach the switch, so even after the routing fix, channel pressure would still do nothing without this. The new floor lets each case rely on its own status-byte size convention; only 0xD0 actually needs the 2-byte allowance, the other cases still inspect data[2] safely because all their status bytes mean 3-byte messages. Poly Key Pressure (0xA0) on a monophonic synth applies globally (there's only one note); the data[1] note-number field is ignored. Found while looking into MPE support — pressure routing is one of the things any MPE mapping needs to get right, so this had to be correct first.
1 parent 13e2275 commit 4d50d27

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

plugin/dpf/DigiDrie/plugin.cpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,11 @@ class DigiDrie : public Plugin {
153153
uint32_t &midiIndex,
154154
uint32_t midiEventCount)
155155
{
156-
if (ev.size != 3) return;
156+
// Channel Pressure is a 2-byte message (status + value); the
157+
// earlier `!= 3` guard silently dropped every 0xD0 event. Use the
158+
// minimum-2 floor and let each case rely on its own status-byte
159+
// convention for how many bytes it actually inspects.
160+
if (ev.size < 2) return;
157161

158162
switch (ev.data[0] & 0xf0) {
159163
// Note off.
@@ -178,19 +182,20 @@ class DigiDrie : public Plugin {
178182
}
179183
} break;
180184

181-
// Polyphonic Key Pressure (Aftertouch).
185+
// Polyphonic Key Pressure. data[1]: note, data[2]: pressure.
186+
// Applied as global aftertouch since the synth is monophonic.
182187
case 0xA0: {
183-
dsp->param.value[ParameterID::pitchBend]->setFromInt(ev.data[2]);
188+
dsp->param.value[ParameterID::aftertouch]->setFromInt(ev.data[2]);
184189
} break;
185190

186191
// Control Change.
187192
case 0xB0: {
188193
handleControlChange(ev, midiEvents, midiIndex, midiEventCount);
189194
} break;
190195

191-
// Channel Pressure (Aftertouch).
196+
// Channel Pressure. data[1]: pressure (no data[2]; 2-byte msg).
192197
case 0xD0: {
193-
dsp->param.value[ParameterID::pitchBend]->setFromInt(ev.data[1]);
198+
dsp->param.value[ParameterID::aftertouch]->setFromInt(ev.data[1]);
194199
} break;
195200

196201
// Pitch bend. Center is 8192 (0x2000).

0 commit comments

Comments
 (0)