Update GUI layout and MIDI CC mappings: CC36=n3, CC37=delay, remove B1/B2 references

This commit is contained in:
2025-09-18 20:35:31 +12:00
parent 8d0c9edf5d
commit 36dfda74b2
2 changed files with 164 additions and 48 deletions

View File

@@ -41,16 +41,17 @@ class MidiHandler:
# Raw CC-driven parameters (0-127)
self.n1 = 10
self.n2 = 10
self.n3 = 1
# Current state for GUI display
self.current_bpm: float | None = None
self.current_pattern: str = ""
self.beat_index: int = 0
def _current_color_hex(self) -> str:
def _current_color_rgb(self) -> tuple:
r = max(0, min(255, int(self.color_r)))
g = max(0, min(255, int(self.color_g)))
b = max(0, min(255, int(self.color_b)))
return f"#{r:02x}{g:02x}{b:02x}"
return (r, g, b)
async def _send_reset_to_sound(self):
try:
@@ -84,25 +85,27 @@ class MidiHandler:
# Attempt to parse as float (BPM) from sound.py
bpm_value = float(message)
self.current_bpm = bpm_value
# On each beat, trigger currently selected pattern
# On each beat, trigger currently selected pattern(s)
if not self.current_pattern:
logging.debug("[Beat] No pattern selected yet; ignoring beat")
else:
payload = {
"0": {
"pattern": self.current_pattern,
"delay": self.delay,
"colors": [self._current_color_hex()],
"brightness": self.brightness,
"num_leds": 200,
"n1": self.n1,
"n2": self.n2,
"n": self.beat_index,
}
}
self.beat_index = (self.beat_index + 1) % 1000000
logging.debug(f"[Beat] Triggering pattern '{self.current_pattern}' with payload: {payload}")
await self.ws_client.send_data(payload)
if self.current_pattern:
payload1 = {
"0": {
"pattern": self.current_pattern,
"delay": self.delay,
"colors": [self._current_color_rgb()],
"brightness": self.brightness,
"num_leds": 200,
"n1": self.n1,
"n2": self.n2,
"n3": self.n3,
"n": self.beat_index,
}
}
logging.debug(f"[Beat] Triggering '{self.current_pattern}' with payload: {payload1}")
await self.ws_client.send_data(payload1)
except ValueError:
logging.warning(f"[MidiHandler - TCP Server] Received non-BPM message from {addr}, not forwarding: {message}") # Changed to warning
except Exception as e:
@@ -136,8 +139,11 @@ class MidiHandler:
msg = port.receive(block=False)
if msg and msg.type == 'control_change':
if msg.control == 36:
self.n3 = max(1, msg.value)
logging.info(f"[Init] n3 set to {self.n3} from CC36")
elif msg.control == 37:
self.delay = msg.value * 4
logging.info(f"[Init] Delay set to {self.delay} ms from CC36")
logging.info(f"[Init] Delay set to {self.delay} ms from CC37")
elif msg.control == 33:
self.brightness = round((msg.value / 127) * 100)
logging.info(f"[Init] Brightness set to {self.brightness} from CC33")
@@ -195,15 +201,15 @@ class MidiHandler:
match msg.type:
case 'note_on':
logging.debug(f" Note ON: Note={msg.note}, Velocity={msg.velocity}, Channel={msg.channel}") # Changed to debug
# Bind patterns starting at MIDI note 36
# Bank1 patterns starting at MIDI note 36
pattern_bindings: list[tuple[str, dict]] = [
("pulse", {"n1": 120, "n2": 120}),
("flicker", {}),
("alternating", {"n1": 6, "n2": 6}),
("n_chase", {"n1": 5, "n2": 5}),
("fill_range", {"n1": 10, "n2": 20}),
# fill_range intentionally omitted from buttons
("rainbow", {}),
("specto", {"n1": 20}),
# specto intentionally omitted from buttons
("radiate", {"n1": 8}),
]
idx = msg.note - 36
@@ -217,13 +223,16 @@ class MidiHandler:
self.n2 = extra["n2"]
logging.info(f"[Select] Pattern selected via note {msg.note}: {self.current_pattern} (n1={self.n1}, n2={self.n2})")
else:
logging.debug(f"Note {msg.note} not bound to a pattern (base 36, {len(pattern_bindings)} entries)")
logging.debug(f"Note {msg.note} not bound to patterns")
case 'control_change':
match msg.control:
case 36:
self.n3 = max(1, msg.value) # Update n3 step rate
logging.info(f"n3 set to {self.n3} by MIDI controller (CC36)")
case 37:
self.delay = msg.value * 4 # Update instance delay
logging.info(f"Delay set to {self.delay} ms by MIDI controller") # Changed to info
logging.info(f"Delay set to {self.delay} ms by MIDI controller (CC37)")
case 27:
if msg.value == 127:
self.beat_sending_enabled = True