A fast, native Guitar Pro viewer written in Rust. Phase one: open Guitar Pro files and view each track as standard notation, tablature, or both.
cargo run --release -- path/to/song.gp # or open from the app: ⌘O / drag and drop| Shortcut | Action |
|---|---|
| ⌘O | Open file |
| ⌘S / ⇧⌘S | Save / save as Guitar Pro 7/8 (.gp) |
| ⌘Z / ⇧⌘Z | Undo / redo |
| ⌘1 … ⌘9 | Select track |
| ⌘+ / ⌘− / ⌘0 | Zoom in / out / reset |
| Space | Play / pause |
| Click / ⇧-click | Place the edit cursor (beat + string) / extend the bar selection |
| ← → / ↑ ↓ | Edit cursor: previous/next beat, string up/down |
| ⌘← / ⌘→ | Previous / next bar (→ past the end of the last bar adds a bar) |
| ⌘I / ⌘↩ / ⌘⇧⌫ | Insert bar before / add bar after / delete bar |
| 0–9 | Enter a fret on the cursor's string (two quick digits: 12) |
| Delete / ⌘Delete | Delete the note / the whole beat |
| + / − / . | Longer / shorter duration, cycle dots |
| R / I | Make the beat a rest / insert a beat |
| H / S / ⇧S | Hammer-on/pull-off / slide / cycle slide type |
| B / V / T | Cycle bend (full, ½, bend-release) / vibrato / tie to previous note |
| P / L / X / O | Palm mute / let ring / dead note / ghost note |
| A / N | Cycle accent / natural harmonic |
| Home | Back to the start |
| ⌘L | Loop the selected bars |
| PgUp / PgDn | Page through the score |
Supported formats: .gp (Guitar Pro 7/8), .gpx (Guitar Pro 6), .gp5, .gp4, .gp3.
Saving writes .gp (Guitar Pro 7/8). When the source was a .gp file, everything gpos doesn't
model (RSE sounds, stylesheets, lyrics, drum kits, layout) is carried over untouched.
Measured on the files in this repo's fixtures and real GP8 exports (Apple Silicon, release build):
- Parse: 0.3–10 ms per file. Layout: under 1 ms for a 64-bar track.
- 0% CPU when idle: egui only repaints on input; layout runs once per (track, width, zoom, view).
- Scrolling paints only the systems in the viewport (binary search over system extents).
- ~100 MB physical footprint when idle, mostly the GPU context; 11.7 MB binary with fonts and the default SoundFont embedded.
- Playback: ~9% of one core total (audio ~6.5%). The beat cursor only repaints at note onsets. The synth engine renders ~55x faster than realtime offline.
- Memory while playing is ~270 MB, of which ~150 MB is a macOS graphics-driver buffer pool that appears whenever frames are presented steadily (identical under OpenGL and Metal, flat over time). Caching systems as textures was tried and made it worse, so it isn't used.
crates/
gp-model Format-agnostic score model (tracks → staves → bars → voices → beats → notes)
gp-parser GP3/4/5 binary, GPX (BCFZ/BCFS container), GP7/8 (zip) → GPIF XML → model
score-layout Spacing, line breaking, notation + tab engraving → display list of primitives
gp-edit Edit cursor, edit operations and undo/redo history (no GUI dependency)
gp-playback Repeats unfolded → note/pitch-bend events → SoundFont synth (rustysynth) → cpal
gpos-app The desktop app (eframe/egui, OpenGL), paints the display list
score-raster CPU rasterizer for the display list (tiny-skia + glyph outlines); embeds the fonts
gpos-render Headless CLI: renders a track to PNG or audio to WAV, for checks and snapshots
assets/fonts Bravura (SMuFL music font, OFL) and Noto Sans (OFL)
assets/soundfont SONiVOX General MIDI SoundFont (Apache-2.0), the default instrument sounds
The layout engine has no GUI dependency: it emits absolutely positioned primitives (lines, glyphs, text, beams, ties) grouped into systems, so the same output drives the app, the PNG renderer, and future exporters (PDF/SVG).
cargo run --release -p gpos-render -- song.gp --track 1 --tab --width 1400 --out track1.png --dump
cargo run --release -p gpos-render -- song.gp --wav song.wav # offline audio render + levels
cargo run --release -p gpos-render -- song.gp5 --save song.gp # convert/save as Guitar Pro 7/8
cargo test --workspaceRenders: clefs, key/time signatures, notes and chords with correct spelling and accidentals, ledger lines, stems, beams (incl. secondary/partial beams), flags, rests, dots, ties, tuplets, grace notes, drum notation from the kit's articulation map, repeats, alternate endings, section markers, tempo marks, chord names, bar numbers. Tab: fret numbers, ties, dead/ghost notes, harmonics, hammer-ons/pull-offs, slides, bends and releases, vibrato, palm mute, let ring, tapping/slap/pop, pick strokes, and rhythm stems when notation is hidden.
Playback: all tracks with per-track mute/solo, repeats and alternate endings, tempo changes,
speed 25–150% (pitch unaffected), bar-range looping, metronome, one-bar count-in, beat cursor
with auto-follow. Effects rendered: ties, bends/releases/pre-bends, whammy, slides (shift,
legato, in/out), vibrato, hammer-ons/pull-offs, palm mute, dead/ghost notes, accents, staccato,
let ring, harmonics, tremolo picking, grace notes, brush strokes, swing/triplet feel.
Sounds: built-in SONiVOX GM bank, or any .sf2 via the "Sound" menu (loaded in the background,
swapped without stopping playback, remembered across launches).
Saving: GP7/8 writer verified three ways — parse→save→parse equality on all 46 fixtures (plus a second save over the result), alphaTab reading saved files identically to the originals for real GP8 files, and GP3-5/GPX conversions matching alphaTab's reading of the source except where alphaTab and PyGuitarPro disagree about the old format. Not yet checked in Guitar Pro itself. Known losses when converting older formats: chord names (GP7 needs chord diagrams) and GP5 bend curves with more than four points (GP7 bends are origin/middle/destination).
Debug aids: GPOS_AUTOPLAY=1 starts playback on launch; GPOS_SHOW=bar|track shows a menu's
contents in a window; GPOS_SCREENSHOT=out.ppm
(with GPOS_SCREENSHOT_DELAY=<secs>) saves the window and quits.
Editing: tab entry with an edit cursor, note effects, undo/redo, unsaved-changes prompts; playback starts at the cursor and follows edits. Effects apply to the note under the cursor, or to the whole beat when the cursor's string is empty. The Bar menu edits time/key signatures (from the current bar until the next change), tempo, repeats, alternate endings, sections and double bars; the Track menu renames, changes sound, tuning (frets kept, pitches follow) and capo, and adds or removes guitar, bass and drum tracks. Copy/paste and a second voice are next.
Not yet: page view/printing, multi-track score view, lyrics, dynamics, codas/segnos, slurs in standard notation.
Test fixtures: crates/gp-parser/tests/fixtures/pyguitarpro (LGPL-3.0, from PyGuitarPro) and
.../alphatab (MPL-2.0, from alphaTab); licenses alongside.