From 74ce7e39f87d0dcb22850c08cd2f08f1ef51daa3 Mon Sep 17 00:00:00 2001 From: Kenneth Reitz Date: Sun, 22 Mar 2026 06:55:26 -0400 Subject: [PATCH] Rewrite fretboard docs: all 25 instruments documented Organized by family: - Guitars: standard, 12-string, bass, alternate tunings - Mandolin family: mandolin, mandola, octave mandolin, mandocello - Bowed strings: violin, viola, cello, double bass, erhu - Plucked: ukulele, banjo, harp - World: oud, sitar, shamisen, pipa, bouzouki, lute, balalaika, charango - Steel: pedal steel - Keyboards: piano (88), synth (61), mini (25) Each section includes tuning details, cultural context, and Wikipedia links. Co-Authored-By: Claude Opus 4.6 (1M context) --- docs/guide/fretboard.rst | 265 +++++++++++++++++++++++---------------- 1 file changed, 158 insertions(+), 107 deletions(-) diff --git a/docs/guide/fretboard.rst b/docs/guide/fretboard.rst index 0ad40be..5f34b7d 100644 --- a/docs/guide/fretboard.rst +++ b/docs/guide/fretboard.rst @@ -1,17 +1,25 @@ -Fretboard and Fingerings -======================== +Instruments and Fingerings +========================== -The :class:`~pytheory.chords.Fretboard` class represents a fretted instrument's -tuning and generates chord fingerings. +The :class:`~pytheory.chords.Fretboard` class models any stringed +instrument and generates chord fingerings. PyTheory includes **25 +instrument presets** spanning Western, Asian, Middle Eastern, Latin +American, and Russian traditions. -How Frets Work --------------- +How It Works +------------ -Each `fret `_ on a guitar (or any fretted instrument) raises the pitch by -exactly **one semitone**. The open string is fret 0; fret 1 is one -semitone up, fret 2 is two semitones up, and so on. +Each `fret `_ on a stringed +instrument raises the pitch by exactly **one semitone**. The open +string is fret 0; fret 1 is one semitone up, and so on. Even fretless +instruments (violin, oud, erhu) can be modeled this way — the "fret" +positions are just semitone steps along the fingerboard. -`Standard guitar tuning `_ (high to low):: +Guitars +------- + +`Standard guitar tuning `_ +(high to low):: String 1: E4 (highest) String 2: B3 @@ -21,119 +29,144 @@ semitone up, fret 2 is two semitones up, and so on. String 6: E2 (lowest) This tuning uses intervals of a perfect 4th (5 semitones) between most -strings, except between G and B which is a major 3rd (4 semitones). This -asymmetry is why guitar chord shapes shift when they cross the G-B pair. - -Preset Tunings --------------- +strings, except between G and B which is a major 3rd (4 semitones). .. code-block:: python from pytheory import Fretboard - # Guitars - guitar = Fretboard.guitar() # Standard EADGBE - twelve = Fretboard.twelve_string() # 12-string (6 doubled courses) - bass = Fretboard.bass() # Standard EADG - bass5 = Fretboard.bass(five_string=True) # 5-string BEADG + guitar = Fretboard.guitar() # Standard EADGBE + twelve = Fretboard.twelve_string() # 12-string (6 doubled courses) + bass = Fretboard.bass() # Standard 4-string EADG + bass5 = Fretboard.bass(five_string=True) # 5-string with low B - # Plucked strings - ukulele = Fretboard.ukulele() # GCEA (re-entrant) - mandolin = Fretboard.mandolin() # GDAE (tuned in 5ths) - banjo = Fretboard.banjo() # Open G (5-string with drone) - - # Bowed strings - violin = Fretboard.violin() # GDAE - viola = Fretboard.viola() # CGDA (5th below violin) - cello = Fretboard.cello() # CGDA (octave below viola) - -Alternate Guitar Tunings -~~~~~~~~~~~~~~~~~~~~~~~~ - -PyTheory supports several common alternate tunings, including -`open tunings `_, -`Drop D `_, and -`DADGAD `_: +**Alternate tunings** — 8 built-in presets: .. code-block:: python - # Built-in alternate tunings - drop_d = Fretboard.guitar("drop d") # DADGBE — heavy riffs - open_g = Fretboard.guitar("open g") # DGDGBD — slide guitar, Keith Richards - open_d = Fretboard.guitar("open d") # DADF#AD — slide, folk - open_e = Fretboard.guitar("open e") # EBEG#BE — slide blues - open_a = Fretboard.guitar("open a") # EAC#EAE - dadgad = Fretboard.guitar("dadgad") # DADGAD — Celtic, fingerstyle - half_down = Fretboard.guitar("half step down") # Eb standard — Hendrix, SRV + Fretboard.guitar("drop d") # DADGBE — heavy riffs, metal + Fretboard.guitar("open g") # DGDGBD — slide guitar, Keith Richards + Fretboard.guitar("open d") # DADF#AD — slide, folk + Fretboard.guitar("open e") # EBEG#BE — slide blues + Fretboard.guitar("open a") # EAC#EAE + Fretboard.guitar("dadgad") # DADGAD — Celtic, fingerstyle + Fretboard.guitar("half step down") # Eb standard — Hendrix, SRV # Custom tuning with any notes - custom = Fretboard.guitar(("D4", "A3", "F#3", "D3", "A2", "D2")) + Fretboard.guitar(("C4", "G3", "C3", "G2", "C2", "G1")) -The String Family +The Mandolin Family +------------------- + +The `mandolin family `_ +mirrors the `violin family `_ +— all tuned in perfect fifths, with each member a fifth or octave +lower than the last: + +.. code-block:: python + + Fretboard.mandolin() # E5 A4 D4 G3 — soprano (= violin) + Fretboard.mandola() # A4 D4 G3 C3 — alto (= viola) + Fretboard.octave_mandolin() # E4 A3 D3 G2 — tenor (octave below mandolin) + Fretboard.mandocello() # A3 D3 G2 C2 — bass (= cello) + +The mandolin's doubled courses (pairs of strings) create a natural +chorus effect. The `octave mandolin `_ +is popular in Irish and Celtic folk music. + +The Bowed String Family +----------------------- + +The orchestral `string family `_ +is tuned in perfect fifths (except the double bass, which uses fourths): + +.. code-block:: python + + Fretboard.violin() # E5 A4 D4 G3 — soprano + Fretboard.viola() # A4 D4 G3 C3 — alto (5th below violin) + Fretboard.cello() # A3 D3 G2 C2 — tenor/bass (octave below viola) + Fretboard.double_bass() # G2 D2 A1 E1 — bass (tuned in 4ths!) + +Bowed strings have no frets — the player can produce any pitch along +the fingerboard, enabling continuous +`vibrato `_ and microtonal +inflections not possible on fretted instruments. + +The `erhu `_ — a 2-stringed Chinese +bowed instrument with a hauntingly vocal quality: + +.. code-block:: python + + Fretboard.erhu() # A4 D4 — tuned a 5th apart, no fingerboard + +Plucked Strings +--------------- + +.. code-block:: python + + Fretboard.ukulele() # A4 E4 C4 G4 — re-entrant tuning + Fretboard.banjo() # Open G (bluegrass, 5th string is high drone) + Fretboard.banjo("open d") # Open D (clawhammer, old-time) + Fretboard.harp() # 47 strings, C1 to G7 (concert pedal harp) + +The `banjo `_'s short 5th string +is a high drone — a defining feature of the instrument's sound. + +The `harp `_ has one string per +diatonic note across nearly 7 octaves. Pedals alter each note name +by up to two semitones across all octaves simultaneously. + +World Instruments ----------------- -All four members of the orchestral string family are tuned in -`perfect fifths `_ -(7 semitones between adjacent strings): +.. code-block:: python + + # Middle Eastern + Fretboard.oud() # C4 G3 D3 A2 G2 C2 — fretless, ancestor of the lute + Fretboard.sitar() # 7 main strings — Indian classical + + # East Asian + Fretboard.shamisen() # C4 G3 C3 — 3-string Japanese, honchoshi tuning + Fretboard.pipa() # D4 A3 E3 A2 — 4-string Chinese lute + Fretboard.erhu() # A4 D4 — 2-string Chinese bowed + + # European + Fretboard.bouzouki() # D4 A3 D3 G2 — Irish (Celtic music) + Fretboard.bouzouki("greek") # D4 A3 F3 C3 — Greek + Fretboard.lute() # G4 D4 A3 F3 C3 G2 — Renaissance (6 courses) + Fretboard.balalaika() # A4 E4 E4 — Russian (2 unison strings) + + # Latin American + Fretboard.charango() # E5 A4 E5 C5 G4 — Andean (re-entrant tuning) + + # Steel guitar + Fretboard.pedal_steel() # 10 strings, E9 Nashville — country music + +The `oud `_ is fretless, allowing +the quarter-tone inflections essential to +`maqam `_ performance. The +`sitar `_ has moveable frets and +sympathetic strings that resonate in harmony with the played notes. + +Keyboards +--------- .. code-block:: python - violin = Fretboard.violin() # E5 A4 D4 G3 — soprano - viola = Fretboard.viola() # A4 D4 G3 C3 — alto (5th below violin) - cello = Fretboard.cello() # A3 D3 G2 C2 — tenor/bass (octave below viola) + Fretboard.keyboard() # 88-key piano (A0 to C8) + Fretboard.keyboard(61, "C2") # 61-key synth controller + Fretboard.keyboard(49, "C2") # 49-key controller + Fretboard.keyboard(25, "C3") # 25-key mini MIDI controller -Unlike fretted instruments, bowed strings have no frets — the player -can produce any pitch along the fingerboard, enabling vibrato and -microtonal inflections. - -Other String Instruments ------------------------- - -.. code-block:: python - - mandolin = Fretboard.mandolin() # E5 A4 D4 G3 (violin tuning) - banjo = Fretboard.banjo() # Open G (with high drone string) - banjo_d = Fretboard.banjo("open d") # Open D (clawhammer) - twelve = Fretboard.twelve_string() # 12 strings (6 doubled courses) - -Custom Instruments ------------------- - -Any stringed instrument can be modeled: - -.. code-block:: python - - from pytheory import Tone, Fretboard - - # Mandola (octave below mandolin, like viola to violin) - mandola = Fretboard(tones=[ - Tone.from_string("E4"), - Tone.from_string("A3"), - Tone.from_string("D3"), - Tone.from_string("G2"), - ]) - - # Baritone ukulele (DGBE — like the top 4 guitar strings) - bari_uke = Fretboard(tones=[ - Tone.from_string("E4"), - Tone.from_string("B3"), - Tone.from_string("G3"), - Tone.from_string("D3"), - ]) - - # Double bass / upright bass - upright = Fretboard(tones=[ - Tone.from_string("G2"), - Tone.from_string("D2"), - Tone.from_string("A1"), - Tone.from_string("E1"), - ]) +While keyboards don't have strings or frets, they map naturally to a +sequence of tones. A full 88-key piano spans over 7 octaves — the +widest range of any standard acoustic instrument. Getting Fingerings ------------------ -The fingering algorithm finds the most playable voicing for any chord on -any fretboard. It scores each possibility by: +The fingering algorithm finds the most playable voicing for any chord +on any instrument. It scores each possibility by: 1. Preferring **open strings** (fret 0) — they ring freely 2. Preferring **ascending** fret patterns — easier hand position @@ -149,7 +182,6 @@ any fretboard. It scores each possibility by: # Best single fingering print(c.fingering(fretboard=fb)) # (0, 1, 0, 2, 3, 0) - # String: E4=0 B3=1 G3=0 D3=2 A2=3 E2=0 # All equally-scored fingerings all_c = c.fingering(fretboard=fb, multiple=True) @@ -188,11 +220,30 @@ Generate fingerings for every chord at once: for name, fingering in chart.items(): print(f"{name:6s} {fingering}") -`Ukulele `_ Example ---------------- + # Works with any instrument + uke_chart = charts_for_fretboard(fretboard=Fretboard.ukulele()) + mando_chart = charts_for_fretboard(fretboard=Fretboard.mandolin()) + +Custom Instruments +------------------ + +Any instrument can be modeled with custom string tunings: .. code-block:: python - fb = Fretboard.ukulele() - c = CHARTS["western"]["C"] - print(c.fingering(fretboard=fb)) # 4-string fingering + from pytheory import Tone, Fretboard + + # Baritone ukulele (DGBE — top 4 guitar strings) + bari_uke = Fretboard(tones=[ + Tone.from_string("E4"), + Tone.from_string("B3"), + Tone.from_string("G3"), + Tone.from_string("D3"), + ]) + + # Tres cubano (Cuban guitar, 3 doubled courses) + tres = Fretboard(tones=[ + Tone.from_string("E4"), + Tone.from_string("B3"), + Tone.from_string("G3"), + ])