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) self.vm.observer.add(self.on_midi)
def on_midi(self): def on_midi(self):
self.get_info() if self.get_info() == self.MIDI_BUTTON:
self.on_midi_press() self.on_midi_press()
def get_info(self): def get_info(self):
current = self.vm.midi.current current = self.vm.midi.current
print(f"Value of midi button {current} is {self.vm.midi.get(current)}") print(f"Value of midi button {current} is {self.vm.midi.get(current)}")
return current
def on_midi_press(self): 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 ( if (
max(self.vm.strip[3].levels.postfader) > -40 self.vm.midi.get(self.MIDI_BUTTON) == 127
and self.vm.midi.get(self.MIDI_BUTTON) == 127 and max(self.vm.strip[3].levels.postfader) > -40
): ):
print( print(
f"Strip 3 level max is greater than -40 and midi button {self.MIDI_BUTTON} is pressed" 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] [tool.poetry]
name = "voicemeeter-api" name = "voicemeeter-api"
version = "2.4.3" version = "2.4.4"
description = "A Python wrapper for the Voiceemeter API" description = "A Python wrapper for the Voiceemeter API"
authors = ["onyx-and-iris <code@onyxandiris.online>"] authors = ["onyx-and-iris <code@onyxandiris.online>"]
license = "MIT" license = "MIT"

View File

@ -210,7 +210,7 @@ class BusLevel(IRemote):
def fget(x): def fget(x):
return round(20 * log(x, 10), 1) if x > 0 else -200.0 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]] vals = self._remote.cache["bus_level"][self.range[0] : self.range[-1]]
else: else:
vals = [self._remote.get_level(mode, i) for i in range(*self.range)] 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. 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]]) return any(self._remote._bus_comp[self.range[0] : self.range[-1]])
is_updated = isdirty is_updated = isdirty

View File

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

View File

@ -415,7 +415,7 @@ class StripLevel(IRemote):
def fget(x): def fget(x):
return round(20 * log(x, 10), 1) if x > 0 else -200.0 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]] vals = self._remote.cache["strip_level"][self.range[0] : self.range[-1]]
else: else:
vals = [self._remote.get_level(mode, i) for i in range(*self.range)] 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. 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]]) return any(self._remote._strip_comp[self.range[0] : self.range[-1]])
is_updated = isdirty is_updated = isdirty

View File

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