Skip to content

1.FretboardMapper Algorithm Configuration and Tunables

ScottVR edited this page Nov 4, 2026 · 1 revision

Mapper Configuration Reference

The fretboard mapper decides where on the neck each note is played. This page lists every option that changes its choices, with its default; gtrsnipe --help is the final word. The player and chord charts use the same mapper: gtrsnipe --play and gtrsnipe -o song.chords.md take every option below, and the shortcuts gtrsnipe-play and gtrsnipe-chords take the tuning and mapper options. Checked against the code of v0.6.10 (2026-09-28).

Source of truth

  • Flags: gtrsnipe/arguments.py: add_tuning_args(), add_mapper_args(), setup_parser()
  • Defaults: MapperConfig in gtrsnipe/core/config.py
  • Scoring and search: GuitarMapper in gtrsnipe/guitar/mapper.py: _score_fingering(), map_multi_string() (Viterbi), _map_multi_string_greedy() (greedy)

How the mapper works

  1. Range. Notes outside the instrument's range (the lowest open string up to the highest open string plus --max-fret) are dropped. --normalize-pitch moves them by octaves until they fit instead.
  2. Grouping. Note starts are rounded to a grid (--quantization-resolution). Notes that start on the same grid point form one group: a chord, or a single note. A group with more notes than the instrument has strings keeps its lowest notes.
  3. Candidates. For each group, the mapper lists every fingering that puts each note on a different string.
  4. Scoring. Each candidate gets a score: bonuses minus penalties for its shape, its place on the neck, and the move from the previous group's fingering. Higher is better.
  5. Choice. The optimizer picks one fingering per group (see below).
  6. Techniques. Hammer-ons, pull-offs and taps are inferred from the chosen positions.

Every weight is a plain number. A negative value turns a penalty into a bonus, and a bonus into a penalty.


The optimizer

Flag Default Effect
--optimizer {viterbi,greedy} viterbi How the mapper chooses among the scored fingerings.
  • viterbi (the default since v0.3.0) finds the sequence of fingerings with the highest total score for the whole piece, by dynamic programming (the Viterbi algorithm). A fingering that scores a little worse on its own can win when it makes the following groups easier.
  • greedy (the only mapper before v0.3.0) takes the groups in order and keeps each one's best-scoring fingering, given the one chosen before it. It never revisits a choice.

Both use the same score, so every weight below means the same thing to both, and the Viterbi total is never lower than greedy's. They can still give different tabs for the same options. The example pages of this wiki were made with greedy; add --optimizer greedy to reproduce them.

--debug prints each candidate's score only with --optimizer greedy.


1. Instrument and tuning

Flag Default Effect
--tuning NAME STANDARD A named tuning (list below). --tuning PIANO is meant for full-range MIDI passthrough, but it currently stops with an error whatever the output.
--tuning-pitches LOW,..,HIGH none A custom tuning: one note name per string, lowest string first, e.g. A1,E2,A2,D3,F#3,B3. Two strings or more. Overrides --tuning.
--drop-low-string N 0 Lower the lowest string by N semitones (2 = drop-D style), on a named or custom tuning.
--num-strings {4,5,6,7} from the tuning Must match the tuning's string count. With STANDARD, 7 selects SEVEN_STRING_STANDARD and 4 selects BASS_STANDARD. For any other instrument, use --tuning-pitches.
--bass off Shortcut for --tuning BASS_STANDARD. It replaces any --tuning you give, so for another bass tuning pass --tuning BASS_DROP_D or --tuning BASS_E_FLAT without --bass.
--capo N 0 Capo at fret N. Tab fret numbers count from the capo.
--max-fret N 24 Highest fret on the virtual neck.

Named tunings. gtrsnipe --list-tunings prints them all with their notes, low string to high; gtrsnipe --show-tuning NAME prints one, with each string's tension on your guitar.

  • Guitar: STANDARD, E_FLAT, DROP_D, D_STANDARD, DROP_C, OPEN_G, OPEN_E, DADGAD, OPEN_D, OPEN_C6, C_SHARP_STANDARD, DROP_B
  • Baritone: BARITONE_B, BARITONE_A, BARITONE_C
  • 7-string: SEVEN_STRING_STANDARD, SEVEN_STRING_DROP_A
  • Bass (4 strings): BASS_STANDARD, BASS_DROP_D, BASS_E_FLAT

In v0.6.9 and earlier, --tuning rejected six of these although --list-tunings listed them: DADGAD, DROP_B, D_STANDARD, OPEN_D, OPEN_E and SEVEN_STRING_DROP_A. With those versions, pass their notes to --tuning-pitches instead.

A 5-string bass has no named tuning: use --tuning-pitches B0,E1,A1,D2,G2. A .tab input is read in the tuning of its // Tuning: header unless you give a tuning option. --scale-length and --string-gauges affect only the string-tension checks (--homograph, --show-tuning, and the warnings for custom tunings), not the mapper. In --string-gauges, w marks a wound string and p a plain one; unsuffixed gauges above .020 count as wound, so a plain .022 is 22p.


2. Shape and position

Scored for each group on its own.

Flag Default Effect
--fret-span-penalty F 100.0 Subtracted once per fret of span: the distance between the group's highest and lowest fret. Open strings count as fret 0 unless --ignore-open is set.
--unplayable-fret-span N 4 A fingering that spans more than N frets gets a score of −1000, which normally rules it out. Also the limit for --diagonal-span-penalty.
--ignore-open off Leave open strings out of the span, so an open string doesn't make a chord look like a stretch. Position and movement still count open strings as fret 0.
--sweet-spot-low N 0 Lowest fret of the preferred range.
--sweet-spot-high N 12 Highest fret of the preferred range.
--sweet-spot-bonus F 0.5 Added when the group's average fret is within the sweet spot.
--high-fret-penalty F 5.0 When the average fret is above --sweet-spot-high, subtracted once per fret above it. Below --sweet-spot-low there is neither bonus nor penalty.
--low-string-high-fret-multiplier F 10.0 Multiplies the high-fret penalty when the group uses string 5 or a lower one, counting the highest string as 1 (the A and low E strings of a 6-string). It never applies on a 4-string bass.
--barre-bonus F 0.0 For a chord with two or more fretted notes on the same fret: added once per note on that fret beyond the first.
--barre-penalty F 0.0 The same count, subtracted.

3. Moves between groups

Scored between each group and the one before it.

Flag Default Effect
--movement-penalty F 3.0 Subtracted once per fret the hand moves: the difference between this group's average fret and the previous group's. Open strings count as fret 0.
--string-switch-penalty F 5.0 Subtracted once for each string that only one of the two groups uses. A single note moving to another string counts 2.
--let-ring-bonus F 0.0 (off) Added once for each string the previous group played that this group leaves alone, so its note can ring on. Open and fretted strings count alike.
--diagonal-span-penalty off Subtract 1000 when the fretted notes of this group and the previous one together span more than --unplayable-fret-span frets. With --let-ring-bonus above 0, the group before the previous one is included too. Open strings are ignored.

4. Open strings

Flag Default Effect
--prefer-open off Penalize each fretted note whose pitch is also the pitch of an open string (so open B wins over the G string's 4th fret).
--fretted-open-penalty F 20.0 The penalty per such note. Used only with --prefer-open.

5. Grouping and cleanup

Flag Default Effect
--quantization-resolution R 0.125 The grid, in beats, for grouping notes into chords and for spacing the tab. R is one of 0.0125, 0.025, 0.0625, 0.125, 0.25, 0.5, 1.0. With a quarter-note beat, 0.125 is a 32nd note, 0.25 a 16th and 0.5 an 8th.
--no-pre-quantize off Skip the pass, on by default, that moves every note's start onto the grid before mapping. Grouping into chords still uses the grid.
--dynamic-quantize off Audio input only: move notes onto a beat grid detected from the audio.
--dedupe off Drop repeated pitches within a chord. Useful for MIDI from keyboards or ensembles.
--mono-lowest-only off ASCII tab output only: after mapping, write one note per chord, the one on the lowest string.

6. Techniques

Flag Default Effect
--legato-time-threshold F 0.5 Two notes in a row on the same string, at most F beats apart, become a hammer-on (going up) or a pull-off (going down).
--no-articulations off No hammer-ons, pull-offs or taps: every note is picked.
--single-string N off Put every note on string N (1 = high e, 6 = low E), bypassing the optimizer. Notes that don't fit on that string are dropped.
--tapping-run-threshold N 2 With --single-string only. In a run of hammer-ons and pull-offs longer than N notes (so, by default, 3 or more), the highest note becomes a tap, unless the run starts on its only highest note (a descending run).

How to use in practice

gtrsnipe -i input.mid -o output.tab --tuning DROP_D \
         --fret-span-penalty 200 --movement-penalty 1.5 --sweet-spot-high 9 --prefer-open
  1. Start with the defaults.
  2. Chords come out with wide stretches: raise --fret-span-penalty or lower --unplayable-fret-span. If open-position chords are being avoided, try --ignore-open.
  3. The hand jumps around the neck: raise --movement-penalty.
  4. Too much on one string: lower --string-switch-penalty. Too many string changes: raise it.
  5. The wrong part of the neck: set --sweet-spot-low and --sweet-spot-high, and raise --high-fret-penalty to keep the notes there.
  6. Open strings: add --prefer-open (and adjust --fretted-open-penalty). Ringing notes: --let-ring-bonus with --diagonal-span-penalty, as in the Asturias example.

Change one option at a time and compare. These help:

  • gtrsnipe -i input.mid --play --view tab plays the fingering as a scrolling tab with the same options, without writing a file.
  • gtrsnipe -i input.mid --analyze ranks the tunings that fit the song by the mapper's score per note, using your options.
  • --save-args NAME saves the options you set (those that differ from the defaults) as a profile, and --profile NAME applies it later. Profiles are plain files in ./.gtrsnipe or ~/.gtrsnipe.

Example: --ignore-open

Four chords, Dm, Am, G and D, two beats each. With the defaults:

e|----|-3--|
B|-6-5|-0-7|
G|-7-5|-0-7|
D|-7-7|-0-7|
A|-5-7|-2-5|
E|---5|-3--|

With --ignore-open:

e|-1-0|-3-2|
B|-3-1|-0-3|
G|-2-2|-0-2|
D|-0-2|-0-0|
A|---0|-2--|
E|----|-3--|

By default an open string counts as fret 0 in the span. The open Dm (frets 0, 2, 3, 1) spans 3 frets, while the Dm at the 5th fret spans 2, so the mapper plays it at the 5th fret and keeps the hand there for Am. With --ignore-open the open Am and D span only 1 fret and win outright. The two Dm shapes now tie at 2 frets, and the open one wins because it is closer to the open Am that follows.

--optimizer greedy --ignore-open still plays the first Dm at the 5th fret. Its two shapes score the same, and greedy keeps the first one it finds without looking at the chords that follow. Page 2 shows the same effect on the Mr Crowley organ intro.

Clone this wiki locally