I’ve been getting a lot of feedback from people wanting to see variations on chords or wanting to modify which chords are displayed, so I thought I would take a break and talk about how the chord selection process currently works in the widget. First of all, the entire chord calculation is done mathematically. There are no data files with lists of chords in them. It’s all calculated on the fly. This is essential in order to support the ability to change the tuning of each guitar string. So there are no master files you can manipulate by hand, so you’ll have to bear with me while I walk you through what happens.
First, the code looks at the fretboard layout and determines the lowest visible fret on-screen. Initially, this is an open string, but as you scroll up the neck it could be the 3rd fret, the 5th fret, or the 12th fret.
Once the code has determined the lowest fret shown, then it calculates five different sets of test ranges used to evaluate fingerings. The first set is a four fret range starting from the lowest fret shown. This set also allows open strings as a possibility. The remaining four sets are barre chord ranges for each of the four frets listed in the first range. However, since they are barre chords their fret range is limited to two frets. Confused yet? Here’s an example. Say the lowest fret shown was the 5th fret, then the ranges considered would be:
- frets 5,6,7,8, and open strings
- frets 6,7 with a barre on the 5th fret
- frets 7,8 with a barre on the 6th fret
- frets 8,9 with a barre on the 7th fret
- frets 9,10 with a barre on the 8th fret
Once the ranges have been determined, the code starts with the bass string and looks through the fret range to see if any of the notes match the root of the chord. The algorithm insists that the root of the chord be the lowest note played. So it automatically eliminates options like a simple D major with a F# bass note.
Once the code find a string containing the root of the chord, it starts looking for strings that contain ANY note in the chord, and records all frets that satisfy this test. After this step, the code has created an array of six elements, one for each string. Each element might contain a -1, meaning no possible note found, or it could contain a single digit meaning only one note was found, or it could contain an array of numbers for all the fret options on that string. For example, if you looked for a C major chord with a lowest visible fret of 5, then the five ranges would look like this:
[8,7,5,[0,5],[5,8],[0,8]]
[8,7,-1,-1,8,8]
[8,7,-1,9,8,8]
[8,10,10,9,8,8]
[-,1-,1,10,9,-1,-1]
Since the first range contains several sub-arrays, the next step is to break that array out into as many combinations as possible. After calculating all the combinations, the code ends up with 12 different options for playing the C major chord:
[8,7,5,0,5,0]
[8,7,5,0,5,8]
[8,7,5,0,8,0]
[8,7,5,0,8,8]
[8,7,5,5,5,0]
[8,7,5,5,5,8]
[8,7,5,5,8,0]
[8,7,5,5,8,8]
[8,7,-1,-1,8,8]
[8,7,-1,9,8,8]
[8,10,10,9,8,8]
[-,1-,1,10,9,-1,-1]
The next step is to run all the combinations through a validator. Currently, the only rule in the validator is that the chord needs to be able to play on at least the top four strings. This eliminates three of the combinations, so now we’re left with:
[8,7,5,0,5,0]
[8,7,5,0,5,8]
[8,7,5,0,8,0]
[8,7,5,0,8,8]
[8,7,5,5,5,0]
[8,7,5,5,5,8]
[8,7,5,5,8,0]
[8,7,5,5,8,8]
[8,10,10,9,8,8]
Now comes the ranking. Each one of the remaining chords is evaluated using a scoring system. The scoring system has each chord start with 6 points. Then each chord receives an additional point for each string that is played (so 6 string chords are rated higher than 4 string chords). Next, each chord loses one point for each finger that is required to fret the chord. Note, however, that the fret for the barre chord does not count against the score. The reasoning here is that since a barre chord has a shorter fret range than an open chord, then it would be easier to play. So in our current dataset, once the scoring is done, here are the results:
8 - [8,7,5,0,5,0]
7 - [8,7,5,0,5,8]
8 - [8,7,5,0,8,0]
7 - [8,7,5,0,8,8]
7 - [8,7,5,5,5,0]
9 - [8,7,5,5,5,8]
7 - [8,7,5,5,8,0]
8 - [8,7,5,5,8,8]
9 - [8,10,10,9,8,8]
This leaves a two-way tie between the fingering [8,7,5,5,5,8] and [8,10,10,9,8,8]. Ties are broken by giving preference to open-string tunings, and even though [8,7,5,5,5,8] is not an open tuning it was derived using the ranges from the open tuning option, so it wins.
And that’s how it works. There are clearly some ways I can still optimize this including making the fret range be based on a physical distance and not just a fret number. This would create more options at the higher end of the neck where it’s easier to have a seven fret range.
But I’m curious what insights people have.
Wow. That’s all I can say. Wow. In just FIVE DAYS there have been over 11,000 downloads of the GuitarChords widget, and it’s reached #10 on Apple’s Top 50 widgets list. You all rock.
I’ve received plenty of great feedback, so I wanted to post a list of the features that will be included in version 1.5 of the widget. I’m hoping to complete this next rev by the end of the week, so check back for an annoucement. In the meantime, here’s a list of what will be included in version 1.5.
- Audio! Using a custom widgetplugin and Quicktime, you’ll be able to hear the chord played string by string as well as all at once.
- Audio playback options - Related to the new audio feature, you will be able to turn the audio on and off, choose the type of guitar (acoustic, electric, etc.) used to play the chord and also control the speed at which the chord is played.
- Lefty fretboard option - I received many comments from people wanting a left-handed view of the fretboard. Considering I play lefty and am always complaining about lack of support for lefties, this feature will be included ASAP.
- Auto-scrolling - If the chord isn’t displayed entirely on screen, then it will now auto-scroll so you’ll be able to see the whole chord. Also, if no chord can be drawn, then you’ll receive a notice as well.
There isn’t going to be a major facelift, and the physical dimensions of the widget will NOT change, so don’t worry that more features equals bigger widget. Though I do suspect the download file size will increase by 50K or so, but personally I think it’s still easily manageable even for dial-up users.
Back to work…