Working 1.0
This commit is contained in:
commit
c070ac9026
157
main.py
Normal file
157
main.py
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
|
import mido
|
||||||
|
|
||||||
|
from mido.ports import MultiPort
|
||||||
|
|
||||||
|
def match_device_name(input_name, output_list):
|
||||||
|
# Function to match device names flexibly
|
||||||
|
for device in output_list:
|
||||||
|
if any(substring in device for substring in input_name.split()):
|
||||||
|
return device
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def determine_host(devices_in):
|
||||||
|
master = None
|
||||||
|
"""
|
||||||
|
Determine the host by listening for 'start' messages on input ports.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- devices_in (list of str): The names of the MIDI input ports to listen to.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
- str: The name of the input port that received the 'start' message.
|
||||||
|
"""
|
||||||
|
# Open all the input ports
|
||||||
|
inports = [mido.open_input(device) for device in devices_in]
|
||||||
|
|
||||||
|
# Create a MultiPort to listen on all input ports
|
||||||
|
#ports = MultiPort(inports, True)
|
||||||
|
|
||||||
|
print("Listening for messages...")
|
||||||
|
try:
|
||||||
|
while not master:
|
||||||
|
for port in inports:
|
||||||
|
for message in port.iter_pending():
|
||||||
|
#print(f"Received message: ({port.name}, {message})")
|
||||||
|
if 'start' in str(message):
|
||||||
|
master = port.name
|
||||||
|
break
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Interrupted by user.")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Ensure all ports are closed
|
||||||
|
for port in inports:
|
||||||
|
port.close()
|
||||||
|
print("Closed all input ports.")
|
||||||
|
if master:
|
||||||
|
return master
|
||||||
|
|
||||||
|
def relay_midi_host_to_out(host_name, devices_out):
|
||||||
|
"""
|
||||||
|
Relay MIDI messages from a specific input port to all specified output ports.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
- host_name (str): The name of the MIDI input port to listen to.
|
||||||
|
- devices_out (list of str): The names of the MIDI output ports to send messages to.
|
||||||
|
"""
|
||||||
|
#host_name = f'{host_name}'
|
||||||
|
reset = False
|
||||||
|
# Open the input port
|
||||||
|
print("Opening Input ffsk", host_name)
|
||||||
|
|
||||||
|
input_port = mido.open_input(host_name)
|
||||||
|
output_ports = [mido.open_output(device) for device in devices_out]
|
||||||
|
|
||||||
|
print(f"Listening for messages on {host_name} and relaying to {devices_out}")
|
||||||
|
recent_messages = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(reset)
|
||||||
|
while not reset:
|
||||||
|
# Process all pending messages
|
||||||
|
#print("Entering loop", input_port.iter_pending() )
|
||||||
|
for message in input_port.iter_pending():
|
||||||
|
read_message = str(message)
|
||||||
|
#spread_the_word = MultiPort(output_ports)
|
||||||
|
#print(read_message)
|
||||||
|
|
||||||
|
if 'start' in read_message or 'stop' in read_message:
|
||||||
|
for dev in output_ports:
|
||||||
|
dev.send(message)
|
||||||
|
recent_messages.append(read_message)
|
||||||
|
#print("SS")
|
||||||
|
|
||||||
|
elif 'clock' in read_message:
|
||||||
|
for dev in output_ports:
|
||||||
|
dev.send(message)
|
||||||
|
#print("clock")
|
||||||
|
|
||||||
|
# Keep only the last 3 messages
|
||||||
|
if len(recent_messages) > 3:
|
||||||
|
recent_messages.pop(0)
|
||||||
|
|
||||||
|
# Check if the last 3 messages are all 'stop'
|
||||||
|
if recent_messages[-3:] == ['stop time=0', 'stop time=0', 'stop time=0']:
|
||||||
|
#print("Received 'stop' three times in a row")
|
||||||
|
# Perform the desired action when 'stop' is received three times in a row
|
||||||
|
# For example, resetting the list
|
||||||
|
recent_messages.clear()
|
||||||
|
|
||||||
|
reset = True
|
||||||
|
break
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
# Handle user interrupt (e.g., Ctrl+C)
|
||||||
|
print("MIDI relay interrupted by user.")
|
||||||
|
|
||||||
|
finally:
|
||||||
|
# Close all ports
|
||||||
|
input_port.close()
|
||||||
|
print(input_port)
|
||||||
|
|
||||||
|
for port in output_ports:
|
||||||
|
#port.reset()
|
||||||
|
port.close()
|
||||||
|
print(port)
|
||||||
|
print("Closed all MIDI ports.")
|
||||||
|
|
||||||
|
#Repeat host detection a nd main loop
|
||||||
|
time.sleep(1)
|
||||||
|
main_run()
|
||||||
|
|
||||||
|
def main_run():
|
||||||
|
|
||||||
|
# Retrieve the list of available input devices
|
||||||
|
devices_in = mido.get_input_names()
|
||||||
|
devices_out = mido.get_output_names()
|
||||||
|
print("Available MIDI input devices:", devices_in)
|
||||||
|
|
||||||
|
# Call the function to start receiving messages from all devices
|
||||||
|
midi_host_in = determine_host(devices_in)
|
||||||
|
print(midi_host_in)
|
||||||
|
|
||||||
|
# Find and remove the matching output device to avoid feedback
|
||||||
|
matching_output_device = match_device_name(midi_host_in, devices_out)
|
||||||
|
|
||||||
|
if matching_output_device:
|
||||||
|
devices_out.remove(matching_output_device)
|
||||||
|
|
||||||
|
print(devices_out)
|
||||||
|
#time.sleep(3)
|
||||||
|
if midi_host_in:
|
||||||
|
relay_midi_host_to_out(midi_host_in, devices_out)
|
||||||
|
|
||||||
|
print("mido died")
|
||||||
|
|
||||||
|
main_run()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
72
main_direct.py
Normal file
72
main_direct.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
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()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user