I've been working on a Python-based music training application for a few months, and have recently run into what I believe are some basic limitations (or at least constraints) of Python with regards to timing. I'll try and give a decently thorough description, and hopefully some of you can process this with your knowledge and help steer me in the right direction.
As mentioned above, my application deals with music training. I have a Tkinter GUI, which communicates via pyserial with an external device I built myself. The code reads in a MIDI file and converts the song to "output data " for the external device and the GUI, all adjusted to the user-selected tempo. While the MIDI file is playing, there are 4 main actions the code must take: 1) Send "output data" signals out to the external hardware. 2) Poll the input from the external hardware device for incoming keypresses. If detected, then the play the sound corresponding to that key. 3) Start and keep a metronome running for the durations of the song. 4) Update GUI I'm able to get all the above "accomplished" through the use of threads and a top-level loop (for updating the Tkinter GUI - if you've worked with threads and Tkinter, then you know that you can't update a Tkinter GUI from a thread, but instead have to do it on the top level loop). While running, I have the following threads implemented : 1) song processing thread - this thread steps incrementally through a data matrix (the "output data"), and updates two variables: GUI_vars and Device_vars 2) metronome thread - this thread starts at the same time as thread #1, and outputs a "beep" to the audio chain 3) poll input thread - this thread loops continually, looking for data on the serial Input. When data is found, it starts playing the sound corresponding to that key until a "note off" signal is received 4) top-level recursive loop (technically not a thread) for updating GUI and calling Serial Write subfunction. This loop monitors GUI_vars and Device_vars, updating the GUI and writing out to the device when either variable has changed Currently, I have all of the above "working", although I'm running into some serious timing issues. When I run the program, I get irregular timing for my metronome (if it sounds at all), as well as irregular timing in writing to the external device. It's extremely crucial that threads #1 & #2 are executed as close to real-time as possible, as they form the "core" of the song, and their elements can't be delayed without "messing" the song up considerably. I've read up quite a bit on different optimization methods in Python, but am not sure which direction to head. I've checked out profile, Psyco, Pyrex, as well as just porting everything over to C. Since I'm on a Mac (Power PC), I can't use Psyco. And doing any of the others seemed like a big enough project that I should really ask someone else before I embark. So, for a music-based application where it's crucial to have real-time execution of serial writeouts and audio, as well as keeping a continual poll on the input from the same port....can this be done successfully in Python? Does using Tkinter have anything to do with my timing issues? Would it benefit me to move over to wxPython (something I've been considering doing)? As for the metronome, should I incorporate the metronome thread into the "song processing" thread, since both are dealing with events whose timing is crucial? I'm a relative newbie (this is my first Python project) to Python, so any help is GREATLY appreciated! Also, just for reference, here's a list of the modules I'm using and my system info: Audio: SndObj Ser com: pyserial GUI: Tkinter System: Apple PowerBook G4 (PowerPC), Mac OS 10.4, Python 2.4.4 Thanks, Craig Lewiston -- http://mail.python.org/mailman/listinfo/python-list