Store unrecognized tracks and per-track unrecognized events - #91
Merged
Conversation
elicwhite
force-pushed
the
unrecognized-tracks
branch
11 times, most recently
from
April 18, 2026 17:38
cdc056c to
1fc912e
Compare
Eliminate top-level notes[]/lyrics[] from NormalizedVocalPart. All vocal
content is accessed through phrase grouping.
- NormalizedVocalPart: removed notes[] and lyrics[]
- NormalizedVocalPhrase: added player?: 1 | 2 for versus mode
- NormalizedLyricEvent.text: stores original unstripped markup symbols
- NormalizedVocalNote.pitch: nonPitched keeps original MIDI pitch
- PART VOCALS merges note 105+106 phrases with player tags
- Harmonies keep separate 105/106 for lossless round-trip
- Pre-collect lyrics per phrase (lyricIdx advances to phraseEnd
regardless of notes, preventing divergence on pitch slide round-trip)
- Pitch slide notes only skipped when lyric survives emptiness filter
- HARM3 CopyDown: clone staticLyricPhrases from HARM2
- Writer emits union of notes/lyrics from both phrase sets
- extractMidiVocalTextEvents for stance/facial anim events on vocal tracks
Generic chart-parser helpers (used elsewhere too):
- resolveChartTrackName: matches YARG's ChartReader logic for instrument+
difficulty resolution from .chart section names ("ExpertDoubleDrums" etc.)
- parseChartSectionEventText: matches YARG's TextEvents.NormalizeTextEvent
pipeline for section event detection
elicwhite
force-pushed
the
unrecognized-tracks
branch
from
April 18, 2026 17:42
1fc912e to
8146f70
Compare
Verify that a lyric at tick T (where phrase 1 ends at T and phrase 2 starts at T) ends up in the new phrase, including when the lyric event appears before the phrase noteOn events in MIDI file order.
Two new fields on RawChartData / ParsedChart:
- unrecognizedTracks: { trackName, events: MidiEvent[] }[]
Whole MIDI tracks whose name isn't in the recognized set
(PART REAL_GUITAR/BASS/KEYS, PART ELITE_DRUMS, PART REAL_DRUMS_PS,
PART KEYS GHL, VENUE, BEAT, custom tracks, etc.). Stored verbatim
for round-trip.
- trackData[].unrecognizedEvents: MidiEvent[]
Events on recognized tracks that the typed parser didn't consume:
noteOn/noteOff outside recognized note ranges, non-Phase-Shift sysEx,
and any other event types (marker, lyrics, instrumentName, channel
events, etc.). Stored verbatim for round-trip.
- unrecognizedSections: { name, lines: string[] }[] (.chart equivalent
of unrecognizedTracks for sections that aren't Song/SyncTrack/Events
or a recognized track section)
Replaces the explicit per-instrument parsing for Pro Guitar/Bass/Pro Keys/
Elite Drums/GHL Keys/Phase Shift Real Drums/VENUE/BEAT/animations/hand
maps/etc. that was bundled in the old #7/#8/#9. The unrecognized fallback
preserves all that data for byte-equivalent round-trip without per-track
schema cost.
PART REAL_DRUMS_PS now always lands as unrecognized (no special-case
duplicateDrumsTrack parseIssue) — no merge with PART DRUMS, just preserved
verbatim alongside it.
13 new unit tests covering whole-track capture, per-track unconsumed
events, REAL_DRUMS_PS coexisting with PART DRUMS, .chart unrecognizedSections.
elicwhite
force-pushed
the
unrecognized-tracks
branch
from
April 19, 2026 00:05
8146f70 to
aa4c8d3
Compare
Per PR review feedback: format-specific fields now spell out their format in the name so consumers don't have to consult the docstring. unrecognizedTracks → unrecognizedMidiTracks (top-level RawChartData) unrecognizedSections → unrecognizedChartSections (top-level RawChartData) trackData[].unrecognizedEvents → unrecognizedMidiEvents VocalTrackData.unrecognizedEvents → unrecognizedMidiEvents The top-level `unrecognizedEvents` (text-like events from the EVENTS track / .chart [Events] section) keeps its name — it applies to both formats.
Per PR review feedback: removing the mutable boolean makes the structure self-documenting — adding a new SysEx case won't require remembering to set the flag, since the only way to reach `unrecognizedEvents.push` is through the explicit `else` arm. The Phase Shift header check is hoisted to a const, then the type lookup short-circuits to null when the header doesn't match. The single type !== null check then routes to either eventEnds (consumed) or unrecognizedEvents (else).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #84 and #90. Merge those first.
Two new fields on RawChartData / ParsedChart for round-trip preservation:
Replaces the explicit per-instrument parsing that was in the previously-closed PRs #81/#82/#83/#88 (Pro Guitar/Bass/Pro Keys/Elite Drums/GHL Keys/VENUE/BEAT/animations/hand maps). The unrecognized fallback preserves all that data for byte-equivalent round-trip without per-track schema cost.
PART REAL_DRUMS_PS now always lands as unrecognized — no special-case duplicateDrumsTrack parseIssue, no merge with PART DRUMS, just preserved verbatim alongside it.
13 new unit tests covering whole-track capture, per-track unconsumed events, REAL_DRUMS_PS coexisting with PART DRUMS, .chart unrecognizedSections.
Validated: 0 hash regressions vs upstream master baseline. 268 unit tests pass.