Skip to content

Commit

Permalink
Light up buttons (#25)
Browse files Browse the repository at this point in the history
Co-authored-by: Łukasz Smoliński <[email protected]>
  • Loading branch information
Jokilos and lukaszsmolinski authored Apr 24, 2024
1 parent 8f69410 commit 1050d2e
Show file tree
Hide file tree
Showing 4 changed files with 221 additions and 30 deletions.
99 changes: 85 additions & 14 deletions midi_app_controller/controller/connected_controller.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import logging
import time
from typing import List, Tuple
from typing import List, Tuple, Set, Callable

import rtmidi
from qtpy.QtCore import QMutex, QMutexLocker

from midi_app_controller.models.controller import Controller
from midi_app_controller.actions.actions_handler import ActionsHandler
Expand All @@ -28,8 +29,16 @@ class ConnectedController:
A list containing all valid button ids on a handled controller.
knob_ids : List[int]
A list containing all valid knob ids on a handled controller.
knob_engagement: Dict[int, int]
knob_engagement : Dict[int, int]
A dictionary that keeps the value of every knob.
butons_mutex : QMutex
Mutex for worker threads.
flashing_buttons : set[int]
Set with ids of buttons that are currently flashing.
knobs_mutex : QMutex
Mutex for worker threads.
flashing_knobs : set[int]
Set of the knob ids, that are currently flashing.
"""

def __init__(
Expand Down Expand Up @@ -65,6 +74,12 @@ def __init__(
self.init_buttons()
self.init_knobs()

self.flashing_knobs = set()
self.flashing_buttons = set()

self.knobs_mutex = QMutex()
self.buttons_mutex = QMutex()

# Set callback for getting data from controller.
self.midi_in.set_callback(self.midi_callback)

Expand Down Expand Up @@ -173,6 +188,37 @@ def send_midi_message(self, data: List[int]) -> None:
except ValueError as err:
logging.error(f"Value Error: {err}")

@staticmethod
def check_set_and_run(
func: Callable[[], None], id: int, mutex: QMutex, id_set: Set[int]
) -> None:
"""Checks if the provided set contains `id`.
It executes `func` if it doesn't and does nothing otherwise.
Parameters
----------
func : Callable[[], None]
Function to execute.
id : int
Id for which we check provided set.
mutex : QMutex
Mutex for ensuring that checking `id` presence is
mutually exclusive.
id_set : Set[int]
Set containing ids.
"""
already_flashing = False
with QMutexLocker(mutex):
if id in id_set:
already_flashing = True
else:
id_set.add(id)

if not already_flashing:
func()
with QMutexLocker(mutex):
id_set.remove(id)

def flash_knob(self, id: int) -> None:
"""Flashes the LEDs corresponding to a knob on a MIDI controller.
Expand All @@ -181,13 +227,31 @@ def flash_knob(self, id: int) -> None:
id : int
Id of the knob.
"""
sleep_seconds = 0.3

for _ in range(3):
self.change_knob_value(id, self.controller.knob_value_min)
time.sleep(sleep_seconds)
self.change_knob_value(id, self.controller.knob_value_max)
time.sleep(sleep_seconds)
current_value = self.knob_engagement[id]
sleep_seconds = 0.04
intervals = 14
min_max_diff = self.controller.knob_value_max - self.controller.knob_value_min

def light_up_func():
for value in range(
self.controller.knob_value_min,
self.controller.knob_value_max,
min_max_diff // intervals,
):
self.change_knob_value(id, value)
time.sleep(sleep_seconds)

for value in range(
self.controller.knob_value_max,
self.controller.knob_value_min,
-min_max_diff // intervals,
):
self.change_knob_value(id, value)
time.sleep(sleep_seconds)

self.change_knob_value(id, current_value)

self.check_set_and_run(light_up_func, id, self.knobs_mutex, self.flashing_knobs)

def flash_button(self, id: int) -> None:
"""Flashes the button LED on a MIDI controller.
Expand All @@ -197,11 +261,18 @@ def flash_button(self, id: int) -> None:
id : int
Id of the button.
"""
for _ in range(3):
self.turn_on_button_led(id)
time.sleep(0.3)
self.turn_off_button_led(id)
time.sleep(0.3)
sleep_seconds = 0.3

def light_up_func():
for _ in range(3):
self.turn_on_button_led(id)
time.sleep(sleep_seconds)
self.turn_off_button_led(id)
time.sleep(sleep_seconds)

self.check_set_and_run(
light_up_func, id, self.buttons_mutex, self.flashing_buttons
)

def build_message(
self,
Expand Down
Loading

0 comments on commit 1050d2e

Please sign in to comment.