Friday, May 19, 2006

Strumming the guitar - stage two

Things have been hectic at work over the past few weeks, which generally means that I don't do anything much with my 'own' time. Now that the pace has relaxed slightly, I thought it a good idea to go back to my MIDI strumming program. As it happens, it's exactly one month since I last wrote about it.

First off, I solved a few of the problems which I had left open:
  • Choosing different voicings of the same chord
  • How to represent strings which aren't played in a chord
  • Time signatures
The third problem wasn't really a problem when I thought about it: a strum's time signature is implicit in its pattern, so all I had to do was remove any code which might have attempted to affect the time signature. Obviously one is not going to use this program in order to strum along with material by National Health (or even Debussy's sublime "Afternoon of a fawn") in which time signatures change frequently.

Choosing different voicings also turned out to be much simpler than I had originally imagined: all it needed was to add a 'version' number to each chord (for example, "E minor7/1" and "E minor7/2" which will be enough to differentiate. Although one might think that there would be problems matching a chord like 'E7/9', this is not so. 

Unplayed strimgs also turned out to be a 'paper tiger': the string's value is set to 'x', and elsewhere the code knows that an 'x' note should have the MIDI value 0.

Here's a screenshot of the chord definition screen:

Once I had got all those problems out of the way, I started on the 'MIDI substitution' code. The idea here is to create a MIDI file consisting one bar of strummed E Major, and then to copy the values contained within the MIDI file into the new file, where the notes of E Major are substituted by the notes in the chosen chord. Whilst this wasn't easy to do, it also wasn't as hard as I had expected. The code uses procedural variables which simplify matters. In the great tradition of information hiding, the calling program sends a chord shape to a routine called 'WriteChord'. without knowing how that routine is actually implemented. The user is presented with several strum patterns, and after a pattern has been chosen, the 'WriteChord' procedural variable is set to the corresponding procedure for the chosen pattern.

The first pattern which I used with the substitution algorithm didn't finish correctly, so I had to edit some of the final delta times in order to get the timing correct. The second pattern which I tried came out correctly.

Now all that's left to do is enter more patterns, which is very much grunt work. There may still be a problem with time signatures - these are coded somewhere in a MIDI file's prologue, and of course at the moment I'm using a 4/4 signature. I imagine that this will be resolved by a flag being set if a specific pattern is in 3/4 (or even 5/4, gasp); prior to writing the file, the signature bytes in the prologue will be modified to the correct value.

I've decided to punt on the issue of chords changing halfway though a bar. The user can manually edit the resulting MIDI file.

No comments: