73 lines
2.2 KiB
Python
73 lines
2.2 KiB
Python
|
import rtmidi
|
||
|
import time
|
||
|
|
||
|
|
||
|
class HostsSync:
|
||
|
def __init__(self):
|
||
|
self.host_id = None
|
||
|
self.available_ports = None
|
||
|
self.midi_out = rtmidi.MidiOut()
|
||
|
self.opened_ports = []
|
||
|
|
||
|
def midi_input_callback(self, event, data_pack):
|
||
|
message, deltatime = event
|
||
|
status = message[0]
|
||
|
host_id, midi_in = data_pack
|
||
|
|
||
|
# Check if the status byte is 0xFA (250 in decimal) or 0xFF (255 in decimal),
|
||
|
# which indicate MIDI Start and Stop messages respectively
|
||
|
if status in [250, 255]:
|
||
|
print(f"MIDI message received from device {host_id}: {message}")
|
||
|
self.host_id = host_id
|
||
|
self.midi_output_called(message)
|
||
|
|
||
|
def midi_output_called(self, message):
|
||
|
if self.host_id is None:
|
||
|
return
|
||
|
|
||
|
for i, port in enumerate(self.available_ports):
|
||
|
if i != self.host_id:
|
||
|
if i not in self.opened_ports:
|
||
|
self.midi_out.open_port(i)
|
||
|
self.opened_ports.append(i)
|
||
|
print(f"Opened MIDI output port: {self.available_ports[i]}")
|
||
|
|
||
|
self.midi_out.send_message(message)
|
||
|
|
||
|
def main(self):
|
||
|
midi_ins = []
|
||
|
self.available_ports = rtmidi.MidiIn().get_ports()
|
||
|
|
||
|
if not self.available_ports:
|
||
|
print("No MIDI input ports available.")
|
||
|
return
|
||
|
|
||
|
print("Available MIDI input ports:")
|
||
|
for i, port in enumerate(self.available_ports):
|
||
|
print(f"{i}: {port}")
|
||
|
|
||
|
try:
|
||
|
for i, port in enumerate(self.available_ports):
|
||
|
midi_in = rtmidi.MidiIn()
|
||
|
midi_in.open_port(i)
|
||
|
midi_in.set_callback(self.midi_input_callback, (i, midi_in))
|
||
|
midi_ins.append(midi_in)
|
||
|
print(f"Listening for MIDI messages on input port: {port}")
|
||
|
|
||
|
# Keep the script running to listen for MIDI messages
|
||
|
while True:
|
||
|
time.sleep(1)
|
||
|
|
||
|
except KeyboardInterrupt:
|
||
|
print("\nExiting...")
|
||
|
|
||
|
finally:
|
||
|
for midi_in in midi_ins:
|
||
|
midi_in.close_port()
|
||
|
|
||
|
self.midi_out.close_port()
|
||
|
|
||
|
if __name__ == "__main__":
|
||
|
HostsSync().main()
|
||
|
|