Instruments and 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 It Works ------------ 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. Guitars ------- `Standard guitar tuning `_:: String 6: E2 (lowest) String 5: A2 String 4: D3 String 3: G3 String 2: B3 String 1: E4 (highest) 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). .. note:: Since **v0.43.0**, fingerings and string lists read **low to high** (lowest-pitched string first) by default — matching how chord diagrams and tab are conventionally written. To get the pre-0.43 high-to-low order, pass ``high_to_low=True`` to any fretboard constructor, e.g. ``Fretboard.guitar(high_to_low=True)``. A custom tuning tuple and manual ``fingering()`` positions are likewise read in the board's orientation. .. code-block:: pycon >>> from pytheory import Fretboard >>> 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 **Alternate tunings** — 8 built-in presets: .. code-block:: pycon >>> 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 >>> Fretboard.guitar(("C4", "G3", "C3", "G2", "C2", "G1")) **Capo** — a `capo `_ raises all strings by a number of frets, letting you play open chord shapes in higher keys: .. code-block:: pycon >>> # Capo on fret 2 — open G shape now sounds as A major >>> fb = Fretboard.guitar(capo=2) >>> # Or apply a capo to an existing fretboard >>> fb = Fretboard.guitar() >>> fb_capo3 = fb.capo(3) 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:: pycon >>> 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:: pycon >>> 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:: pycon >>> Fretboard.erhu() # A4 D4 — tuned a 5th apart, no fingerboard Plucked Strings --------------- .. code-block:: pycon >>> 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 ----------------- .. code-block:: pycon >>> # 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:: pycon >>> 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 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 instrument. It scores each possibility by: 1. Preferring **open strings** (fret 0) — they ring freely 2. Preferring **ascending** fret patterns — easier hand position 3. Minimizing the number of **fingers needed** .. code-block:: pycon >>> from pytheory import Fretboard >>> fb = Fretboard.guitar() >>> f = fb.chord("C") >>> f Fingering(E=x, A=3, D=2, G=0, B=1, e=0) >>> f['A'] 3 >>> f[1] 3 >>> f.identify() 'C major' >>> chord = f.to_chord() >>> chord.identify() 'C major' You can also go from fret positions to chord identification: .. code-block:: pycon >>> # "What chord am I playing?" (positions read low to high) >>> fb = Fretboard.guitar() >>> f = fb.fingering(0, 2, 2, 0, 0, 0) >>> f Fingering(E=0, A=2, D=2, G=0, B=0, e=0) >>> f.identify() 'E minor' Reading Fingerings ~~~~~~~~~~~~~~~~~~ Each position is labeled with its string name. Duplicate string names are disambiguated — on a standard guitar, high E appears as ``e`` and low E as ``E``. Strings read low to high (lowest first):: E|--x-- (muted — low E) A|--3-- (fret 3 — C) D|--2-- (fret 2 — E) G|--0-- (open — G) B|--1-- (fret 1 — C) e|--0-- (open — high E) A value of ``x`` (``None``) means the string is muted (not played). ASCII Tablature ~~~~~~~~~~~~~~~ For a more visual representation, use ``tab()``: .. code-block:: pycon >>> print(fb.tab("C")) C major E|--x-- A|--3-- D|--2-- G|--0-- B|--1-- e|--0-- Generating Full Charts ---------------------- Generate fingerings for every chord at once: .. code-block:: pycon >>> fb = Fretboard.guitar() >>> chart = fb.chart() >>> chart["C"] Fingering(E=x, A=3, D=2, G=0, B=1, e=0) >>> # Works with any instrument >>> uke_chart = Fretboard.ukulele().chart() >>> mando_chart = Fretboard.mandolin().chart() Scale Diagrams with Chord Highlighting --------------------------------------- The ``scale_diagram()`` method renders an ASCII fretboard showing where scale notes fall on each string. Pass an optional ``chord`` argument to highlight chord tones in UPPERCASE while scale-only tones appear in lowercase — a quick way to visualize target notes for soloing: .. code-block:: pycon >>> from pytheory import Fretboard, TonedScale, Chord >>> fb = Fretboard.guitar() >>> pentatonic = TonedScale(tonic="A4")["minor pentatonic"] >>> print(fb.scale_diagram(pentatonic, frets=5)) >>> # Highlight Am chord tones within the scale: >>> am = Chord.from_symbol("Am") >>> print(fb.scale_diagram(pentatonic, frets=5, chord=am)) Non-String Instruments ---------------------- Looking for drums and percussion? PyTheory also supports drum pattern programming through the sequencing engine. See the :doc:`drums` guide for drum kits, patterns, and fills. Custom Instruments ------------------ Any instrument can be modeled with custom string tunings: .. code-block:: pycon >>> from pytheory import Tone, Fretboard >>> # Baritone ukulele (DGBE — top 4 guitar strings, low to high) >>> bari_uke = Fretboard(tones=[ ... Tone.from_string("D3"), ... Tone.from_string("G3"), ... Tone.from_string("B3"), ... Tone.from_string("E4"), ... ]) >>> # Tres cubano (Cuban guitar, 3 doubled courses, low to high) >>> tres = Fretboard(tones=[ ... Tone.from_string("G3"), ... Tone.from_string("B3"), ... Tone.from_string("E4"), ... ]) If it has strings, you can model it. Define the tuning, and PyTheory handles the rest -- fingerings, charts, scale diagrams, all of it. Got a weird instrument or a custom tuning? That's what the ``Fretboard`` constructor is for.