Source code for jdxi_editor.devel.replicate_working_app

#!/usr/bin/env python3
"""
Replicate Working App Approach

This attempts to replicate the approach used by the working MIDI monitoring app
that successfully captured your controller's messages.
"""

import sys
import time

import rtmidi
from PySide6.QtCore import QCoreApplication, QTimer
from PySide6.QtWidgets import QApplication

from picomidi import BitMask, MidiStatus

# Add the project root to the path
sys.path.insert(0, "/Users/brooks/projects/JDXI-Editor")

# Import compatibility module first
import rtmidi_compat


[docs] class WorkingAppReplicator: def __init__(self):
[docs] self.app = QCoreApplication(sys.argv)
[docs] self.midi_in = None
[docs] self.message_count = 0
[docs] self.start_time = None
[docs] def midi_callback(self, message, data): """Callback that should work like the successful app""" message_data, timestamp = message self.message_count += 1 # Format timestamp like your working app elapsed = time.time() - self.start_time if self.start_time else 0 timestamp_str = f"{elapsed:.3f}" # Decode the message if len(message_data) >= 3: status = message_data[0] if status == MidiStatus.CONTROL_CHANGE: # Control Change channel = (status & BitMask.LOW_4_BITS) + 1 controller = message_data[1] value = message_data[2] # Format like your working app if controller == 10: print( f"{timestamp_str:>8}\tFrom SINCO VMX8-Private\tControl\t{channel}\tPan (fine)\t{value}" ) elif controller == 41: print( f"{timestamp_str:>8}\tFrom SINCO VMX8-Private\tControl\t{channel}\tController 41\t{value}" ) else: print( f"{timestamp_str:>8}\tFrom SINCO VMX8-Private\tControl\t{channel}\tController {controller}\t{value}" ) else: print( f"{timestamp_str:>8}\tFrom SINCO VMX8-Private\tOther\t{message_data}" ) else: print(f"{timestamp_str:>8}\tFrom SINCO VMX8-Private\tRaw\t{message_data}")
[docs] def test_ports(self): """Test both SINCO ports""" print("=== Replicating Working App Approach ===") # Create MIDI input self.midi_in = rtmidi.RtMidiIn() # List ports port_count = self.midi_in.getPortCount() print(f"Available ports: {port_count}") ports = [] for i in range(port_count): port_name = self.midi_in.getPortName(i) ports.append((i, port_name)) print(f" {i}: {port_name}") # Find SINCO ports sinco_ports = [ (i, name) for i, name in ports if "SINCO" in name.upper() or "VMX8" in name.upper() ] if not sinco_ports: print("❌ No SINCO ports found") return False print(f"\nFound SINCO ports: {sinco_ports}") # Test each port for port_index, port_name in sinco_ports: print(f"\n=== Testing {port_name} ===") try: # Close any existing port if self.midi_in.isPortOpen(): self.midi_in.closePort() # Open the port self.midi_in.openPort(port_index) print(f"✅ Opened {port_name}") # Set callback self.midi_in.setCallback(self.midi_callback) print("✅ Callback set") # Set ignore types self.midi_in.ignoreTypes(False, True, True) print("✅ Ignore types set") # Start monitoring self.start_time = time.time() self.message_count = 0 print("Move controls on your SINCO VMX8 controller...") print("Monitoring for 15 seconds...\n") # Monitor with Qt event processing start_time = time.time() while time.time() - start_time < 15: self.app.processEvents() time.sleep(0.001) # Very short sleep if self.message_count > 0: print( f"\n✅ SUCCESS! Received {self.message_count} messages from {port_name}" ) else: print(f"\n❌ No messages received from {port_name}") # Close port self.midi_in.closePort() print(f"✅ Closed {port_name}") except Exception as e: print(f"❌ Error testing {port_name}: {e}") try: self.midi_in.closePort() except Exception: pass return True
[docs] def main(): print("Replicating Working MIDI App Approach") print("=" * 50) replicator = WorkingAppReplicator() success = replicator.test_ports() if success: print("\n✅ Test completed!") else: print("\n❌ Test failed!") sys.exit(1)
if __name__ == "__main__": try: main() except KeyboardInterrupt: print("\nExiting...") except Exception as e: print(f"Fatal error: {e}") sys.exit(1)