Compare commits

...

5 Commits

Author SHA1 Message Date
708a7e6d8e reword 2023-08-05 13:05:29 +01:00
409d2deea9 patch bump 2023-08-05 13:02:56 +01:00
0ee3a223ec stopped() checks if stop_event object is None.
In case the events thread was not initiated.
2023-08-05 13:02:04 +01:00
6bfd18c1ac call on_midi_press()
only if midi.current == MIDI_BUTTON
2023-08-05 13:00:45 +01:00
103355d265 use Threading.Event object to terminate producer 2023-08-04 23:13:54 +01:00
6 changed files with 29 additions and 18 deletions

View File

@ -14,19 +14,20 @@ class App:
self.vm.observer.add(self.on_midi)
def on_midi(self):
self.get_info()
self.on_midi_press()
if self.get_info() == self.MIDI_BUTTON:
self.on_midi_press()
def get_info(self):
current = self.vm.midi.current
print(f"Value of midi button {current} is {self.vm.midi.get(current)}")
return current
def on_midi_press(self):
"""if strip 3 level max > -40 and midi button 48 is pressed, then set trigger for macrobutton 0"""
"""if midi button 48 is pressed and strip 3 level max > -40, then set trigger for macrobutton 0"""
if (
max(self.vm.strip[3].levels.postfader) > -40
and self.vm.midi.get(self.MIDI_BUTTON) == 127
self.vm.midi.get(self.MIDI_BUTTON) == 127
and max(self.vm.strip[3].levels.postfader) > -40
):
print(
f"Strip 3 level max is greater than -40 and midi button {self.MIDI_BUTTON} is pressed"

View File

@ -1,6 +1,6 @@
[tool.poetry]
name = "voicemeeter-api"
version = "2.4.3"
version = "2.4.4"
description = "A Python wrapper for the Voiceemeter API"
authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT"

View File

@ -210,7 +210,7 @@ class BusLevel(IRemote):
def fget(x):
return round(20 * log(x, 10), 1) if x > 0 else -200.0
if self._remote.running and self._remote.event.ldirty:
if not self._remote.stopped() and self._remote.event.ldirty:
vals = self._remote.cache["bus_level"][self.range[0] : self.range[-1]]
else:
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
@ -232,7 +232,7 @@ class BusLevel(IRemote):
Expected to be used in a callback only.
"""
if self._remote.running:
if not self._remote.stopped():
return any(self._remote._bus_comp[self.range[0] : self.range[-1]])
is_updated = isdirty

View File

@ -1,5 +1,6 @@
import ctypes as ct
import logging
import threading
import time
from abc import abstractmethod
from queue import Queue
@ -28,11 +29,11 @@ class Remote(CBindings):
self.cache = {}
self.midi = Midi()
self.subject = self.observer = Subject()
self.running = False
self.event = Event(
{k: kwargs.pop(k) for k in ("pdirty", "mdirty", "midi", "ldirty")}
)
self.gui = VmGui()
self.stop_event = None
self.logger = logger.getChild(self.__class__.__name__)
for attr, val in kwargs.items():
@ -52,16 +53,20 @@ class Remote(CBindings):
def init_thread(self):
"""Starts updates thread."""
self.running = True
self.event.info()
self.logger.debug("initiating events thread")
self.stop_event = threading.Event()
self.stop_event.clear()
queue = Queue()
self.updater = Updater(self, queue)
self.updater.start()
self.producer = Producer(self, queue)
self.producer = Producer(self, queue, self.stop_event)
self.producer.start()
def stopped(self):
return self.stop_event is None or self.stop_event.is_set()
def login(self) -> None:
"""Login to the API, initialize dirty parameters"""
self.gui.launched = self.call(self.bind_login, ok=(0, 1)) == 0
@ -331,9 +336,10 @@ class Remote(CBindings):
self.logger.info(f"Profile '{name}' applied!")
def end_thread(self):
if self.running:
if not self.stopped():
self.logger.debug("events thread shutdown started")
self.running = False
self.stop_event.set()
self.producer.join() # wait for producer thread to complete cycle
def logout(self) -> None:
"""Logout of the API"""

View File

@ -415,7 +415,7 @@ class StripLevel(IRemote):
def fget(x):
return round(20 * log(x, 10), 1) if x > 0 else -200.0
if self._remote.running and self._remote.event.ldirty:
if not self._remote.stopped() and self._remote.event.ldirty:
vals = self._remote.cache["strip_level"][self.range[0] : self.range[-1]]
else:
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
@ -448,7 +448,7 @@ class StripLevel(IRemote):
Expected to be used in a callback only.
"""
if self._remote.running:
if not self._remote.stopped():
return any(self._remote._strip_comp[self.range[0] : self.range[-1]])
is_updated = isdirty

View File

@ -10,14 +10,18 @@ logger = logging.getLogger(__name__)
class Producer(threading.Thread):
"""Continously send job queue to the Updater thread at a rate of self._remote.ratelimit."""
def __init__(self, remote, queue):
super().__init__(name="producer", daemon=True)
def __init__(self, remote, queue, stop_event):
super().__init__(name="producer", daemon=False)
self._remote = remote
self.queue = queue
self.stop_event = stop_event
self.logger = logger.getChild(self.__class__.__name__)
def stopped(self):
return self.stop_event.is_set()
def run(self):
while self._remote.running:
while not self.stopped():
if self._remote.event.pdirty:
self.queue.put("pdirty")
if self._remote.event.mdirty: