Skip to content

Track detection refactor#8

Merged
sarossilli merged 2 commits intomainfrom
sr/track_detection_refactor
Feb 26, 2026
Merged

Track detection refactor#8
sarossilli merged 2 commits intomainfrom
sr/track_detection_refactor

Conversation

@sarossilli
Copy link
Owner

@sarossilli sarossilli commented Feb 26, 2026

Note

Medium Risk
Substantial refactor of core MIDI parsing and playback coordination (new part normalization, scoring, and planned track assignment), which could change timing/selection behavior and introduce playback regressions across varied MIDI files.

Overview
Refactors MIDI handling from track-based, runtime re-ranking to part-based normalization and precomputed planning: MIDI is normalized into (channel, program) Parts (handling program changes), scored to pick primary/secondary candidates, converted into rumble tracks, and assigned via a skyline-based PlaybackPlan rather than the removed TrackMergeController/ranking thread.

Playback now supports runtime keyboard controls (S swap L/R, 1/2 cycle candidates, Q quit) via crossterm, and updates scheduling/HID output (scheduled-time sleeps, same-tick command coalescing, write throttling).

Adds developer tooling: a Rust devcontainer with Bluetooth/DBus dependencies, a scripts/pair-joycons.sh helper for Bluetooth pairing, and .gitattributes enforcing LF for *.sh; also adds the crossterm dependency and expands the public prelude exports.

Written by Cursor Bugbot for commit 252dddd. This will update automatically on new commits. Configure here.

@sarossilli sarossilli force-pushed the sr/track_detection_refactor branch from 94150e6 to 0b9abba Compare February 26, 2026 15:58
@sarossilli sarossilli force-pushed the sr/track_detection_refactor branch from 0b9abba to 252dddd Compare February 26, 2026 16:00
@sarossilli sarossilli merged commit 2fa3fe3 into main Feb 26, 2026
11 checks passed
@sarossilli sarossilli deleted the sr/track_detection_refactor branch February 26, 2026 16:04
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.

events.push((n.start_tick, true, n.pitch, n.velocity as f32 / 127.0));
events.push((n.end_tick, false, n.pitch, 0.0));
}
events.sort_by_key(|e| (e.0, !e.1)); // note-offs before note-ons at same tick
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Inverted sort order: note-ons sorted before note-offs

Medium Severity

The sort key (e.0, !e.1) produces the opposite of the intended order. Since e.1 is is_on: bool and Rust orders false < true, negating it with ! causes note-ons (!true = false) to sort before note-offs (!false = true) at the same tick. The comment says "note-offs before note-ons at same tick" but the code does the reverse. The fix is to use (e.0, e.1) instead of (e.0, !e.1). This causes the is_note_off check in the playback loop to miss transition boundaries where one note ends and another begins at the same tick, potentially delaying track switches.

Fix in Cursor Fix in Web

current_time,
);
pending_track_switch = None;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scheduled_time not reset on track switch causes drift

Medium Severity

When a track switch occurs (binding swap, section boundary note-off, or track exhaustion), command_index is repositioned via find_commands_at_time but scheduled_time is not reset to match the new track's cumulative timeline. Subsequent commands add their wait_before to the stale scheduled_time, producing a persistent timing offset equal to scheduled_time minus the new track's cumulative time at the new index, which can be up to one command's wait_before duration.

Additional Locations (2)

Fix in Cursor Fix in Web

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant