Glorious Voice Leader, my chord-obsessed side project, now has the ability to turn a collection of notes played on the guitar fretboard into a list of possible chord names. Deciding on a specific chord name is still a very human, very context dependent task, but we can let the computer do a lot of the heavy lifting for us.

I’ve included a simplified version of this chord namer to the left. Feel free to click on the frets to enter any guitar chord you’d like the name of. Glorious Voice Leader will crunch the numbers and come up with a list of possible names that exactly describes the chord you’ve entered, sorted alphabetically.

In the full-fledged Glorious Voice Leader application, this functionality is accessible by simply clicking on the fretboard without first selecting the name of the chord you want. This felt like an intuitive design decision. You might know the shape of a specific chord you want to play in a progression, but you’re not sure of its name.

Enter it into the fretboard and Glorious Voice Leader will give you a corresponding list of names. When you click on one of those names, it’ll automatically suggest alternative voicings that voice lead smoothly from the previous chord.

The actual code behind this feature is dead simple. We simply filter over our set of all possible chord roots and qualities, and compare the set of notes in each resulting chord with the set of notes entered by the user:


let possibleNames = _.chain(qualities)
  .flatMap(quality =>
    _.map(Object.keys(roots), root => {
      return {
        root,
        quality
      };
    })
  )
  .filter(({ root, quality }) => {
    if (_.isEmpty(chord.notes)) {
      return false;
    }
    let chordNotes = _.chain(chord.notes)
      .map(([string, fret]) => (tuning[string] + fret) % 12)
      .uniq()
      .sortBy(_.identity)
      .value();
    let qualityNotes = _.chain(quality.quality)
      .map(note => (roots[root] + note) % 12)
      .sortBy(_.identity)
      .value();
    return _.isEqual(chordNotes, qualityNotes);
  })
  .map(({ root, quality }) => {
    return `${root}${quality.name}`;
  })
  .sortBy(_.identity)
  .value();

From there we simply present the list of possible chord names to the user in some meaningful or actionable way.

For future work, it would be nice to sort the list of name suggestions in order of the lowest notes they entered on the fretboard. For example, if they entered the notes C, E, G, and B in ascending order, we should sort the Cmaj7 suggestion before the Am9 no 1 suggestion. As with all of the items on my future work list, there are many subtitles and nuances here that would have to be addressed before it becomes a reality.

I hope you find this helpful. If you find Glorious Voice Leader interesting or useful in any way, please let me know!