writeMidiFile: emit PART VOCALS / HARM1 / HARM2 / HARM3 tracks - #76
Open
elicwhite wants to merge 1 commit into
Open
writeMidiFile: emit PART VOCALS / HARM1 / HARM2 / HARM3 tracks#76elicwhite wants to merge 1 commit into
elicwhite wants to merge 1 commit into
Conversation
This was referenced Apr 20, 2026
Owner
Author
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
This was referenced Apr 20, 2026
elicwhite
force-pushed
the
midi-writer-guitar
branch
from
April 20, 2026 05:09
3d5ebf4 to
6bfcf43
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 20, 2026 05:09
17b2b16 to
ba58fa3
Compare
elicwhite
force-pushed
the
midi-writer-guitar
branch
from
April 20, 2026 05:10
6bfcf43 to
fa58c6e
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 20, 2026 05:10
ba58fa3 to
cc46d30
Compare
elicwhite
force-pushed
the
midi-writer-guitar
branch
from
April 20, 2026 05:19
fa58c6e to
409ccf5
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 20, 2026 05:19
cc46d30 to
631a9d0
Compare
This was referenced Apr 20, 2026
elicwhite
marked this pull request as ready for review
April 20, 2026 16:09
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 21, 2026 04:29
631a9d0 to
a5b46ec
Compare
elicwhite
force-pushed
the
midi-writer-guitar
branch
2 times, most recently
from
April 21, 2026 04:47
4069bbd to
e846368
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 21, 2026 04:48
a5b46ec to
e69e3e0
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
2 times, most recently
from
April 21, 2026 16:35
b5242da to
7a8a4ff
Compare
elicwhite
force-pushed
the
midi-writer-guitar
branch
2 times, most recently
from
April 21, 2026 16:38
7627809 to
0dc86ae
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
2 times, most recently
from
April 21, 2026 16:51
09e9e4e to
4de2741
Compare
elicwhite
force-pushed
the
midi-writer-guitar
branch
from
April 21, 2026 16:51
0dc86ae to
21b132d
Compare
elicwhite
force-pushed
the
midi-writer-guitar
branch
from
April 21, 2026 23:18
21b132d to
f4cca25
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 21, 2026 23:18
4de2741 to
771cfa8
Compare
Adds vocal-track emission to writeMidiFile. One MIDI track per vocal
part (vocals → PART VOCALS, harmony{1,2,3} → HARM{1,2,3}; HARM* not
PART HARM*, matching the convention used in the wild).
Phrase-marker emission is careful about YARG's CopyDownPhrases, which
at parse time copies HARM1's notePhrases onto HARM2/HARM3:
- PART VOCALS: notePhrases → 105 (player:2 → 106)
- HARM1: notePhrases → 105, staticLyricPhrases → 106
- HARM2: only staticLyricPhrases → 106 (note 105 comes from HARM1
via CopyDown on re-parse — would double-count otherwise)
- HARM3: no phrase markers at all
Lyrics and notes are union'd across both phrase sets (note 105 and 106
can have different boundaries; emitting the union keeps all lyrics
that belong on the track). Zero-length vocal notes are preserved via
per-event `seq` tags so finalizeMidiTrack keeps noteOn immediately
before its matching noteOff.
Star power (MIDI 116) is suppressed on HARM2/HARM3 — CopyDown recreates
it from HARM1 on re-parse. Range shifts (MIDI 0) and lyric shifts (MIDI
1) are per-part for lossless round-trip, with fallback to the
track-level arrays for the part that owns them (PART VOCALS, or HARM1
when PART VOCALS is absent). Raw vocal-track text events (stance
markers, facial anim triggers) are re-emitted verbatim so that
stance-only tracks survive round-trip — YARG marks a VocalsPart
non-empty iff it has phrases or text events.
Tests: 18 new cases covering track naming (PART VOCALS, HARM1/2/3 with
no PART HARM* prefix), phrase-marker routing per part, pitched/
percussion/out-of-range note emission, lyric union across phrase sets,
star power suppression on HARM2/3, range+lyric shifts, text events,
and round-trip through parseChartAndIni for both PART VOCALS and the
full harmony stack with CopyDown semantics preserved.
71 midi-writer tests, 415 total scan-chart tests passing.
elicwhite
force-pushed
the
midi-writer-guitar
branch
from
April 22, 2026 16:34
f4cca25 to
940eeea
Compare
elicwhite
force-pushed
the
midi-writer-vocals
branch
from
April 22, 2026 16:34
771cfa8 to
53a5a9d
Compare
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.

Adds vocal-track emission to writeMidiFile. One MIDI track per vocal
part (vocals → PART VOCALS, harmony{1,2,3} → HARM{1,2,3}; HARM* not
PART HARM*, matching the convention used in the wild).
Phrase-marker emission is careful about YARG's CopyDownPhrases, which
at parse time copies HARM1's notePhrases onto HARM2/HARM3:
via CopyDown on re-parse — would double-count otherwise)
Lyrics and notes are union'd across both phrase sets (note 105 and 106
can have different boundaries; emitting the union keeps all lyrics
that belong on the track). Zero-length vocal notes are preserved via
per-event
seqtags so finalizeMidiTrack keeps noteOn immediatelybefore its matching noteOff.
Star power (MIDI 116) is suppressed on HARM2/HARM3 — CopyDown recreates
it from HARM1 on re-parse. Range shifts (MIDI 0) and lyric shifts (MIDI
track-level arrays for the part that owns them (PART VOCALS, or HARM1
when PART VOCALS is absent). Raw vocal-track text events (stance
markers, facial anim triggers) are re-emitted verbatim so that
stance-only tracks survive round-trip — YARG marks a VocalsPart
non-empty iff it has phrases or text events.
Tests: 18 new cases covering track naming (PART VOCALS, HARM1/2/3 with
no PART HARM* prefix), phrase-marker routing per part, pitched/
percussion/out-of-range note emission, lyric union across phrase sets,
star power suppression on HARM2/3, range+lyric shifts, text events,
and round-trip through parseChartAndIni for both PART VOCALS and the
full harmony stack with CopyDown semantics preserved.
71 midi-writer tests, 415 total scan-chart tests passing.