Fix MIDI bridge: remove semicolons (corrupts Pd velocity parsing), retry on device busy
Validate and Test / validate-patches (push) Failing after 13s
Validate and Test / validate-patches (push) Failing after 13s
This commit is contained in:
+14
-22
@@ -17,12 +17,6 @@ SERVICES = ["midi-bridge", "pd-synth-onboard", "led-matrix-viz", "prometheus-exp
|
|||||||
STATUS_CACHE = {}
|
STATUS_CACHE = {}
|
||||||
LAST_STATUS_CHECK = 0.0
|
LAST_STATUS_CHECK = 0.0
|
||||||
|
|
||||||
STATUS_ROW = 0
|
|
||||||
SERVICE_COLS = {0: 0, 1: 1, 2: 2, 3: 3}
|
|
||||||
AUDIO_COL = 4
|
|
||||||
NOTE_ROWS = 7
|
|
||||||
NOTE_ROW_OFFSET = 1
|
|
||||||
|
|
||||||
def _check_services():
|
def _check_services():
|
||||||
global STATUS_CACHE, LAST_STATUS_CHECK
|
global STATUS_CACHE, LAST_STATUS_CHECK
|
||||||
now = time.monotonic()
|
now = time.monotonic()
|
||||||
@@ -55,31 +49,28 @@ def render(active_notes):
|
|||||||
pixels = [[0] * COLS for _ in range(ROWS)]
|
pixels = [[0] * COLS for _ in range(ROWS)]
|
||||||
note_min, note_max = 36, 96
|
note_min, note_max = 36, 96
|
||||||
for note in active_notes:
|
for note in active_notes:
|
||||||
row = NOTE_ROWS - 1 - int((note - note_min) / (note_max - note_min) * (NOTE_ROWS - 1))
|
row = 7 - int((note - note_min) / (note_max - note_min) * 7)
|
||||||
row = max(0, min(NOTE_ROWS - 1, row)) + NOTE_ROW_OFFSET
|
row = max(0, min(6, row))
|
||||||
col = note % 12
|
col = note % 12
|
||||||
pixels[row][col] = 1
|
pixels[row][col] = 1
|
||||||
status = _check_services()
|
status = _check_services()
|
||||||
for idx, svc in enumerate(SERVICES):
|
ok = sum(1 for s in SERVICES if status.get(s))
|
||||||
col = SERVICE_COLS[idx]
|
|
||||||
if status.get(svc):
|
|
||||||
pixels[STATUS_ROW][col] = 1
|
|
||||||
if len(active_notes) > 0:
|
if len(active_notes) > 0:
|
||||||
pixels[STATUS_ROW][AUDIO_COL] = 1
|
ok += 1
|
||||||
|
for c in range(ok):
|
||||||
|
pixels[7][c] = 1
|
||||||
return pack_frame(pixels)
|
return pack_frame(pixels)
|
||||||
|
|
||||||
|
|
||||||
def _diag_frame(active_notes):
|
def _diag_frame(active_notes):
|
||||||
pixels = [[0] * COLS for _ in range(ROWS)]
|
pixels = [[0] * COLS for _ in range(ROWS)]
|
||||||
status = _check_services()
|
status = _check_services()
|
||||||
for idx, svc in enumerate(SERVICES):
|
ok = sum(1 for s in SERVICES if status.get(s))
|
||||||
col = SERVICE_COLS[idx]
|
|
||||||
if status.get(svc):
|
|
||||||
for r in range(ROWS):
|
|
||||||
pixels[r][col] = 1
|
|
||||||
if len(active_notes) > 0:
|
if len(active_notes) > 0:
|
||||||
|
ok += 1
|
||||||
for r in range(ROWS):
|
for r in range(ROWS):
|
||||||
pixels[r][AUDIO_COL] = 1
|
for c in range(ok):
|
||||||
|
pixels[r][c] = 1
|
||||||
return pack_frame(pixels)
|
return pack_frame(pixels)
|
||||||
|
|
||||||
|
|
||||||
@@ -193,14 +184,15 @@ def main():
|
|||||||
except BlockingIOError:
|
except BlockingIOError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
while b";" in buf:
|
msg = data.decode().strip()
|
||||||
raw_msg, buf = buf.split(b";", 1)
|
|
||||||
msg = raw_msg.decode().strip()
|
|
||||||
parts = msg.split()
|
parts = msg.split()
|
||||||
if len(parts) >= 3 and parts[0] == "midi":
|
if len(parts) >= 3 and parts[0] == "midi":
|
||||||
|
try:
|
||||||
status = int(parts[1])
|
status = int(parts[1])
|
||||||
note = int(parts[2])
|
note = int(parts[2])
|
||||||
vel = int(parts[3]) if len(parts) >= 4 else 0
|
vel = int(parts[3]) if len(parts) >= 4 else 0
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
msg_type = status & 0xF0
|
msg_type = status & 0xF0
|
||||||
changed = False
|
changed = False
|
||||||
if msg_type == 0x90 and vel > 0:
|
if msg_type == 0x90 and vel > 0:
|
||||||
|
|||||||
+10
-2
@@ -46,8 +46,8 @@ def _find_midi_dev():
|
|||||||
|
|
||||||
def midi_msg(status, data1, data2=None):
|
def midi_msg(status, data1, data2=None):
|
||||||
if data2 is not None:
|
if data2 is not None:
|
||||||
return f"midi {status} {data1} {data2};"
|
return f"midi {status} {data1} {data2}"
|
||||||
return f"midi {status} {data1};"
|
return f"midi {status} {data1}"
|
||||||
|
|
||||||
|
|
||||||
def _open_midi():
|
def _open_midi():
|
||||||
@@ -55,7 +55,15 @@ def _open_midi():
|
|||||||
while not os.path.exists(midi_dev):
|
while not os.path.exists(midi_dev):
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
midi_dev = _find_midi_dev()
|
midi_dev = _find_midi_dev()
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
fd = os.open(midi_dev, os.O_RDWR | os.O_NONBLOCK)
|
fd = os.open(midi_dev, os.O_RDWR | os.O_NONBLOCK)
|
||||||
|
break
|
||||||
|
except OSError as e:
|
||||||
|
if e.errno == 16:
|
||||||
|
time.sleep(0.5)
|
||||||
|
continue
|
||||||
|
raise
|
||||||
os.set_blocking(fd, False)
|
os.set_blocking(fd, False)
|
||||||
return fd
|
return fd
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user