Skip to content

fix(core): GPIF imports keep tapping and hammer-on origin semantics - #201

Merged
PhysShell merged 3 commits into
mainfrom
claude/gpif-technique-fidelity
Sep 17, 2026
Merged

PhysShell merged 3 commits into
mainfrom
claude/gpif-technique-fidelity

Conversation

@PhysShell

Copy link
Copy Markdown
Owner

What

GPIF imports (GP6 .gpx, GP7/8 .gp) now keep tapping and read hammer-on/pull-off with GP3/4/5 semantics. Both were lost in the guitarpro 0.4.2 GPIF conversion:

before after
Tapped note property never read (beat tap effect left a placeholder) → no GP6/7 tapping in griff beat gets SlapEffect::Tapping (how GP3/4/5 store it) → notes marked NoteMark::Tap
HopoOrigin / HopoDestination both set the one legacy hammer flag → the destination note carried its own HammerOn span flag reset to HopoOrigin only — "legato to the next note on this string", as in GP3/4/5

How

As with the tuning fix (#198), the adapter reads the GPIF document itself and repairs the converted song at the import boundary. It walks the document exactly as the crate does and zips it with the converted song: each track's bar per master bar, voice slots skipping -1, then existing beats and notes in order. A voice whose converted beats or notes do not line up is left as converted and reported in the LossReport, never re-labelled out of step.

Measured on a 410-file Guitar Pro corpus (145 GPIF files)

GP6/GP7 files main this PR
files with tapped notes 0 28
tapped notes 0 2,013
HammerOn spans on single notes 18,284 10,906
next single note on the same string after a hammer span 76.8% 99.7%
voices left unrestored 0 0

GP3/4/5 imports are unchanged (identical tap and span counts; 99.1% same-string).

Tests

  • Red first (b9c037b), then green (89f3bde).
  • core/tests/gp_gpif_techniques.rs: authored GPIF text (no copyrighted tab) packed with the crate's public writer. It covers:
    • only the origin carries the hammer span;
    • a chain marks every origin but not the last destination;
    • two adjacent pairs stay two pairs;
    • a tapped note imports as a tap;
    • a tapped chord note taps its beat (the legacy per-beat model).
  • cargo test --workspace green locally (1,697 tests; missing_file_golden skipped locally only — its golden holds the English OS error text), cargo clippy -p griff-core --all-targets -- -D warnings and cargo fmt --check clean.

Out of scope / notes

🤖 Generated with Claude Code

…ntics

Two losses in the guitarpro 0.4.2 GPIF conversion, measured on a 410-file
Guitar Pro corpus:

- the Tapped note property is never read (the beat's tap effect is left a
  placeholder): 31 of 145 GPIF files carry tapping (1,006 Tapped note
  definitions) and none of it reached griff;
- HopoOrigin and HopoDestination both set the one legacy hammer flag. GP3/4/5
  set it on the origin note only and griff's HammerOn span follows that
  note; on GPIF input the destination got a span too, so adjacent
  independent pairs read as one chain. On the corpus, "same string" across
  derived hammer-on / pull-off edges is ~98% for GP3-5 but 79-85% for GP6-7.

Five failing tests over authored GPIF text packed with the crate's public
writer: only the origin carries the hammer span; a chain marks every origin
but not the last destination; two adjacent pairs stay two pairs; a tapped
note imports as a tap; a tapped chord note taps its beat (the legacy
model's per-beat tapping, as for GP3/4/5).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The adapter already reads the GPIF document itself (#198); it now also
restores two note techniques the guitarpro 0.4.2 conversion drops or
merges, walking the document exactly as the crate walks it (each track's
bar per master bar, voice slots skipping -1, existing beats and notes in
order) and zipping it with the converted song:

- Tapped: a beat with a tapped note gets the legacy beat-level
  SlapEffect::Tapping — how GP3/4/5 store tapping — so its notes become
  NoteMark::Tap through the existing path;
- HopoOrigin / HopoDestination: the legacy hammer flag is reset to
  HopoOrigin alone, the GP3/4/5 meaning ("legato to the next note on this
  string"), so a destination no longer carries a HammerOn span of its own.

A voice whose converted beats or notes do not line up with the document is
left as converted and reported in the loss report, never re-labelled out of
step.

Measured on the 410-file corpus, GP6/GP7 files (145):
- files with tapped notes 0 -> 28, tapped notes 0 -> 2,013;
- HammerOn spans on single notes 18,284 -> 10,906 (7,378 destination-only
  spans gone); the next single note is on the same string 76.8% -> 99.7%,
  in line with GP3-5's 99.1%;
- voices left unrestored: 0.
GP3/4/5 imports are unchanged (same tap and span counts).

cargo test --workspace green (1,697 tests; missing_file_golden skipped
locally only, as before); clippy -D warnings and fmt clean for griff-core.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Sep 17, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Advanced

Run ID: 6d4db0f7-6e88-4218-b46c-af11e7c22ce3


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@PhysShell
PhysShell merged commit c028609 into main Sep 17, 2026
16 checks passed
PhysShell pushed a commit that referenced this pull request Sep 17, 2026
#201 imports GP6/7 tapping. Rerun on this PR's lab code merged locally
with main: the slice grows from 155 to 242 lines, and the length-matched
baseline had contained that unlabelled tapping (1.26 -> 1.17 excess per
note for the original lines).

Hand attribution closes most, not all, of the slice's excess (94% on the
original lines against the corrected pool, 66% on the added GP6/7 lines
against their format, 78% overall); exactness stays out of reach in both
formats. The remaining excess concentrates in one-string tapping figures
with open-string pull-offs. Stage 2 starts from this re-measured baseline,
per format and with a per-song concentration check.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

2 participants