chord-fingering
A CommonJS module for generating chord fingerings for any tuning. Chords can be found by their symbols in the Anglophone alphabetic musical notation.
The package has been developed for the Chordline app. This project uses and is inspired by tonaljs, a music theory library. The data powering the project comprises 111 unique chord patterns.
Installation
npm i chord-fingering
Basic usage
import { findGuitarChord } from 'chord-fingering';
let chord = findGuitarChord('C');
console.log(chord.fingerings[0].positionString); // => 'x32010'
For more in-depth examples see API.
Table of contents
chord-fingering
Installation
Usage
API
findGuitarChord
findChord
findFingerings
parseTuning
detectBarre
findPositions
getNoteValue
getNoteAbove
findFret
Development
Data
API
Typical usage will be limited to findGuitarChord
, findChord
, or findFingerings
functions, but other exposed functions are listed below as well.
findGuitarChord(symbol, [tuning]) ⇒ object
Find intervals, corresponding notes, and possible fingerings for a given chord symbol and tuning.
Returns: object
- Chord data in format { symbol, intervals, optionalIntervals, requiredIntervals, tonic, notes, optionalNotes, requiredNotes, bass, description, fullName, fingerings }
.
Fingerings are in format { positions: [ { stringIndex: Number, fret: Number, note: String } ] }
, with muted strings omitted.
Param | Type | Description |
---|---|---|
symbol | string |
Chord symbol, e.g. 'C' , 'Dm' , 'Ebmaj7' , 'C#11b13' . |
[tuning] |
string | Array<string>
|
Array or hyphen-delimited list of notes of the tuning from the lowest (thickest string). Can include octave number after the note. E.g. 'E2-A2-D3-G3-B3-E4' or ['D','A','D','F#','A','D'] . Without octaves, starts from octave 2 . |
Internally calls findChord
and findFingerings
to return a merged chord object with fingerings.
// ESnext
import { findGuitarChord } from 'chord-fingering';
// CommonJS
const findGuitarChord = require('chord-fingering').findGuitarChord;
let chord = findGuitarChord('C');
Result
{
input: "C",
symbol: "C",
symbols: [ "" ],
altSymbols: [],
intervals: [ "1P", "3M", "5P" ],
optionalIntervals: [],
requiredIntervals: [ "1P", "3M", "5P" ],
tonic: "C",
notes: [ "C", "E", "G" ],
optionalNotes: [],
requiredNotes: [ "C", "E", "G" ],
bass: "C",
description: "major",
fingerings: [
{
positions: [
{ stringNote: "A2", stringIndex: 1, fret: 3, note: "C3" },
{ stringNote: "D3", stringIndex: 2, fret: 2, note: "E3" },
{ stringNote: "G3", stringIndex: 3, fret: 0, note: "G3" },
{ stringNote: "B3", stringIndex: 4, fret: 1, note: "C4" },
{ stringNote: "E4", stringIndex: 5, fret: 0, note: "E4" }
],
barre: null,
positionString: "x32010",
difficulty: 4.55
}, {
positions: [
{ stringNote: "A2", stringIndex: 1, fret: 3, note: "C3" },
{ stringNote: "D3", stringIndex: 2, fret: 5, note: "G3" },
{ stringNote: "G3", stringIndex: 3, fret: 5, note: "C4" },
{ stringNote: "B3", stringIndex: 4, fret: 5, note: "E4" },
{ stringNote: "E4", stringIndex: 5, fret: 3, note: "G4" }
],
barre: { fret: 3, stringIndices: [ 1, 5 ] },
positionString: "x35553",
difficulty: 12.13
}, {
positions: [
{ stringNote: "E2", stringIndex: 0, fret: 8, note: "C3" },
{ stringNote: "A2", stringIndex: 1, fret: 10, note: "G3" },
{ stringNote: "D3", stringIndex: 2, fret: 10, note: "C4" },
{ stringNote: "G3", stringIndex: 3, fret: 9, note: "E4" },
{ stringNote: "B3", stringIndex: 4, fret: 8, note: "G4" },
{ stringNote: "E4", stringIndex: 5, fret: 8, note: "C5" }
],
barre: { fret: 8, stringIndices: [ 0, 4, 5 ] },
positionString: "8-10-10-9-8-8",
difficulty: 9.84
},
// ... 15 more
]
}
findChord(symbol) ⇒ object
Find intervals and corresponding notes for a given chord symbol.
Returns: object
- Chord data in format { symbol, intervals, optionalIntervals, requiredIntervals, tonic, notes, optionalNotes, requiredNotes, bass, description }
.
Param | Type | Description |
---|---|---|
symbol | string |
Chord symbol, e.g. 'C' , 'Dm' , 'Ebmaj7' , 'C#11b13' . |
// ESnext
import { findChord } from 'chord-fingering';
// CommonJS
const findChord = require('chord-fingering').findChord;
let chord1 = findChord('C');
let chord2 = findChord('Amaj7');
let chord3 = findChord('D#sus4');
let chord4 = findChord('Fdim');
let chord5 = findChord('Gbadd11');
chord1:
chord1:
{
input: "C",
symbol: "C",
symbols: [ "" ],
altSymbols: [],
intervals: [ "1P", "3M", "5P" ],
optionalIntervals: [],
requiredIntervals: [ "1P", "3M", "5P" ],
tonic: "C",
notes: [ "C", "E", "G" ],
optionalNotes: [],
requiredNotes: [ "C", "E", "G" ],
bass: "C",
description: "major"
}
chord5:
chord5:
{
input: "Gbadd11",
symbol: "Gbadd4",
symbols: [ "add4", "add11" ],
altSymbols: [],
intervals: [ "1P", "3M", "4P", "5P" ],
optionalIntervals: [],
requiredIntervals: [ "1P", "3M", "4P", "5P" ],
tonic: "Gb",
notes: [ "Gb", "Bb", "Cb", "Db" ],
optionalNotes: [],
requiredNotes: [ "Gb", "Bb", "Cb", "Db" ],
bass: "Gb",
description: ""
}
findFingerings(notes, [optionalNotes], [bass], [tuning]) ⇒ object
Return all positions within the first octave on the fretboard where a set of notes can be played in a given tuning.
Returns: object
- Fingerings in format { positions: [ { stringIndex: Number, fret: Number, note: String } ] }
.
Muted strings are omitted.
Param | Type | Default | Description |
---|---|---|---|
notes | Array<string> |
Notes to be played, e.g. ['E', 'G#', 'B', 'D#'] . |
|
[optionalNotes] | Array<string> |
Notes that can be omitted for ease of playing, typically the fifth in an extended chord. | |
[bass] | string |
The lowest note in the chord, if other than the first of notes (typically for chord inversions). |
|
[tuning] |
string | Array<string>
|
"E-A-D-G-B-E" |
Array or hyphen-delimited list of notes of the tuning from the lowest (thickest string). Can include octave number after the note. E.g. 'E2-A2-D3-G3-B3-E4' or ['D','A','D','F#','A','D'] . Without octaves, starts from octave 2 . |
// ESnext
import { findFingerings } from 'chord-fingering';
// CommonJS
const findFingerings = require('chord-fingering').findFingerings;
const notes = ['E', 'G#', 'B', 'F'], optionalNotes = [];
const fingerings = findFingerings(notes, optionalNotes);
fingerings:
fingerings:
[
{ positions: [ { stringNote: "E2", stringIndex: 0, fret: 0, note: "E2" },
{ stringNote: "A2", stringIndex: 1, fret: 2, note: "B2" },
{ stringNote: "D3", stringIndex: 2, fret: 2, note: "E3" },
{ stringNote: "G3", stringIndex: 3, fret: 1, note: "G#3" },
{ stringNote: "B3", stringIndex: 4, fret: 0, note: "B3" },
{ stringNote: "E4", stringIndex: 5, fret: 1, note: "F4" }
],
barre: null,
positionString: "022101",
difficulty: 3.9
}, { positions: [ { stringNote: "E2", stringIndex: 0, fret: 0, note: "E2" },
{ stringNote: "A2", stringIndex: 1, fret: 2, note: "B2" },
{ stringNote: "D3", stringIndex: 2, fret: 3, note: "F3" },
{ stringNote: "G3", stringIndex: 3, fret: 1, note: "G#3" },
{ stringNote: "B3", stringIndex: 4, fret: 0, note: "B3" },
{ stringNote: "E4", stringIndex: 5, fret: 0, note: "E4" }
],
barre: null,
positionString: "023100",
difficulty: 8.75
}, { positions: [ { stringNote: "E2", stringIndex: 0, fret: 0, note: "E2" },
{ stringNote: "A2", stringIndex: 1, fret: 2, note: "B2" },
{ stringNote: "D3", stringIndex: 2, fret: 3, note: "F3" },
{ stringNote: "G3", stringIndex: 3, fret: 1, note: "G#3" },
{ stringNote: "B3", stringIndex: 4, fret: 0, note: "B3" },
{ stringNote: "E4", stringIndex: 5, fret: 1, note: "F4" }
],
barre: null,
positionString: "023101",
difficulty: 11.75
}, { positions: [ { stringNote: "E2", stringIndex: 0, fret: 0, note: "E2" },
{ stringNote: "A2", stringIndex: 1, fret: 8, note: "F3" },
{ stringNote: "D3", stringIndex: 2, fret: 9, note: "B3" },
{ stringNote: "G3", stringIndex: 3, fret: 10, note: "F4" },
{ stringNote: "B3", stringIndex: 4, fret: 9, note: "G#4" },
{ stringNote: "E4", stringIndex: 5, fret: 0, note: "E4" }
],
barre: null,
positionString: "0-8-9-10-9-0",
difficulty: 7.19
}, { positions: [ { stringNote: "E2", stringIndex: 0, fret: 0, note: "E2" },
{ stringNote: "A2", stringIndex: 1, fret: 7, note: "E3" },
{ stringNote: "D3", stringIndex: 2, fret: 9, note: "B3" },
{ stringNote: "G3", stringIndex: 3, fret: 10, note: "F4" },
{ stringNote: "B3", stringIndex: 4, fret: 9, note: "G#4" },
{ stringNote: "E4", stringIndex: 5, fret: 0, note: "E4" }
],
barre: null,
positionString: "0-7-9-10-9-0",
difficulty: 10.22
}, { positions: [ { stringNote: "E2", stringIndex: 0, fret: 0, note: "E2" },
{ stringNote: "A2", stringIndex: 1, fret: 11, note: "G#3" },
{ stringNote: "D3", stringIndex: 2, fret: 9, note: "B3" },
{ stringNote: "G3", stringIndex: 3, fret: 10, note: "F4" },
{ stringNote: "B3", stringIndex: 4, fret: 9, note: "G#4" },
{ stringNote: "E4", stringIndex: 5, fret: 0, note: "E4" }
],
barre: null,
positionString: "0-11-9-10-9-0",
difficulty: 9.56
}, { positions: [ { stringNote: "D3", stringIndex: 2, fret: 2, note: "E3" },
{ stringNote: "G3", stringIndex: 3, fret: 1, note: "G#3" },
{ stringNote: "B3", stringIndex: 4, fret: 0, note: "B3" },
{ stringNote: "E4", stringIndex: 5, fret: 1, note: "F4" }
],
barre: null,
positionString: "xx2101",
difficulty: 0.9
}, { positions: [ { stringNote: "A2", stringIndex: 1, fret: 7, note: "E3" },
{ stringNote: "D3", stringIndex: 2, fret: 9, note: "B3" },
{ stringNote: "G3", stringIndex: 3, fret: 10, note: "F4" },
{ stringNote: "B3", stringIndex: 4, fret: 9, note: "G#4" },
{ stringNote: "E4", stringIndex: 5, fret: 0, note: "E4" }
],
barre: null,
positionString: "x-7-9-10-9-0",
difficulty: 10.22
},
// ...15 more
]
parseTuning(arg) ⇒ Array<string>
Deduces tuning from a string.
Returns: Array<string>
- Array of note pitches (with octave numbers) comprising the tuning, e.g. ['D2','A2','D3','F#3','A3','D4']
.
Param | Type | Description |
---|---|---|
arg |
string | Array<string>
|
Array or hyphen-delimited list of notes of the tuning from the lowest (thickest string). Can include octave number after the note. E.g. 'E-A-D-G-B-e' , 'E2-A2-D3-G3-B3-E4' or ['D','A','D','F#','A','D'] . By default, starts from octave 2 . |
detectBarre(positions, [stringCount]) ⇒ object
Detect barre in a fingering.
Returns: object
- Barre in format { stringIndices: Number[], fret: Number } ] }
or null
.
Param | Type | Description |
---|---|---|
positions | Array<object> |
Fingering in format [ { stringIndex: Number, fret: Number } ] . |
positions[].stringIndex | number |
Zero-based index of the guitar string, starting from lowest (thickest). |
positions[].fret | number |
Zero-based index of the guitar fret. |
[stringCount] | number |
Number of the instrument's strings, defaults to 6 . |
findPositions(notes, [tuning]) ⇒ Array<Object>
Return all positions within the first octave on the fretboard where a set of notes can be played in a given tuning.
Returns: Array<Object>
- Positions in format { stringIndex: Number, fret: Number, note: String }
.
Param | Type | Default | Description |
---|---|---|---|
notes | Array<String> |
Notes to be played, e.g. ['E', 'G#', 'B', 'D#'] . |
|
[tuning] |
string | Array<string>
|
"E-A-D-G-B-E" |
Array or hyphen-delimited list of notes of the tuning from the lowest (thickest string). Can include octave number after the note. E.g. 'E2-A2-D3-G3-B3-E4' or ['D','A','D','F#','A','D'] . Without octaves, starts from octave 2 . |
getNoteValue(note)
Return note stripped of octave number, e.g. 'C'
.
Param | Type | Description |
---|---|---|
note | String |
Note with optional octave number, e.g. 'C5' . |
getNoteAbove(note, baseNote) ⇒
Given two notes, returns the first note with octave number such that it is the lowest note higher or equal than the second.
Returns: First note with octave number, e.g. ('D', 'G3') => 'D4'
Param | Type | Description |
---|---|---|
note | string |
Note, with or without octave number, e.g. 'D'
|
baseNote | string |
Base note with octave, e.g. 'G3'
|
findFret(note, stringNote) ⇒ Number
Find the fret number within the first octave on the fretboard where a note can be played on a given string.
Returns: Number
- Number of semitones (fret number), e.g. 4
.
Param | Type | Description |
---|---|---|
note | String |
Higher note (note to be played), e.g. 'G#' . |
stringNote | String |
Lower note (note of the string), e.g. 'E' . |
Development
Currently there is no build process. The project is structured as a CommonJS module, so it can be used in Node as well as with Webpack.
Testing:
npm run test
Data
Each of the 111 chord types is defined by its intervals, some of which may be considered optional for the purpose of deriving a guitar fingering of the chord. The chord type can have one or more symbol aliases.
Each entry is an array of five strings (for convenience and avoiding redundance), but this representation is normalized upon export into an object of the following properties:
{
intervals: [ "1P", "3M", "5P", "6M" ], // all intervals comprising the chord (tonic, major third, perfect fifth, major sixth)
optionalIntervals: [ "5P" ], // intervals that can be arbitrarily omitted for ease of playing
symbols: [ "6", "add6", "add13" ], // aliases parsed by UltimateGuitar.com
altSymbols: [ "M6" ], // other aliases
description: "sixth" // verbal description of the chord type
}
Some of the entries contained in the dataset have no known symbols honored by UltimateGuitar.com, but such symbols might exist.