Developing a JavaScript guitar chord diagramming app using p5.js

part 1

Here is my process for developing a guitar chord diagramming app, from drawing the initial sketch using the p5.js library to enabling CRUD operations for other users to be able to create and save their own guitar chord voicings and progressions.

Background

A short time before my daughter was born, I took a one-off lesson with jazz guitar legend Pat Martino, who was at home in South Philadelphia between tours. It was my birthday, and my wife said, “We will never have money again after the baby is born.” How right she was. It was good value, though, because four years later, I’m still trying to figure out what he taught me.

I always say it was like meeting Gandalf, but maybe that is disrespectful to say. Pat was a very kind and patient teacher, and he took me seriously and wanted to share his knowledge of the guitar, which is vast and philosophical. I remember he also showed me some new gear he had just received, a reverb device the size of a toaster oven that made his guitar sound like storm clouds over the ocean.

One of the things I continue to study from Pat’s lesson book Fundamentals of Guitar is how chords are related by augmented parental forms and what that means in practical terms of smooth voice leading from one to the next. I thought an app might help me understand that concept better, especially with these lovely open sounding inversions.

The project code

The p5.js library provides an easy-to-use sandbox environment and some custom functions to make programming for web apps more approachable for artists, musicians, teachers and others.

In this first draft, I just want to draw one guitar chord diagram nicely, using a Mel Bay chord book as a model. Note the use of for loops to draw lines and iterate through an array. The next step will be to construct a class and instantiate additional chord objects.

/* first, initiate global variables
    so they will be accessible within
    the setup() and draw() functions
*/
let root;
let third;
let fifth;
let mute;

function setup() {
  createCanvas(106, 145);
  /* next, add data in setup() function,
    key value pairs within curly braces
    creates an easily readable set of
    variables accessible by dot
    and bracket notation
*/

  fifth = {
    note: "G",
    x: 10,
    y: 85,
  };
  root = {
    note: "C",
    x: 64,
    y: 133,
  };
  third = {
    note: "E",
    x: 46,
    y: 61,
  };
  /* also input values for the fingering pattern
    above the nut here. But this seems cumbersome to input.
    Maybe a function should calculate this instead?
*/
  mute = ["o", "x", "o", "o", "x", "x"];
}

function draw() {
  // print chord name centered
  textSize(12);
  textAlign(CENTER, BASELINE);
  fill("black");
  text("C 2nd Inv", width / 2, 13);
  // print fingering above nut, 18px apart, same as strings
  for (let i = 0, x = 10; i < mute.length, x < width; i += 1, x += 18) {
    textSize(9);
    textAlign(CENTER, BASELINE);
    text(mute[i], x, 21);
  }
  /* print left-hand position
    here it is at the nut, so position "1"
  */
  textSize(9);
  textAlign(LEFT, BASELINE);
  text("1", 0, 30);

  //draw nut with a thicker line and square caps
  strokeCap(SQUARE);
  strokeWeight(4);
  line(9, 24, 100, 24);

  //draw frets 24 px apart
  for (let y = 48; y < 145; y += 24) {
    strokeWeight(1);
    line(10, y, 100, y);
  }

  /* draw strings 18 px apart without exceeding the
      width of the canvas, starting at 10 to allow
      for left-hand position label number in the margin
  */
  for (let x = 10; x < width; x += 18) {
    strokeWeight(1);
    line(x, 24, x, 144);
  }
  /* draw a black dot with note letter name inside.
   Trial & error results in a 14px ellipse and size 12 text
   seems comfortably readable to me
   add +1 to y value of text to make it appear centered.
   
   */

  fill("black");
  ellipse(root.x, root.y, 14, 14);
  fill("white");
  textSize(12);
  textAlign(CENTER, CENTER);
  text(root.note, root.x, root.y + 1);

  fill("black");
  ellipse(third.x, third.y, 14, 14);
  fill("white");

  text(third.note, third.x, third.y + 1);

  fill("black");
  ellipse(fifth.x, fifth.y, 14, 14);
  fill("white");

  text(fifth.note, fifth.x, fifth.y + 1);
}

Be sure to look for Part 2 in which I turn into a werewolf and convert this simple sketch into slaughterhouse of JavaScript classes and objects.

By Chris Mohnacky.

Comments

2 responses to “Developing a JavaScript guitar chord diagramming app using p5.js”

  1. kinderslaapkamer Avatar

    I have tried almost all free chord plugin and this one is by far the best I have used. Feature rich and super easy to use and customize. If transposing on the fly is implemented this will be a killer ??

    Liked by 1 person

    1. Chris Mohnacky Avatar

      Hey, thanks for stopping by. I don’t know about any plugins for guitar chords. You could share some links if you wanted. I’m seeing this as more of a study tool for arranging rather than something that will transpose on the fly, but definitely want to allow users to add new chords, drag and drop, save progressions, and so on. Probably a few articles down the road when I get to the database part.

      Liked by 1 person

Leave a comment