[英]Is there a way to run a funcion on several instances of a class at exactly the same time? Independent Multi-Metronome with MIDI ctrl
Hi:) I am programming an independent multi-metronome and need to run the funciont beat() on a while loop for every instances of my class Metronome() , starting at the same time.嗨 :) 我正在编写一个独立的多节拍器,需要同时开始为我的类 Metronome() 的每个实例在 while 循环上运行 funciont beat() 。
import time
import mido
from numpy import interp
from IPython.display import clear_output
inport = mido.open_input() #my MIDI is a KORG nanoKontrol 2
class Metronome():
#A dict for my MIDI controller
metronomes_controls = {
'inst_number':[n + 0 for n in range(0,7)],
'vol_slide':[n + 0 for n in range(0,7)],
'tempo_knob': [n + 16 for n in range(0,7)],
'play_stop': [n + 32 for n in range(0,7)],
'sync_selected': [n + 48 for n in range(0,7)],
'tap_button': [n + 64 for n in range(0,7)]}
def __init__(self, inport, inst_number = 0, tempo=60, active=True,
on_off_list = ['ON','OFF','ON','OFF'], selector = 0):
self.inport = inport
self.inst_number = inst_number
self.tempo = tempo
self.active = active
self.on_off_list = on_off_list #The controller is not so precise
self.selector = selector
self.controls = dict(zip(list(metronomes_controls.keys()),
[val[self.inst_number] for val in metronomes_controls.values()]))
def beat(self):
if self.active == True:
print('Tick', self.tempo) #this is going to be a sound
time.sleep(int(round(60/self.tempo)))
clear_output()
self.update()
else:
self.update()
def update(self):
msg = self.inport.receive(block=False)
for msg in inport.iter_pending():
if msg.control == self.controls['tempo_knob']:
self.tempo = int(interp(msg.value,[0,127],[20,99]))
if msg.control == self.controls['play_stop']:
self.selector += 1
if self.selector >3:
self.selector = 0
if 'ON' in self.on_off_list[self.selector]:
print('ON')
self.active = True
if 'OFF' in self.on_off_list[self.selector]:
print('OFF')
self.active = False
#Creating two instances of my class
m0 = Metronome(inport = inport, inst_number = 0)
m1 = Metronome(inport = inport,inst_number = 1)
m2 = Metronome(inport = inport,inst_number = 1)
m3 = Metronome(inport = inport,inst_number = 1)
#They run on a while loop. All should start at the same time.
while True:
m0.beat()
m1.beat()
m2.beat()
m3.beat()
I read about threading but it seems to create some starting delay.我阅读了有关线程的信息,但它似乎会造成一些启动延迟。 Then I got into barries , but I couldn't imagine how to implement it:/ or maybe should I try something with multiprocess?
然后我进入了barries ,但我无法想象如何实现它:/或者我应该尝试使用多进程? I got really lost!
我真的迷路了! Any advice is highly appreciated
非常感谢任何建议
Thanks for the help!!!谢谢您的帮助!!!
Create one thread per metronome and start them at (almost) the same time:为每个节拍器创建一个线程并(几乎)同时启动它们:
from threading import Thread
# Previous code...
...
def create_thread(inport, inst_number):
# The function the thread is going to execute
def inner():
m = Metronome(inport, inst_number)
m.beat()
return Thread(target=inner)
if __name__ == "__main__":
inport = mido.open_input()
# Create the threads
threads = [
create_thread(inport, i) for i in (0, 1, 1, 1)
]
# Start them at (almost) the same time
for t in threads:
t.start()
# Wait for them to finish execution
for t in threads:
t.join()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.