added midi messages log windows

This commit is contained in:
Paul Lipscomb
2026-06-29 04:14:09 -04:00
parent 16fa8395c7
commit fc9da58d7c
4 changed files with 133 additions and 32 deletions
+123 -24
View File
@@ -497,6 +497,62 @@ textedit_osc_out_log.setStyleSheet("""
} }
""") """)
# Container: container_midi_in_log
container_midi_in_log = QWidget(None, Qt.WindowType.Window)
container_midi_in_log.setWindowTitle("MIDI In — Incoming")
container_midi_in_log.setStyleSheet("background-color: #1a1a1a;")
container_midi_in_log.setFixedWidth(360)
vstack_midi_in_log = QVBoxLayout(container_midi_in_log)
vstack_midi_in_log.setContentsMargins(6, 6, 6, 6)
vstack_midi_in_log.setSpacing(4)
hstack_midi_in_log_header = QHBoxLayout()
label_midi_in_log_title = QLabel("MIDI In — Incoming")
label_midi_in_log_title.setStyleSheet("color: #ff8c00; font-weight: bold; font-size: 11px;")
button_midi_in_clear = QPushButton("Clear")
button_midi_in_clear.setFixedSize(45, 18)
textedit_midi_in_log = QTextEdit()
textedit_midi_in_log.setReadOnly(True)
textedit_midi_in_log.setStyleSheet("""
QTextEdit {
background-color: #111111;
color: #ff8c00;
font-family: monospace;
font-size: 10px;
border: none;
}
""")
# Container: container_midi_out_log
container_midi_out_log = QWidget(None, Qt.WindowType.Window)
container_midi_out_log.setWindowTitle("MIDI Out — Outgoing")
container_midi_out_log.setStyleSheet("background-color: #1a1a1a;")
container_midi_out_log.setFixedWidth(360)
vstack_midi_out_log = QVBoxLayout(container_midi_out_log)
vstack_midi_out_log.setContentsMargins(6, 6, 6, 6)
vstack_midi_out_log.setSpacing(4)
hstack_midi_out_log_header = QHBoxLayout()
label_midi_out_log_title = QLabel("MIDI Out — Outgoing")
label_midi_out_log_title.setStyleSheet("color: #00bcd4; font-weight: bold; font-size: 11px;")
button_midi_out_clear = QPushButton("Clear")
button_midi_out_clear.setFixedSize(45, 18)
textedit_midi_out_log = QTextEdit()
textedit_midi_out_log.setReadOnly(True)
textedit_midi_out_log.setStyleSheet("""
QTextEdit {
background-color: #111111;
color: #00bcd4;
font-family: monospace;
font-size: 10px;
border: none;
}
""")
# MARK: PRESET BROWSER ROW MODULE # MARK: PRESET BROWSER ROW MODULE
label_preset_browser_title = QLabel("Preset Browser") label_preset_browser_title = QLabel("Preset Browser")
hstack_preset_browser = QHBoxLayout() hstack_preset_browser = QHBoxLayout()
@@ -987,6 +1043,24 @@ class MainWindow(QMainWindow):
container_osc_out_log.setVisible(False) container_osc_out_log.setVisible(False)
#MARK: MIDI IN LOG CONTAINER
hstack_midi_in_log_header.addWidget(label_midi_in_log_title)
hstack_midi_in_log_header.addStretch()
hstack_midi_in_log_header.addWidget(button_midi_in_clear)
vstack_midi_in_log.addLayout(hstack_midi_in_log_header)
vstack_midi_in_log.addWidget(textedit_midi_in_log)
button_midi_in_clear.clicked.connect(lambda: textedit_midi_in_log.clear())
container_midi_in_log.setVisible(False)
#MARK: MIDI OUT LOG CONTAINER
hstack_midi_out_log_header.addWidget(label_midi_out_log_title)
hstack_midi_out_log_header.addStretch()
hstack_midi_out_log_header.addWidget(button_midi_out_clear)
vstack_midi_out_log.addLayout(hstack_midi_out_log_header)
vstack_midi_out_log.addWidget(textedit_midi_out_log)
button_midi_out_clear.clicked.connect(lambda: textedit_midi_out_log.clear())
container_midi_out_log.setVisible(False)
main_layout.addWidget(make_separator()) main_layout.addWidget(make_separator())
# MARK: TRANSPORT ROW CONTROLS # MARK: TRANSPORT ROW CONTROLS
@@ -1185,7 +1259,9 @@ class MainWindow(QMainWindow):
check_midi_port_availability() check_midi_port_availability()
midi_receiver.midi_in_signal.connect(lambda msg: make_activity_blink(activity_indicator_midi_in)) midi_receiver.midi_in_signal.connect(lambda msg: make_activity_blink(activity_indicator_midi_in))
midi_receiver.midi_out_signal.connect(lambda: make_activity_blink(activity_indicator_midi_out)) midi_receiver.midi_in_signal.connect(log_midi_incoming)
midi_receiver.midi_out_signal.connect(lambda _: make_activity_blink(activity_indicator_midi_out))
midi_receiver.midi_out_signal.connect(log_midi_outgoing)
midi_receiver.transport_out_signal.connect(lambda: make_activity_blink(activity_indicator_transport_out)) midi_receiver.transport_out_signal.connect(lambda: make_activity_blink(activity_indicator_transport_out))
midi_receiver.hw_cc_signal.connect(midi_message_route_hw_to_output_cc) midi_receiver.hw_cc_signal.connect(midi_message_route_hw_to_output_cc)
@@ -1357,34 +1433,46 @@ def set_port_transport_output(port_name):
check_midi_port_availability() check_midi_port_availability()
save_io_config() save_io_config()
def _append_log(textedit, line):
textedit.append(line)
if textedit.document().blockCount() > 200:
cursor = textedit.textCursor()
cursor.movePosition(cursor.MoveOperation.Start)
cursor.select(cursor.SelectionType.LineUnderCursor)
cursor.removeSelectedText()
cursor.deleteChar()
def _midi_msg_str(msg):
if len(msg) >= 3:
status = msg[0] & 0xF0
ch = (msg[0] & 0x0F) + 1
if status == 0xB0:
return f"CC{msg[1]} CH{ch} [{msg[2]}]"
return " ".join(f"{b:02X}" for b in msg)
def log_midi_incoming(msg):
from datetime import datetime
ts = datetime.now().strftime("%H:%M:%S")
line = f"<span style='color:#555'>{ts}</span> <span style='color:#ff8c00'>{_midi_msg_str(msg)}</span>"
_append_log(textedit_midi_in_log, line)
def log_midi_outgoing(msg):
from datetime import datetime
ts = datetime.now().strftime("%H:%M:%S")
line = f"<span style='color:#555'>{ts}</span> <span style='color:#00bcd4'>{_midi_msg_str(msg)}</span>"
_append_log(textedit_midi_out_log, line)
def log_osc_incoming(addr, val): def log_osc_incoming(addr, val):
from datetime import datetime from datetime import datetime
ts = datetime.now().strftime("%H:%M:%S") ts = datetime.now().strftime("%H:%M:%S")
line = f"<span style='color:#555'>{ts}</span> <span style='color:#00e676'>{addr}</span> <span style='color:#d4d4d4'>{val}</span>" line = f"<span style='color:#555'>{ts}</span> <span style='color:#00e676'>{addr}</span> <span style='color:#d4d4d4'>{val}</span>"
textedit_osc_in_log.append(line) _append_log(textedit_osc_in_log, line)
doc = textedit_osc_in_log.document()
if doc.blockCount() > 200:
cursor = textedit_osc_in_log.textCursor()
cursor.movePosition(cursor.MoveOperation.Start)
cursor.select(cursor.SelectionType.LineUnderCursor)
cursor.removeSelectedText()
cursor.deleteChar()
def log_osc_outgoing(addr, val): def log_osc_outgoing(addr, val):
from datetime import datetime from datetime import datetime
ts = datetime.now().strftime("%H:%M:%S") ts = datetime.now().strftime("%H:%M:%S")
line = f"<span style='color:#555'>{ts}</span> <span style='color:#1e88e5'>{addr}</span> <span style='color:#d4d4d4'>{val}</span>" line = f"<span style='color:#555'>{ts}</span> <span style='color:#1e88e5'>{addr}</span> <span style='color:#d4d4d4'>{val}</span>"
textedit_osc_out_log.append(line) _append_log(textedit_osc_out_log, line)
doc = textedit_osc_out_log.document()
if doc.blockCount() > 200:
cursor = textedit_osc_out_log.textCursor()
cursor.movePosition(cursor.MoveOperation.Start)
cursor.select(cursor.SelectionType.LineUnderCursor)
cursor.removeSelectedText()
cursor.deleteChar()
def update_osc_server_ip(ip): def update_osc_server_ip(ip):
set_osc_target(ip=ip.strip() or "127.0.0.1") set_osc_target(ip=ip.strip() or "127.0.0.1")
@@ -2191,18 +2279,29 @@ def midi_message_route_hw_to_output_cc(fader_uid, value):
def log_ui_show_hide(checked): def log_ui_show_hide(checked):
container_osc_in_log.setVisible(checked) container_osc_in_log.setVisible(checked)
container_osc_out_log.setVisible(checked) container_osc_out_log.setVisible(checked)
container_midi_in_log.setVisible(checked)
container_midi_out_log.setVisible(checked)
log_ui_window_calc() log_ui_window_calc()
def log_ui_window_calc(): def log_ui_window_calc():
geo = app_window.frameGeometry() geo = app_window.frameGeometry()
h = geo.height() h = geo.height()
container_osc_in_log.setFixedHeight(h) half = h // 2 - 2
# Left column: OSC In (top) + OSC Out (bottom)
container_osc_in_log.setFixedWidth(360)
container_osc_in_log.setFixedHeight(half)
container_osc_in_log.move(geo.right() + 4, geo.top()) container_osc_in_log.move(geo.right() + 4, geo.top())
container_osc_out_log.setFixedWidth(360) container_osc_out_log.setFixedWidth(360)
container_osc_out_log.setFixedHeight(h // 2) container_osc_out_log.setFixedHeight(half)
container_osc_out_log.move(geo.right() + 4, geo.top() + h // 2 + 4) container_osc_out_log.move(geo.right() + 4, geo.top() + half + 4)
container_osc_in_log.setFixedHeight(h // 2 - 4) # Right column: MIDI In (top) + MIDI Out (bottom)
container_midi_in_log.setFixedWidth(360)
container_midi_in_log.setFixedHeight(half)
container_midi_in_log.move(geo.right() + 368, geo.top())
container_midi_out_log.setFixedWidth(360)
container_midi_out_log.setFixedHeight(half)
container_midi_out_log.move(geo.right() + 368, geo.top() + half + 4)
def start_osc_server(port=9000): def start_osc_server(port=9000):
global _osc_server, _osc_thread global _osc_server, _osc_thread
+1 -1
View File
@@ -2,7 +2,7 @@ from PyQt6.QtCore import QObject, pyqtSignal
class MidiReceiver(QObject): class MidiReceiver(QObject):
midi_in_signal = pyqtSignal(list) midi_in_signal = pyqtSignal(list)
midi_out_signal = pyqtSignal() midi_out_signal = pyqtSignal(list)
transport_out_signal = pyqtSignal() transport_out_signal = pyqtSignal()
hw_cc_signal = pyqtSignal(str, int) hw_cc_signal = pyqtSignal(str, int)
+6 -4
View File
@@ -14,12 +14,14 @@ print("Available MIDI ports:", available_ports)
def send_cc(cc_number, value, channel=None): def send_cc(cc_number, value, channel=None):
ch = (channel - 1) if channel is not None else MIDI_CH ch = (channel - 1) if channel is not None else MIDI_CH
msg = [0xB0 | ch, cc_number, value]
if midi_out.is_port_open(): if midi_out.is_port_open():
midi_out.send_message([0xB0 | ch, cc_number, value]) midi_out.send_message(msg)
midi_receiver.midi_out_signal.emit() midi_receiver.midi_out_signal.emit(msg)
def send_transport_cc(cc_number, value): def send_transport_cc(cc_number, value):
msg = [0xB0 | TRANSPORT_MIDI_CH, cc_number, value]
if transport_midi_out.is_port_open(): if transport_midi_out.is_port_open():
transport_midi_out.send_message([0xB0 | TRANSPORT_MIDI_CH, cc_number, value]) transport_midi_out.send_message(msg)
midi_receiver.transport_out_signal.emit() midi_receiver.midi_out_signal.emit(msg)
+2 -2
View File
@@ -483,8 +483,8 @@
], ],
"transport_show_hide": false, "transport_show_hide": false,
"io_config": { "io_config": {
"midi_out": "Not Connected", "midi_out": "IAC Driver Bus 1",
"midi_in": "VMPK Output", "midi_in": "Not Connected",
"transport_out": "Not Connected", "transport_out": "Not Connected",
"osc_ip": "127.0.0.1", "osc_ip": "127.0.0.1",
"osc_listen_port": 9000, "osc_listen_port": 9000,