npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

chord-fingering

v1.0.2

Published

Calculate possible fingerings for a given chord and string tuning.

Downloads

35

Readme

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');
{
  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.