Python Notes

Tuesday, August 17, 2004

Guitar MIDI simulator

I must be crazy. I've never did multimedia programming before, and my first project is a guitar simulator. Why did I chose such a project? Well, I like to play MIDIs at home. I have a small collection of MIDI-Karaoke files, and we have fun singing in family. There are many MIDI Karaoke files out there, but in many cases the sound of the guitar is crap. Many people assume that it has to be so, but it isn't. The actual samples are pretty good. The problem is that most MIDI files just play the guitar part just like a piano. There is no dynamics; all the notes are hit at once. Rhythm guitar is not played flat, strings are strummed in sequence as the right hand goes down an up. The timing is essential to convey the rhythm.

There are actually a few professional tools to do it around the 'net. The best example that I could find is the Rhythm'n'Chords MIDI FX plug-in for Cakewalk Pro Audio. However, all these tools are proprietary and expensive. So I decided to give it a try.

Being my first incursion on multimedia programming, the first step was to actually learn a little about the basics - how good is the OS support for MIDI, and what are the libraries available. I found that I have indeed a few choices, but all with some type limitation. Most libraries that I've found are outdated, or not actively maintained. Some are Linux only, and I'm writing my code for Windows. And finally, the most up-to-date routines that I could find only work for MIDI files, and do not do real time MIDI playback.

For my initial tests, I decided upon using midipy, real-time MIDI input module for Python. It's not being maintained by its author, but it works; other people have recompiled it for newer versions of Python (I suspect that a new version could be made using simpler tools, by directly wrapping the Windows multimedia DLLs, but I don't have enough knowledge about how to do it). The reasoning behin this choice is simple: I would like to be able to hear my tests immediately, and all other approaches involve either writing MIDI files for playback, or low-level development. That's not the focus of the project - the focus is to understand how to simulate the sequence of events of a rhythm guitar being played.

The guitar itself is a simple class. Each string is treated independently, and there are separate methods for the left and right hands movements. The left hand moves to set up a new chord position. When a chord changes, the strings are muted, and each string is "tuned" to a particular tone. The left hand movement has several attributes that can be customized; the main ones are the speed at the which the hand traverses all strings, and the direction, that can be either "down" or "up". Depending on the direction, the strings are strummed in a different fashion. For both hands, the result is a sequence of timed events that can be played to give the illusion of a real guitar being played.

To synchronize the events, I used the threading module. The threads are started only after all events were generated, to avoid concurrency issues. The results are actually acceptable for a short sequence. There is some jitter, and large sequences don't play well due to interruptions and delays. The threading timer is not real time, and it not good enough for multimedia applications. But as a proof of concept, the project seems to be going well. I was able to write a fairly simple rhythm pattern that sounds just like someone learning to play guitar, which is more than I had expected after a few hours of programming.

I'm now at the point where I must take a decision. If I'm going to keep the real time interface, then I'll need to improve the timing. One alternative is to write my own multimedia event handlers, but I'm not sure if this is possible to do in Python; or I can try to use the Midi Stream API, but then I have to implement a wrapper for Python. The remaining alternative is to forget the real time MIDI playback for now, and write all stuff to MIDI files. This approach has the advantage of letting me concentrate on the guitar playing aspects of the simulator, but I lose interactivity. The testing of new rhytmic patterns may become more difficult, and some of the fun may go away, too. Let's ponder about it for a while before taking any decision.


Post a Comment

<< Home