0

I started from this: https://stackoverflow.com/questions/12435211/python-threading-timer-repeat-function-every-n-seconds#=

I want to send MIDI timecode, cross-platform. I checked the input logged from my code and the timing loses 100 milliseconds or so here and there, which is not nearly accurate enough - I need to send 96-120 times a second, evenly spaced messages. The input I get from Cubase is very, very accurate in this (max. 1 ms off after 10 seconds), but I have the feeling (I hope) I haven't yet found the best way to do it in Python. Also, I'd like the timing to be unaffected by the amount of processing taking place in between calls, which I guess will depend on how much musical activity is occurring at any given moment. But this is just timecode, no notes, and even so the timing is not accurate enough. I'm using Python 2.7 on Windows 7 (later on OSX 10.9 and Linux). Everywhere I look, I find results for benchmarking code or functions, but what I want is to execute some code 100+ times per second without drift. Any ideas? My code:

import time
import threading as th

ind = 0

class MyThread(th.Thread):
    def __init__(self, event):
        th.Thread.__init__(self)
        self.stopped = event
        self.ind = 0

    def run(self):
        while not self.stopped.wait(0.01):
            self.ind += 1
            if self.ind % 100 == 0:
                print time.clock()
            if self.ind == 1000:
                self.stopped.set()

stopFlag = th.Event()
thread = MyThread(stopFlag)
thread.start()

Thanks a million! -Chuckk

Community
  • 1
  • 1
Chuckk Hubbard
  • 129
  • 1
  • 9
  • 4
    I'm very skeptical that you can do this with Python and threading, actually. I'd expect a package like Cubase to have specialised routines to minimise the drift that are not limited by an interpreter loop and OS-level threading. – Martijn Pieters May 21 '15 at 13:49
  • Have you checked the APScheduler package? – RaJa May 21 '15 at 14:02
  • Possible implicit duplicate of http://stackoverflow.com/questions/1133857/how-accurate-is-pythons-time-sleep – Filip Malczak May 21 '15 at 14:18
  • Well, could be, but the responses to that question don't give me an answer to mine. I also mentioned wanting timing to be unaffected by other activities. And I'm not determined to use time.sleep(), necessarily. – Chuckk Hubbard May 21 '15 at 21:40
  • Thanks for the suggestion, RaJa. I'm not sure, looking at it, it looks like it's intended for long-term use. I can already schedule my messages, but their timing is off. I came across some info about sched today, but haven't had time to look into it... – Chuckk Hubbard May 21 '15 at 21:41
  • Now I'm considering using the Windows API for users on Windows. Anyone: I know it is possible, in some way, to send 100+ MIDI messages/second with millisecond accuracy, because the software I'm trying to emulate does this. Everything I check is intended for something else; the Windows API advises me not to set SetWaitableTimer to short intervals, or if I do... then not to set them periodic, which is the only thing I need! If I have to code the timing of my program in C and pipe information to it, I will; but please, how can this be done? Google has been letting me down on this for weeks. – Chuckk Hubbard May 22 '15 at 07:51
  • OK, now this seems to work. It's so simple I fear there must be obvious flaws with it... CPU or what not? But it gets great timing, and in Python... mout = md.MidiOut() mout.open_port(1) ind = 1 start = time.clock() while ind < 1100: diff = time.clock() - start if diff > ind/100.0: mout.send_message((241, msglist[ind][1])) ind += 1 time.sleep(.001) (I indented my code, but it won't show correctly) – Chuckk Hubbard May 23 '15 at 08:13

1 Answers1

0

If you want precision below 10 ms you need to program this in a real real-time system like a microprocessor. Windows 7 won't be accurate enough because of interrupts. From what I know it's something like 16 ms at best for Windows.

Atto
  • 152
  • 9