Help with a JavaScipt project (knowledge of music theory and/or guitar is helpful)

Project name: Guitar Chord Names

Goal: I want the user to enter the fret numbers for a guitar chord, and after hitting a Submit button, return the name of the chord. I want to more than only that, but that is where I want to start.

Problem: I want to reduce the number of variables to do the job.

I have a variable with the chromatic scale notes for the strings of a guitar: E, A, D, G, B, E. I also have a variable listing the 12 possible notes in Western music called the chromatic scale. If you know music theory, I am only going to use sharps for now.

I do not want to have a variable with the chromatic scale notes for each string. I would like to use use the string note to cycle through the chromatic scale notes. For example, a note on the 4th fret of the 6th tring of a guitar (the E string) is a G sharp (G#). If a user enters the number 4 for the 6th string input, I want to convert that to the note G# and save it.

Here is where I am confused about what to do. After getting the value of the input, I want to cycle through the chromatic scale variable, starting on the string note (E in this case), and count up until I find the chromatic note value that corresponds to the fret number entered. Or is it easier to have an array of chromatic note values for each string? Am I going about this the wrong way?

// Standard tuning open string note values
const standardTuning = ["E", "A", "D", "G", "B", "E"];

// The chromatic scale using sharps
const chromaticSharps = ["A", "A♯", "B", "C", "C♯", "D", "D♯", "E", "F", "F♯", "G", "G♯"];

How do I loop through the array chromaticSharps , starting on E and counting up to find G#? E has an index of 7 in the array, but I will need it to be “reset” to 0 so that G# has an index (in relation to E) of 4. And the 4th fret on the E string is G#.

I’d prefer to do that rather than creating 5 array variables for each unique string, each having 12 values. Right now, the variable chromaticSharps would be perfect for the A string. I would have to repeat that pattern starting on E for the E strings, D for the D string, etc.

If you do know music theory, then you know that I will have to incorporate the flat notes for flat keys. Right now, I just want to focus on chords that can be built from the major scale.

I don’t think you would need a loop, I would think you would need to find the string name in the chromatic scale and add the fret to it.

so you get G# by doing something like chromaticSharps[indexOf E + fretNumber]

Ok, I can see how that will work. Let me get to work on that - thanks!

Actually, indexOf returns the index of the value passed to it. I need the opposite: to return the value after passing the index number. I think I just need to create a variable for each string:

// The chromatic scale by string
const stringE = ["E", "F", "F♯", "G", "G♯", "A", "A♯", "B", "C", "C♯", "D", "D♯"];
const stringA = ["A", "A♯", "B", "C", "C♯", "D", "D♯", "E", "F", "F♯", "G", "G♯"];
const stringD = ["D", "D♯", "E", "F", "F♯", "G", "G♯", "A", "A♯", "B", "C", "C♯"];
const stringG = ["G", "G♯", "A", "A♯", "B", "C", "C♯", "D", "D♯", "E", "F", "F♯"];
const stringB = ["B", "C", "C♯", "D", "D♯", "E", "F", "F♯", "G", "G♯", "A", "A♯"];

console.log(stringE[4]); // logs G♯ 

that is just how you access an array, that’s why I said

you actually don’t need to create different arrays, just need to use the % operator

I tried that but you need to pass in the value for indexOf, not an index number. I had to pass in G#.

However, the complexity of what I have to do is immense. I’m thinking I either need a large JSON file or create an API, which I do not know how to do. As I’m trying to think about how to do this, I keep encountering situations where I have a lot of conditionals, a lot of potential if statements. For every guitar fret number entered by the user I have to:

  1. Treat it as a potential root note for the chord and then
  2. Determine what interval type the other user-supplied notes are in relation to the note being checked
  3. Then for each note, I have to check for the quality of the 3rd (major or minor) which will determine whether the chord is a major, minor, diminished, or augmented triad. But…
  4. I need to see if a fifth is present and determine and if so whether it is perfect, diminished, or augmented before knowing the overall quality of the chord (major, minor, diminished, or augmented)
  5. For completeness, if there is no major or minor 3rd present then I need to see if there is a perfect 4th or major 2nd ALONG with a perfect 5th because that would be a sus2 or sus4 chord.
  6. Then after determining the triad or sus chord quality, I have to look at the remaining notes (if any) to come up with the chord name. And there are plenty of chords that equal each other (C6 = Am7).
  7. On top of that, are the 5 chromatic notes that can be either flat or sharp. For example, there is a Gb major key, but there is not an A# major key even though Gb and A# are the same note. And although A# is not a major scale key, there are A# chords in B major and F# major.

And that is what I will have to do with any and all chords types that can be built from all the major scale keys. But there are other chords that can only be created from other scales. I only use 5 other scales: Harmonic Minor, Melodic Minor, Whole Tone, Augmented, and Diminshed.

And at the end of it all, every chord name is built from specific intervals. So not only do I have to have a list of all potential chord names, but I also have to have all the intervals that build each of those chord names.

Throw into the mix enharmonic equivalents, where a #9 and a b3 are the same note, or “odd” notes like the perfect 4th in G major is a Cb, otherwise known as B.

I originally built a spreadsheet to create all possible chord names for any note and the notes in that chord. That spreadsheet has a lot of tabs, but I really only need 2 tabs: 1) that has the notes values for all intervals for every chromatic note, 2) the tab that uses VLOOKUP to grab the notes values for every chord name.

Those tabs are basically tables - rows and columns with values - two tables. What are APIs? Why do mostly all of them return the data as JSON files? I think the answer is because there is a lot of data that is or can be arranged into rows and columns that contain the values.

I would like to think that logic could reproduce what an API/JSON file provides, but it would probably a huge amount of code to do that.