Skip to content

Fix GP7 score system layout serialization for multitrack view#2774

Merged
Danielku15 merged 8 commits into
CoderLine:developfrom
chenkigba:fix/gp7-score-multitrack-metadata
Jul 10, 2026
Merged

Fix GP7 score system layout serialization for multitrack view#2774
Danielku15 merged 8 commits into
CoderLine:developfrom
chenkigba:fix/gp7-score-multitrack-metadata

Conversation

@chenkigba

@chenkigba chenkigba commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #2775

This PR fixes Guitar Pro multitrack layout instability by changing only two numeric score-level GPIF fields from CDATA to text:

  • ScoreSystemsDefaultLayout
  • ScoreSystemsLayout

Free-form metadata remains CDATA. MultiVoice is intentionally left unchanged after maintainer feedback and isolated testing showed that it is unrelated to this issue.

Root cause

alphaTab previously exported the score-level layout fields as:

<ScoreSystemsDefaultLayout><![CDATA[3]]></ScoreSystemsDefaultLayout>
<ScoreSystemsLayout><![CDATA[1 2]]></ScoreSystemsLayout>

The equivalent per-track layout fields, and the score-level fields in the repository's Guitar Pro fixtures, use text:

<ScoreSystemsDefaultLayout>3</ScoreSystemsDefaultLayout>
<ScoreSystemsLayout>1 2</ScoreSystemsLayout>

The distinction matches the failure boundary: single-track layout uses the track-level fields, while multitrack layout uses the score-level fields. Guitar Pro 8.1.5 on macOS can open the CDATA form, but switching to multitrack view can cause malformed layout and abnormal memory growth.

Although CDATA and text represent character data at the XML data-model level, the isolated results below show that Guitar Pro's multitrack layout path is sensitive to this representation.

Isolated Guitar Pro 8.1.5 validation

All variants used the same exported score and were tested with a cold Guitar Pro launch:

Variant Score layout fields MultiVoice XML / binary Result
Baseline CDATA 1> / 0 Failed, RSS 461.9 -> 2188.1 MB
Layout-only fix, run 1 Text 1> / 0 Passed, RSS 461.7 -> 472.6 MB
Layout-only fix, run 2 Text 1> / 0 Passed, RSS 458.2 -> 467.1 MB
MultiVoice-only change CDATA 0> / 0 Failed, RSS reached 2183.9 MB
Layout plus MultiVoice change Text 0> / 0 Passed
Consistent enabled MultiVoice CDATA 1> / 1 Failed, RSS reached 2227.7 MB

This isolates the fix to the two score layout fields: changing them to text is sufficient, while changing MultiVoice is neither necessary nor sufficient.

Fixture evidence and safety

A scan of all 210 .gp fixtures under packages/alphatab/test-data found:

  • 210/210 serialize both score-level layout fields as text
  • 0/210 serialize either layout field as CDATA
  • Guitar Pro does write MultiVoice values with the trailing >, so this PR preserves the existing value

The CDATA safety concern for arbitrary strings does not apply here: these fields are generated from number and number[]. Titles, artists, lyrics, and other free-form fields are not changed.

Regression coverage

The exporter regression test now uses explicit non-default layout values and verifies:

<ScoreSystemsDefaultLayout>5</ScoreSystemsDefaultLayout>
<ScoreSystemsLayout>3 2 3</ScoreSystemsLayout>

It also verifies that neither field is emitted as CDATA.

Validation on this branch:

  • Gp7Exporter.test.ts: 19 passed
  • TypeScript typecheck: passed
  • lint on changed files: passed
  • full package lint: exited successfully with existing unrelated warnings

AI disclosure

Research and content generated by gpt5.6sol-max.

@chenkigba

Copy link
Copy Markdown
Contributor Author

For the reviewer:

First, thank you for this project. I use it in my own website, it's really really helpful!

Then, forgive me, I posted this PR by gpt5.5 xhigh.

But, only 3 line of code changed, I think it's reviewable.

And, I manually tested this fix in my case, it passed.

Picture 1: rendered by alphatab in my website
image

Picture 2: export from alphatab to .gp then import in guitar pro with multi-track view.
image

: )

@Danielku15

Copy link
Copy Markdown
Member

I have to dig deeper here. The current logic exists for various important reasons:

  • CData prevents corrupt XMLs when somebody has XML like characters in the text <> for number based tags we can safely change it, but for other areas we have to be careful.
  • The MultiVoice tag looks very strange, but that's what Guitar Pro actually writes.
image image
  • Guitar Pro 6+ (written in C++) uses quite standardized XML parsers, it surprises me that the change has such a significant impact to the GP behavior.

Keep Guitar Pro's native MultiVoice value unchanged and strengthen the regression test with explicit score layout values.\n\nResearch and implementation generated by gpt5.6sol-max.
@chenkigba chenkigba changed the title Fix GP7 score metadata export for Guitar Pro multitrack view Fix GP7 score system layout serialization for multitrack view Jul 10, 2026
@chenkigba

Copy link
Copy Markdown
Contributor Author

Thanks for pointing this out. You are right about MultiVoice: the trailing > is written by Guitar Pro itself, so I have reverted that part of the PR.

I ran an isolated ablation on Guitar Pro 8.1.5 using the same exported score and a cold launch for each variant:

  • baseline with the two score layout fields as CDATA: RSS grew from 461.9 MB to 2188.1 MB and failed;
  • changing only ScoreSystemsDefaultLayout and ScoreSystemsLayout from CDATA to text, while preserving MultiVoice=1>: passed twice (461.7 -> 472.6 MB and 458.2 -> 467.1 MB);
  • changing only MultiVoice, while retaining layout CDATA: still failed at 2183.9 MB;
  • making the XML and binary MultiVoice states consistent while retaining layout CDATA: still failed at 2227.7 MB.

This isolates the problem to the two score-level system-layout fields. I pushed e625b9fd to narrow the implementation and regression test accordingly.

The CDATA safety concern does not apply to these two fields because they are serialized from number and number[]; all free-form metadata remains CDATA. The equivalent per-track layout fields already use text, and all 210 .gp fixtures in the repository serialize both score-level layout fields as text.

I also noticed that GPIF MultiVoice and Content/LayoutConfiguration can be inconsistent in alphaTab output, but that is separate from this multitrack layout issue and should be investigated independently.

Research and content generated by gpt5.6sol-max.

# Conflicts:
#	packages/alphatab/src/exporter/GpifWriter.ts
#	packages/alphatab/test/exporter/Gp7Exporter.test.ts
@Danielku15

Copy link
Copy Markdown
Member

I just digged into this topic and detected some other issue around exporting which I fixed. Actually it was a bug in the Guitar Pro 3-5 importer which could lead to invalid midi port and channel configurations leading also to crashes. This happened often on GP3-5 to GP8 conversions.

@Danielku15 Danielku15 force-pushed the fix/gp7-score-multitrack-metadata branch from 024f137 to 3811071 Compare July 10, 2026 12:31
@Danielku15 Danielku15 merged commit 71dfb54 into CoderLine:develop Jul 10, 2026
5 checks passed
@Danielku15

Copy link
Copy Markdown
Member

Thanks a lot for your contribution, fix is merged 🥳

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.

Broken multitrack SystemLayout in exported GP files

3 participants