Skip to content

Calculate possible fingerings for a given chord and string tuning.

License

Notifications You must be signed in to change notification settings

hyvyys/chord-fingering

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

npm

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:

{
  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:

{
  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:

[
  { 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.

About

Calculate possible fingerings for a given chord and string tuning.

Resources

License

Stars

Watchers

Forks

Packages

No packages published