Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Light up buttons #25

Merged
merged 23 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading