From b4096fa6cbac37df3d391c25b43cecfa602e2a8b Mon Sep 17 00:00:00 2001 From: jrd Date: Sat, 25 Jul 2026 02:35:56 +0000 Subject: [PATCH 1/2] Fix MIDI pickup crossing detection never firing Pickup mode has a second acceptance path, next to the tolerance test, for the case where a fast fader move makes consecutive MIDI values skip over the software value. Two separate defects meant it never ran. While waiting for pickup, midiPickupTryApply returned early without recording the value, so the history deque stayed empty and the size() >= 2 guard in midiPickupShouldApply was never satisfied. And prevMidi read back(), which is the value just appended, so the bracket test reduced to midiValue == currentValue, already covered by the tolerance test above it. Either defect alone disables the path; both are fixed here. Co-Authored-By: Claude Opus 5 --- src/audiomixerboard.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/audiomixerboard.cpp b/src/audiomixerboard.cpp index bedd53526f..d9c7fa146b 100644 --- a/src/audiomixerboard.cpp +++ b/src/audiomixerboard.cpp @@ -95,7 +95,7 @@ static bool midiPickupShouldApply ( int midiValue, int currentValue, int toleran // Handles the case where rapid movement causes MIDI values to "skip over" the software value if ( recentMidiValues.size() >= 2 ) { - int prevMidi = recentMidiValues.back(); + int prevMidi = recentMidiValues[recentMidiValues.size() - 2]; // Check if current and previous MIDI values bracket the software value if ( ( prevMidi <= currentValue && midiValue >= currentValue ) || ( prevMidi >= currentValue && midiValue <= currentValue ) ) return true; @@ -117,7 +117,11 @@ static bool midiPickupTryApply ( int midiValue, int currentValue, int tolerance, tempPickup.push_back ( midiValue ); if ( !midiPickupShouldApply ( midiValue, currentValue, tolerance, tempPickup ) ) + { + // keep this value: the next message needs it to detect a crossing + pickupBuffer = tempPickup; return true; // Still waiting for pickup + } // Picked up. Stop waiting waitingForPickup = false; From 938faf084286a4d55918f911ac8bbfa171c2789d Mon Sep 17 00:00:00 2001 From: jrd Date: Sat, 12 Sep 2026 16:35:24 +0000 Subject: [PATCH 2/2] Name the caller's deque in the pickup comment From review on #3835: pickupBuffer is this function's parameter name, so a reader looking for where it is defined finds nothing but the signature. The objects behind it are the per-channel MidiPickupState::recentFader and ::recentPan deques, bound at the two call sites in SetFaderLevel and SetPanValue. Comment only; no behaviour change. CHANGELOG: SKIP Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01MEXBpjaa8oA5PPgQcZg5Sq --- src/audiomixerboard.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/audiomixerboard.cpp b/src/audiomixerboard.cpp index d9c7fa146b..6717c01d88 100644 --- a/src/audiomixerboard.cpp +++ b/src/audiomixerboard.cpp @@ -118,7 +118,8 @@ static bool midiPickupTryApply ( int midiValue, int currentValue, int tolerance, if ( !midiPickupShouldApply ( midiValue, currentValue, tolerance, tempPickup ) ) { - // keep this value: the next message needs it to detect a crossing + // still waiting: keep this value in the channel's recentFader/recentPan + // history so the next message can detect a crossing pickupBuffer = tempPickup; return true; // Still waiting for pickup }