Python Notes

Tuesday, August 31, 2004

Installing a Python Application Development Environment-

I am installing a brand new Python environment on a low-end PC to keep up with my software development tasks while I'm off my office. The PC is really low end by todays standard -- a Pentium 166 -- but still, it should be enough for by needs, that is, mostly writing code. It has a few advantages too - in the sense that I'm not going to be able to test everything by the old lazy hit-the-run-button approach, and I'm probably going to have to rely on the well disciplined code reading approach to check out my code before running (after all, running it may be too slow).

The code that I am going to write now is not fancy stuff (the guitar playing code will have to wait a few days more). It's a business application that I've been talking about with a potential customer. I still haven't closed the deal, but I feel the need to try a few things out before doing so, just to make sure that we are on the right road. I'm not still sure if the application is going to be web-based or wxWidgets based. There are good reasons for both, but I never used wxWidgets for a professional project before, and I don't know about the current quality of the GUI tools for it.

I need the following tools:

  • A good programming environment -- that is, the Python interpreter, libs, docs, editor and debugger.

  • If wxWidgets comes into play, a good visual RAD tools is a must have. Boa Constructor is the default candidate here - it's free and it seems to be the tool of choice today.

  • Database support means two things. First, I need the SQL database engine itself. The range of choices for open source projects is big: MySQL, mSQL, PostgreSQL and Firebird [1] come to mind. We also need a good ORM, or Object Relational Mapper. There are several good ones for Python: MiddleKit [1], Object Relational Membrane. Not all ORMs work with every database engine, though.

  • Web development tools are also important. The best ones that I know (ignoring Zope for its bloat) are CherryPy, WebWare, Quixote and Cheetah. For this particular project, CherryPy seems to be the best fit, specially for its ability to include a reasonably fast running webserver into the generated code.


There are a few more things that I was tempted to include in my list today, but will have to wait a little bit more. First of all, aspect oriented programming tools seem to be useful for web applications. CherryPy does support it, but there are other options around that deserve a check. Also, source code control is something important for any reasonably sized project. Subversion seems the way to go -- a lot of Python projects are using it, and there are several tools to help managing Subversion-based projects around. But's still too early to tell; also, my current setup does not allow for such complex tools right now.

Basic Toolset -- first round


This list is by no means definitive. It's rather an attempt to select a reasonable amount of tools to try in actual production in a slower machine. I'm probably going to have to limit myself to non-visual tools anyway, but I hope to turn this into an actual advantage.
ActivePython

First of all, nothing beats ActiveState's Python environment when talking about MS Windows. It's the best Python distro around, for it comes with a valuable selection of tools and docs ready to install. A must have.

SciTE

Just in case, I opted to download SciTE, the official Scintilla text editor. PythonWIN text editor is also scintilla based, but SciTE is useful for other tasks too, and have supports syntax-coloring for a lot of different languages. It's a useful addition.

wxPython

It's almost an official part of every native GUI development toolkit for Python.

Boa Constructor

Boa is in it's 0.3.1 release. It's still pre-alpha, but it works. I don't know if I will be able to use it on my current setup, though.

Object Relational Mapper 1.0.1

I've still not decided which database to use -- but I downloaded this ORM, to check the documentation and study it a little bit. It supports a good selection of servers, including MySQL, PostgreSQL and Firebird.

Friday, August 20, 2004

Implementing real time MIDI playback

After some thought, I decided to give it a try and implement real time playback using the MIDI Streams API. I installed ctypes, an outstanding Python library to support native DLL calls from Python. After hacking with it a little bit, I managed to implement the basic midiStreamOpen and midiStreamClose calls. The library is actually fairly easy to use, but there were a few gotchas:
  • I mistakenly assumed that I would have to load the mmsystem.dll library. In fact, I had to load winmm.dll. What made this problem worse is that the error message when trying to load mmsystem.dll is totally misleading, and I had to count on the help of the ctypes-users mailing list to solve it.

  • The winmm.dll library is 16 bit - weird, but understandable, given Microsoft tradition. This was not an issue up to this point, but I'm better be prepared for surprises.

  • It takes some time to get to speed to translate C protoype definitions (with all those ugly hungary notation names) in the correspondent ctypes for Python. It's not hard, but a few mistakes were met with segfaults and stuff like that.


In the end, everything ran fine. I'm now working on the hardest part - the midiStreamOut call. The call itself is easy, bu I have first to set up the MIDIHDR and MIDIEVENT buffers. Both structures form simple linked lists with real C pointers, and that's something that I haven't done for a long time (being first a Pascal/Delphi nut, and now a Python lover). I fear that a few segfaults expect me there.

There is another thing that I absolutely have to do, that is to understand better the MIDI tempo stuff. Some of the information on the MIDI header is tempo related. My current model for the guitar is time-based -- the argument for the right hand movement defines how long does it take for each beat, in seconds. Now I have to change everything to expressed in terms of quarter notes and beats per minute. It's a small paradigm change, but clearly for better, and I'm still on the early stages of design so it's welcome.

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.

Monday, August 09, 2004

A nice Python based blog engine

Nu Cardboard: Blog Notes

I found this blog today, while checking the news from Daily Python. Hey. it's really nice, and it seems to be very well structured. That's the type of stuff I'm looking for myself. The author has promised to publish the source code, and I'm really looking forward to check how some things were implemented. Even if he doesn't publish it, the tips about CherryPy and Cheetah were welcome and worth the visit.

Back to Python, Blogs & Wikis

About one year ago I stopped coding and following Python's development. Not because I didn't like it, but other professional activities required my full dedication. Now it's over, and I'm back to my home office trying to figure out what the next big revolution will be. Over the past year, I missed the blog explosion, but I think that there is still time to catch up. And for all my programming needs... why not Python?

I've recently installed Python 2.3 (the latest stable release) and checked 2.4's progress. While the minor complaints regarding the growing complexity of the language are valid, it's also amazing how much progress in terms of useful stuff was made. Some things that were only partly implemented are now a real part of the language (namely, iterators - they're everywhere, and that's good). The latest discussions that I remind myself taking part involved CVS and Decimal numbers. Both are there too, although not exactly asI have dreamed.

I'm also coding, albeit at a slow pace. I downloaded MoinMoin, the excellent Pure Python Wiki engine. I started to customize it to my needs, and it is slowly beginning to resemble a crossover between a Wiki and a Blog. I can write blog-like, timestamped entries, and still link to Wiki style webpages. I think I'm onto something here. Of course, I should not be writing this in public, but hey, it would not be bad to attract a few people to join me and discuss these ideas...