Help with Optimization of Python software: real-time audio controller

Discussion in 'Python' started by craiglewiston@gmail.com, Feb 12, 2007.

  1. Guest

    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
    , Feb 12, 2007
    #1
    1. Advertising

  2. Perhaps boosting priorities for time critical threads will help.

    I don't know about MacOS but for Win32 something like that helps:

    thread = win32api.GetCurrentThread()
    win32process.SetThreadPriority(thread,
    win32process.THREAD_PRIORITY_TIME_CRITICAL)

    current_process = win32process.GetCurrentProcess()
    win32process.SetPriorityClass(current_process,
    win32process.REALTIME_PRIORITY_CLASS)
    Vasily Sulatskov, Feb 12, 2007
    #2
    1. Advertising

  3. Paul Rubin Guest

    writes:
    > 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 think you can't really do that, not just because of Python but also
    as a result of using a multitasking OS that's not especially designed
    for real time. You have to rely on some buffering in the audio
    hardware, so you don't have to be sample-accurate with the timings.
    Paul Rubin, Feb 12, 2007
    #3
  4. Ross Ridge Guest

    Paul Rubin wrote:
    > I think you can't really do that, not just because of Python but also
    > as a result of using a multitasking OS that's not especially designed
    > for real time. You have to rely on some buffering in the audio
    > hardware, so you don't have to be sample-accurate with the timings.


    For his application you don't need "sample-accurate" timings. Between
    MIDI and synthesizer latency a few milliseconds of delay are inherent
    in what he's trying to do, regardless of operatings system, and a
    latency of 20 milliseconds or more is probably acceptable. Assuming
    he's not trying to write his own synthesizer, he might just be able to
    write his application in Python under Mac OS X.

    Ross Ridge
    Ross Ridge, Feb 12, 2007
    #4
  5. a écrit :
    > 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).

    <zip>

    > 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
    >



    You may take a look at PureData, interface is in TCL/Tk, but realtime
    sound management layers are in compiled C.
    "just" copy it using Python as high level language...
    I dont think Python itself just using scripting can achieve needed
    performance for *realtime* (like) audio.

    http://www.puredata.info/
    http://www-crca.ucsd.edu/~msp/
    Laurent Pointal, Feb 12, 2007
    #5
  6. Klaas Guest

    On Feb 11, 6:40 pm, wrote:
    > 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.


    Your problems do not necessarily stem from slow code. Python only
    performs thread context switches every 100 øpcodes, and the switch
    might not arrive at the right time.

    You can lower this value (sys.setcheckinterval). Your computationally-
    intensive threads may effectively lower their priority by calling
    time.sleep(.00001) every so often.

    Ultimately, maintaining explicity control over the scheduling of
    events is probably the way to go.

    Pyrex is my preferred optimization method, but it can take some
    knowledge of what's going on to get the most out of it. numpy is
    another option.

    -Mike
    Klaas, Feb 12, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. preet

    About AC97 audio controller

    preet, Jul 9, 2005, in forum: VHDL
    Replies:
    4
    Views:
    3,659
    Andy Peters
    Jul 14, 2005
  2. Romulo Carneiro

    Audio in Real Time

    Romulo Carneiro, Nov 14, 2006, in forum: C Programming
    Replies:
    3
    Views:
    314
    james of tucson
    Nov 14, 2006
  3. Replies:
    6
    Views:
    547
    Dennis Lee Bieber
    Mar 31, 2007
  4. Chris
    Replies:
    1
    Views:
    314
    clintonG
    Jun 14, 2007
  5. Michael Earls
    Replies:
    3
    Views:
    3,247
    MBUnit
    Mar 24, 2009
Loading...

Share This Page