Skip to content

GP vocal import drops lyrics when the first bar voice is silent #103

Closed as not planned

Description

@cchacs

Target

lib/gp2rs_gpx.py, convert_vocal_track(), multi-voice loop around lines 2290–2360 (commit 6246269).

Category

Workflow / data-loss regression

Flaw analysis

The new unconditional break runs after processing the first valid GP voice object in a bar, regardless of whether that voice emitted any lyric token. A common GP layout can place a silent/alternate-rhythm voice first and the actual lyric-bearing voice second. In that case the converter drops every lyric in the second voice.

Minimal reproduction against current HEAD:

  • one 4/4 master bar
  • <Bar><Voices>silent lyric</Voices></Bar>
  • silent contains a quarter-note beat with no <Lyrics>
  • lyric contains a quarter-note beat with <Lyrics><Line>hello</Line></Lyrics> and a pitched note

convert_vocal_track() returns:

<?xml version="1.0" ?>
<vocals count="0"/>

The targeted parser suite currently passes because tests/test_gp2rs_gpx.py tests convert_vocal_track_to_pitch_sidecar() but has no multi-voice tests for convert_vocal_track().

There is also a consistency gap: convert_vocal_track_to_pitch_sidecar() still walks all voices and leaves tie durations uncapped, so callers following its documented “call both” workflow can produce a lyric XML and pitch ribbon with different voice membership and sustain lengths.

Remediation

Select the primary vocal voice by content, not position: inspect voices for lyric-bearing beats and choose the first coherent lyric-bearing voice for that bar (or define a deterministic track-level voice policy). Apply the same voice-selection and tie-duration policy to the pitch-sidecar helper. Add regressions for:

  1. first voice silent, second voice lyrical;
  2. two simultaneous lyrical voices;
  3. XML and pitch-sidecar timelines having matching selected onsets and capped durations.

Activity

  1. pullfrog commented on Sep 26, 2026

    @pullfrog
  2. added theissue type on Sep 26, 2026
  3. cchacs commented on Oct 2, 2026

    @cchacs
    CollaboratorAuthor

    I couldn't reproduce this on current main (db83297).

    • convert_vocal_track() in lib/gp2rs_gpx.py has no unconditional break after the first voice. The only break in that function is the inner one that picks one pitch per beat.
    • I built the repro from the issue (one 4/4 bar, a silent first voice, a second voice with <Lyrics><Line>hello</Line></Lyrics> and a pitched note). It returns <vocals count="1"> with lyric="hello".
    • The commit cited (6246269) doesn't exist in this repo, so the regression may live on another branch or fork, or already be fixed here.

    I added a regression test for the scenario in #129 (see the PR linked from #94's fix). Could you say which branch or commit you saw count="0" on? If it's not reproducible there either, this can be closed.


    Generated by Claude Code

  4. reopened this on Oct 2, 2026
  5. cchacs commented on Oct 2, 2026

    @cchacs
    CollaboratorAuthor

    Closing: not reproducible on main, and no further details have come in. The multi-voice case from the report (silent first voice, lyric in the second) is now pinned by a regression test in tests/test_gp2rs_gpx.py (merged in #129), so a regression would fail CI. If it shows up on a specific branch or commit, reopen with that ref.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions