fix: undo reconnection, doesnt really work yet.
This commit is contained in:
parent
d83cf8ce00
commit
4cfd750afc
1 changed files with 11 additions and 81 deletions
|
|
@ -3,32 +3,25 @@ MIDI Controller module for MIDI-to-Hue application.
|
||||||
Handles MIDI device connections, message processing, and event handling.
|
Handles MIDI device connections, message processing, and event handling.
|
||||||
"""
|
"""
|
||||||
import mido
|
import mido
|
||||||
import time
|
|
||||||
import threading
|
|
||||||
from typing import Dict, List, Callable, Optional, Any, Union
|
from typing import Dict, List, Callable, Optional, Any, Union
|
||||||
|
|
||||||
|
|
||||||
class MidiController:
|
class MidiController:
|
||||||
"""Manages MIDI device connections and message handling."""
|
"""Manages MIDI device connections and message handling."""
|
||||||
|
|
||||||
def __init__(self, midi_device_index: int = 1, reconnect_interval: int = 5):
|
def __init__(self, midi_device_index: int = 1):
|
||||||
"""
|
"""
|
||||||
Initialize the MIDI controller.
|
Initialize the MIDI controller.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
midi_device_index: Index of the MIDI device to use
|
midi_device_index: Index of the MIDI device to use
|
||||||
reconnect_interval: Seconds between reconnection attempts (if connection lost)
|
|
||||||
"""
|
"""
|
||||||
self.midi_device_index = midi_device_index
|
self.midi_device_index = midi_device_index
|
||||||
self.reconnect_interval = reconnect_interval
|
|
||||||
self.port = None
|
self.port = None
|
||||||
self.input_names = []
|
self.input_names = []
|
||||||
self.output_names = []
|
self.output_names = []
|
||||||
self.ioport_names = []
|
self.ioport_names = []
|
||||||
self.message_handlers = []
|
self.message_handlers = []
|
||||||
self._running = False
|
|
||||||
self._reconnect_thread = None
|
|
||||||
self._connection_healthy = False
|
|
||||||
|
|
||||||
# Initialize MIDI
|
# Initialize MIDI
|
||||||
self._initialize()
|
self._initialize()
|
||||||
|
|
@ -69,25 +62,17 @@ class MidiController:
|
||||||
selected_input = self.input_names[self.midi_device_index]
|
selected_input = self.input_names[self.midi_device_index]
|
||||||
print(f"\nOpening MIDI input: {selected_input}")
|
print(f"\nOpening MIDI input: {selected_input}")
|
||||||
self.port = mido.open_ioport(selected_input)
|
self.port = mido.open_ioport(selected_input)
|
||||||
self._connection_healthy = True
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error opening MIDI device: {e}")
|
print(f"Error opening MIDI device: {e}")
|
||||||
self._connection_healthy = False
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def close(self) -> None:
|
def close(self) -> None:
|
||||||
"""Close the MIDI port if open."""
|
"""Close the MIDI port if open."""
|
||||||
self._running = False
|
|
||||||
if self._reconnect_thread and self._reconnect_thread.is_alive():
|
|
||||||
self._reconnect_thread.join(timeout=1.0)
|
|
||||||
|
|
||||||
if self.port:
|
if self.port:
|
||||||
self.port.close()
|
self.port.close()
|
||||||
self.port = None
|
self.port = None
|
||||||
|
|
||||||
self._connection_healthy = False
|
|
||||||
|
|
||||||
def register_handler(self, handler: Callable) -> None:
|
def register_handler(self, handler: Callable) -> None:
|
||||||
"""Register a function to handle incoming MIDI messages."""
|
"""Register a function to handle incoming MIDI messages."""
|
||||||
|
|
@ -100,78 +85,23 @@ class MidiController:
|
||||||
else:
|
else:
|
||||||
print("Error: No MIDI port open")
|
print("Error: No MIDI port open")
|
||||||
|
|
||||||
def _reconnect_monitor(self) -> None:
|
|
||||||
"""
|
|
||||||
Monitor thread that attempts to reconnect if the MIDI connection is lost.
|
|
||||||
"""
|
|
||||||
while self._running:
|
|
||||||
if not self._connection_healthy and not self.port:
|
|
||||||
print("MIDI connection lost. Attempting to reconnect...")
|
|
||||||
# Refresh available devices
|
|
||||||
self._initialize()
|
|
||||||
# Try to open the port again
|
|
||||||
if self.open():
|
|
||||||
print("Successfully reconnected to MIDI device!")
|
|
||||||
else:
|
|
||||||
print(f"Reconnect failed. Retrying in {self.reconnect_interval} seconds...")
|
|
||||||
|
|
||||||
# Wait before checking again
|
|
||||||
time.sleep(self.reconnect_interval)
|
|
||||||
|
|
||||||
def process_messages(self) -> None:
|
def process_messages(self) -> None:
|
||||||
"""Start processing MIDI messages, calling registered handlers."""
|
"""Start processing MIDI messages, calling registered handlers."""
|
||||||
if not self.port:
|
if not self.port:
|
||||||
print("Error: No MIDI port open")
|
print("Error: No MIDI port open")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Start the reconnect monitor thread
|
|
||||||
self._running = True
|
|
||||||
self._reconnect_thread = threading.Thread(
|
|
||||||
target=self._reconnect_monitor,
|
|
||||||
daemon=True
|
|
||||||
)
|
|
||||||
self._reconnect_thread.start()
|
|
||||||
|
|
||||||
print("Waiting for MIDI messages... Press Ctrl+C to exit.")
|
print("Waiting for MIDI messages... Press Ctrl+C to exit.")
|
||||||
|
try:
|
||||||
while self._running:
|
for msg in self.port:
|
||||||
try:
|
print(f"Received: {msg}")
|
||||||
if not self.port:
|
# Call all registered handlers
|
||||||
time.sleep(0.5) # If port is None, wait a bit
|
for handler in self.message_handlers:
|
||||||
continue
|
handler(msg)
|
||||||
|
except KeyboardInterrupt:
|
||||||
# Non-blocking way to check for messages
|
print("\nExiting MIDI processing...")
|
||||||
msg = self.port.poll()
|
except Exception as e:
|
||||||
if msg:
|
print(f"Error processing MIDI messages: {e}")
|
||||||
print(f"Received: {msg}")
|
|
||||||
# Call all registered handlers
|
|
||||||
for handler in self.message_handlers:
|
|
||||||
handler(msg)
|
|
||||||
# Connection is healthy since we received a message
|
|
||||||
self._connection_healthy = True
|
|
||||||
else:
|
|
||||||
# Small sleep to prevent CPU hogging in the loop
|
|
||||||
time.sleep(0.001)
|
|
||||||
|
|
||||||
except (IOError, AttributeError) as e:
|
|
||||||
# These errors typically indicate a connection problem
|
|
||||||
print(f"MIDI connection error: {e}")
|
|
||||||
self._connection_healthy = False
|
|
||||||
if self.port:
|
|
||||||
try:
|
|
||||||
self.port.close()
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
self.port = None
|
|
||||||
time.sleep(1) # Wait a bit before continuing the loop
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
|
||||||
print("\nExiting MIDI processing...")
|
|
||||||
self._running = False
|
|
||||||
break
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
print(f"Error processing MIDI messages: {e}")
|
|
||||||
|
|
||||||
|
|
||||||
class DeviceMappingManager:
|
class DeviceMappingManager:
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue