Skip to main content

Crate guitar_tab_generator

Crate guitar_tab_generator 

Source
Expand description

Generate fingerstyle guitar tabs, ranked from easiest to hardest to play.

Given a list of pitches, the crate finds every fret-and-string fingering for each pitch, builds a weighted directed graph of how hard it is to move between them, and runs Yen’s k-shortest-paths search to return whole arrangements ordered by difficulty. It is built for compilation to WebAssembly, but the same API works for native Rust.

§Quick start

use guitar_tab_generator::{generate_arrangements, TabInput};

// Newline-separated pitches. A blank line is a rest. A line like "D4G4" is a chord.
let input = TabInput::new("E2\nA2\nD3", "standard", 18, 0, 1);

// Arrangements come back ranked by difficulty, easiest first.
let set = generate_arrangements(input).expect("input is valid");

// render(index, width, padding, playback) is cheap to call repeatedly.
println!("{}", set.render(0, 30, 2, None).expect("arrangement 0 exists"));

§API at a glance

Most callers want the high-level path:

  1. Build a TabInput with TabInput::new (optionally TabInput::with_max_fret_span_filter).
  2. Call generate_arrangements to get an ArrangementSet.
  3. Read the set by index: ArrangementSet::render, ArrangementSet::difficulty, ArrangementSet::max_fret_span, and ArrangementSet::normalized_input.

For finer control, the building blocks behind that entry point are public too: parse_lines turns text into Lines, Guitar::new (with create_string_tuning and the TuningName presets from get_tuning_names) describes the instrument, create_arrangements runs the search, and render_tab formats one arrangement.

Every fallible call returns a typed TabError. Parser failures carry ParseError, and pitches that reach no string carry UnplayablePitch.

§Typed input

Rust callers can skip the string parser and build the input from Pitch and Line values directly, then call create_arrangements. It returns a Vec of Arrangement, and each one renders through render_tab.

use guitar_tab_generator::{
    create_arrangements, render_tab, Guitar, Line, NumArrangements, Pitch,
};

// A standard 18-fret 6-string guitar.
let guitar = Guitar::default();

// Build the input from Pitch values instead of parsing strings.
let lines = vec![
    Line::Playable(vec![Pitch::E2]),
    Line::Playable(vec![Pitch::A2]),
    Line::Playable(vec![Pitch::D3, Pitch::G3]), // a chord
];

// create_arrangements takes the guitar by value (the call is memoized), so pass a clone.
let arrangements = create_arrangements(
    guitar.clone(),
    lines,
    NumArrangements::try_new(1).expect("1 is in range"),
    None,
)
.expect("input is playable");

// Read metadata and render from the typed Arrangement.
let best = &arrangements[0];
println!("difficulty {}", best.difficulty());
println!("{}", render_tab(best.lines(), &guitar, 30, 2, None));

§More

The project README has the full algorithm walkthrough (with diagrams) and a link to the live web demo.

Structs§

Arrangement
Arrangement is re-exported for direct Rust consumers. The canonical 2.x access path for per-arrangement metadata is ArrangementSet::difficulty(i) and ArrangementSet::max_fret_span(i); direct construction of Arrangement values is internal. A single ranked guitar arrangement: one fingering choice per beat, ordered by line.
ArrangementSet
Opaque handle holding the result of one generate_arrangements call.
Guitar
A guitar configuration: the playable fret count above the capo and the reachable pitch range for each string.
NumArrangements
Validated count of arrangements to compute. Construction enforces 1..=NumArrangements::MAX.
ParseError
One unparseable substring in the input, with its 1-indexed line number.
PitchFingering
The assignment of a single Pitch to a specific StringNumber and fret position.
StringNumber
A validated guitar string number in the range 1..=12.
TabInput
Configuration bundle for one tab-generation request.
UnplayablePitch
A pitch that could not be played on the configured guitar, with its 1-indexed line number.

Enums§

Line
Arrangement is re-exported for direct Rust consumers. The canonical 2.x access path for per-arrangement metadata is ArrangementSet::difficulty(i) and ArrangementSet::max_fret_span(i); direct construction of Arrangement values is internal. One logical line of a parsed or arranged composition.
NormalizedBeat
One beat in the normalized input echoed back from ArrangementSet::normalized_input.
Pitch
A musical pitch in the range C0 through B9.
TabError
Top-level error variant for the WASM boundary.
TuningName
Named tuning presets. Parsed case-insensitively from strings.

Functions§

create_arrangements
Arrangement is re-exported for direct Rust consumers. The canonical 2.x access path for per-arrangement metadata is ArrangementSet::difficulty(i) and ArrangementSet::max_fret_span(i); direct construction of Arrangement values is internal.
create_string_tuning
Builds a tuning map from a slice of open-string pitches, numbering them from string 1 (highest) to string N (lowest).
generate_arrangements
Generates an ArrangementSet from a TabInput. Single entry point for both Rust callers and the WASM boundary; JS sees this as generateArrangements.
get_tuning_names
Returns the supported TuningName variants, typed for JS consumption via tsify.
parse_lines
render_tab
Renders an Arrangement’s lines as an ASCII guitar tab.

Type Aliases§

BeatVec
Arrangement is re-exported for direct Rust consumers. The canonical 2.x access path for per-arrangement metadata is ArrangementSet::difficulty(i) and ArrangementSet::max_fret_span(i); direct construction of Arrangement values is internal. One beat’s worth of items (usually Pitch or PitchFingering).