Issue 47 * May 1, 2008

Chorduroy:
Revolution Teaches Guitar
Part One

by Tom Healy

For some of you out there exercising your fingers with long sessions of Ten Thumbs Typing Tutor or furious Revolution code offs just won't be enough, and you may find yourself turning to a guitar to improve your dexterity. In this series of articles I'm going to be taking you through the process of making a chord generating program (creatively named Chorduroy), stage by stage. The aim of the program is to allow you to select a chord name and key, have its notes displayed in an easy to understand format and be shown different ways of playing these chords on a guitar. This should be much easier than trawling through one of those chord dictionaries and will display the information in a way that will give you a better understanding of how chords are constructed. You might also learn some new Revolution coding ideas along the way! You can download the accompanying project here.

Firstly, I'm quickly going to run through some of the basics of the theory behind constructing chords for those of you who aren't familiar with the concepts. I don't want to get too bogged down in this however as the focus of this article is on programming in Revolution. Anyone who knows their music theory should skip the next section.

Ok, here goes. An octave is the name given to the gap between two notes, where one note is twice the frequency of the first. The second note is the same as the first but just an octave higher. The frequencies between the two notes are subdivided into 12 equal steps known as semitones and surprisingly enough two semitones are known as a tone. A major scale is made up of 7 of these 12 semitones spaced out in the following way, tone, tone, semitone, tone, tone, tone, semitone i.e. 2,2,1,2,2,2,1. The notes in this scale are numbered, 1 being the note that gives the scale its name. The 8th note takes you back to this 1st note but is an octave higher. Here are the 12 semitones that separate two C notes an octave apart:

C C#/Db D D#/Eb E F F#/Gb G G#/Ab A A#/Bb B

Here are the 7 notes that make up the C major scale from these 12 semitones:

C D E F G A B -> up to C again

You'll notice that some of the notes have two names. A note with a # symbol is a sharp note meaning it is raised by 1 semitone - C# is one semitone higher than C. A note with a b symbol is a flat, meaning it is lowered by 1 semitone in a similar way. They are two different names for the same note. There are rules on when to use each name but for the purposes of this program this can basically be overlooked. Now let's move onto chord construction.

When two or more notes of different pitches are played at the same time, this is referred to as a chord. Different combinations of the notes in the major scale have been assigned specific names. For example playing the 1st, 3rd and 5th notes from the major scale at the same time will result in a very agreeable sounding chord known as a Major chord. So C Major is made up of C, E and G. There are many different types of chord, each with their associated formula. This program will attempt to store and make use of all these formulas in an easily understandable way. Ok, that's basically everything you need to know in order to understand the concepts behind this program.

So assuming you either already know everything I've just mentioned or you've somehow managed to understand my convoluted explanation, let's move on and look at the chord generator program itself. This program attempts to store the various rules to chord composition I've just mentioned and present the information in a simple format that tells you the notes required to play a chord. It will hopefully give you an insight into how they are constructed if you still aren't sure about this.

Using the program is simple, you select the key (or root note) of the chord you wish to display in the field on the far left, then select the type of chord from the list of commonly used ones in the field to its right. The chord information window will then be updated to display the chord's long name, the chord formula, the interval numbers of the major scale used to make the chord, the chord notes and the semitones. This is the number of each chord note in terms of its position in the 12 semitones of the octave as shown here:

The stack basically works by storing each of the above pieces of information in custom properties of the cards. Storing these values in this way means that they can be accessed by any other control in this stack simply by using a command such as:

   local tScale
   put the cScale of this card into tScale

So firstly let's look at using the two list fields that allow you to select the key and chord. Both these fields have very similar scripts. The "on selectionChanged" handler is a very efficient way to handle the different methods of selecting lines from this field, as it deals with selections made by clicking on a line and also selections made by using the up and down arrow keys. Key selection field:

on selectionChanged
   set the cKey of this card to the selectedText of me 
   refreshCard
end selectionChanged 

Chord selection field:

on selectionChanged
   local tLineNumber
     put the hilitedLine of me  into tLineNumber
     set the cChordFormula of this card of this stack to line
tLineNumber of the cChordFormulaLookup of me 
   set the cChordName of this card of this stack to the 
hilitedText of me 
   refreshCard
end selectionChanged

The first control makes use of the "selectedText" property since the text of the selected line is literally what will be stored as the key. The contents of the chord selection field however, are associated with particular chord formulae, so here I've used a different method. The field itself has a custom property, "cChordFormulaLookup", which is a list of all the chord formulas corresponding to each line of the field. So we store the "hilitedLine" of the field and then use this line number with the "cChordFormulaLookup" to access the correct chord formula and store this in a custom property of the card. After storing each of these, the "refreshCard" command is issued, which is a handler stored in the card script responsible for updating the on screen controls of the stack.

Moving on now to look at card script itself. The refreshCard handler is responsible for updating the onscreen controls. It's important with control updates to lock the screen at the beginning of the handler as this will make the transition the controls undergo appear smooth and instantaneous. The first control to be updated is the chord name field. This is dealt with by its own handler which is stored in the script of the field itself. Since the script of that field is higher up in the message path we must send the command as a message specifically to that field as follows:

	send "selectChord" to field "chord title" of this card
   

Now taking a look at the script of the chord title field we can see the "selectChord" command handler. This handler again makes use of the stored custom property of the card corresponding to the chord name. The purpose of this function is to examine the short name selected and then place the chords' actual long name into this field. For the sake of variety I've used a switch statement to perform this, even though it is a slightly more long winded method than using a custom property lookup table or something similar. For this switch statement I've had to set the "caseSensitive" to false in order to make the distinction between an "m" meaning minor chord and an "M" meaning a major chord. Finally there is a check to make sure both a chord name and key are selected, if they are, the text of the chord name field is set, otherwise the text is set to empty.

Moving back to the card script now, the next control to update is the chord formula field:

	put the cChordFormula of me into field "formula" of me 
	

Next we must update the semitones field. As mentioned earlier this field doesn't really have a musical purpose but is used internally when calculating the correct note names and is therefore displayed here for the purposes of clarity. So first of all a conversion takes place from the stored chord formula into a numerical formula that can be applied to the 12 semitones present in an octave. This conversion is performed by the "returnNumericalFormula" command. This command has to convert the 1,b3,5 (minor chord) type notation to a more useable list of digits, in this case 1,4,8. Since there aren't too many different formula terms (b3, #7 etc) I've used another switch statement here as a series of conditions checking for flats and sharps would probably be more hassle than it's worth. After the switch is performed the cNumericalFormula of the card is set to this new set of values.

Finally we must obtain the note names from the scale we are using. This is achieved with a call to the return notes function. This command makes use of a data field stored on another card of this stack, appropriately called "chord data". On this card there is a field named "scales" which contains a list of all the 12 notes beginning from each note. Firstly the text of this field is placed into a variable:

   put the text of field "Scales" 
  of card "Chord Data" of this stack into tScaleTable
   split tScaleTable by return and tab
   put tScaleTable[the cKey of me] into tScale
   set the cScale of me to tScale
   

Next the split command is used to convert this data into an array with assigned keys, the primary delimiter being return and the seconday delimiter being tab. This places each line into an array entry with the initial character of each line, the tab separated part, being the key for each line. Next we place the correct element of the array into a variable using the cKey of the card as a reference. Now the cScale of the card is set to the contents of this element. Once the correct scale has been stored it is simply a matter of taking the items that correspond to the numerical chord formula and placing them into a variable. Since some of the numbers in each formula exceed 12 and are actually octaves of these notes we can make use of the wrap function which will loop back to the beginning of the scale should 12 be exceeded.

   put item tNoteIndex wrap 12 of tScale & comma after tChordNotes
   

This wraps the 12 items of the tScale variable. This feature is a new addition added in Revolution 2.9, full details of which can be found in the documentation.

At the bottom right of the stack there is a group titled "scale". The central yellow band of this group displays the current scale relating to the selected key, the top band indicates the location of the chord notes along the scale and the bottom band simply shows the position of the scale degrees.

I've included this feature in the stack for the sake of clarity but its operation will be explained in my next article along with some additional features that will form the ground work for displaying how to play these chords on a guitar neck.

Main Menu What's New