mirror of
				https://github.com/onyx-and-iris/voicemeeter-api-python.git
				synced 2025-11-04 15:41:48 +00:00 
			
		
		
		
	refactor levels.
only compute strip/bus comp tuples if ldirty. add comp generator function to util. added some docstrings patch bump
This commit is contained in:
		
							parent
							
								
									210c75ed5f
								
							
						
					
					
						commit
						e979595a09
					
				@ -1,6 +1,6 @@
 | 
			
		||||
[tool.poetry]
 | 
			
		||||
name = "voicemeeter-api"
 | 
			
		||||
version = "0.2.2"
 | 
			
		||||
version = "0.2.3"
 | 
			
		||||
description = "A Python wrapper for the Voiceemeter API"
 | 
			
		||||
authors = ["onyx-and-iris <code@onyxandiris.online>"]
 | 
			
		||||
license = "MIT"
 | 
			
		||||
 | 
			
		||||
@ -9,7 +9,7 @@ from .cbindings import CBindings
 | 
			
		||||
from .error import VMError
 | 
			
		||||
from .kinds import KindId
 | 
			
		||||
from .subject import Subject
 | 
			
		||||
from .util import polling, script
 | 
			
		||||
from .util import comp, polling, script
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Remote(CBindings):
 | 
			
		||||
@ -44,7 +44,13 @@ class Remote(CBindings):
 | 
			
		||||
        t.start()
 | 
			
		||||
 | 
			
		||||
    def _updates(self):
 | 
			
		||||
        """Continously update observers of dirty states."""
 | 
			
		||||
        """
 | 
			
		||||
        Continously update observers of dirty states.
 | 
			
		||||
 | 
			
		||||
        Generate _strip_comp, _bus_comp and update level cache if ldirty.
 | 
			
		||||
 | 
			
		||||
        Runs updates at a rate of self.ratelimit.
 | 
			
		||||
        """
 | 
			
		||||
        self.cache["strip_level"], self.cache["bus_level"] = self._get_levels()
 | 
			
		||||
 | 
			
		||||
        while self.running:
 | 
			
		||||
@ -53,6 +59,12 @@ class Remote(CBindings):
 | 
			
		||||
            if self.mdirty:
 | 
			
		||||
                self.subject.notify("mdirty")
 | 
			
		||||
            if self.ldirty:
 | 
			
		||||
                self._strip_comp, self._bus_comp = (
 | 
			
		||||
                    tuple(
 | 
			
		||||
                        not x for x in comp(self.cache["strip_level"], self._strip_buf)
 | 
			
		||||
                    ),
 | 
			
		||||
                    tuple(not x for x in comp(self.cache["bus_level"], self._bus_buf)),
 | 
			
		||||
                )
 | 
			
		||||
                self.cache["strip_level"] = self._strip_buf
 | 
			
		||||
                self.cache["bus_level"] = self._bus_buf
 | 
			
		||||
                self.subject.notify("ldirty")
 | 
			
		||||
@ -110,16 +122,10 @@ class Remote(CBindings):
 | 
			
		||||
    def ldirty(self) -> bool:
 | 
			
		||||
        """True iff levels have been updated."""
 | 
			
		||||
        self._strip_buf, self._bus_buf = self._get_levels()
 | 
			
		||||
        self._strip_comp, self._bus_comp = (
 | 
			
		||||
            tuple(
 | 
			
		||||
                not a == b
 | 
			
		||||
                for a, b in zip(self.cache.get("strip_level"), self._strip_buf)
 | 
			
		||||
            ),
 | 
			
		||||
            tuple(
 | 
			
		||||
                not a == b for a, b in zip(self.cache.get("bus_level"), self._bus_buf)
 | 
			
		||||
            ),
 | 
			
		||||
        return not (
 | 
			
		||||
            self.cache.get("strip_level") == self._strip_buf
 | 
			
		||||
            and self.cache.get("bus_level") == self._bus_buf
 | 
			
		||||
        )
 | 
			
		||||
        return any(any(l) for l in (self._strip_comp, self._bus_comp))
 | 
			
		||||
 | 
			
		||||
    def clear_dirty(self):
 | 
			
		||||
        while self.pdirty or self.mdirty:
 | 
			
		||||
 | 
			
		||||
@ -116,16 +116,21 @@ class BusLevel(IRemote):
 | 
			
		||||
        self.range = self.level_map[self.index]
 | 
			
		||||
 | 
			
		||||
    def getter(self, mode):
 | 
			
		||||
        """Returns a tuple of level values for the channel."""
 | 
			
		||||
        """
 | 
			
		||||
        Returns a tuple of level values for the channel.
 | 
			
		||||
 | 
			
		||||
        If observables thread running fetch values from cache otherwise call CAPI func.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        def fget(i):
 | 
			
		||||
            if self._remote.running and "bus_level" in self._remote.cache:
 | 
			
		||||
                res = self._remote.cache["bus_level"][i]
 | 
			
		||||
            else:
 | 
			
		||||
                res = self._remote.get_level(mode, i)
 | 
			
		||||
            return round(20 * log(res, 10), 1) if res > 0 else -200.0
 | 
			
		||||
            return round(20 * log(i, 10), 1) if i > 0 else -200.0
 | 
			
		||||
 | 
			
		||||
        return tuple(fget(i) for i in range(*self.range))
 | 
			
		||||
        if self._remote.running and "bus_level" in self._remote.cache:
 | 
			
		||||
            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)]
 | 
			
		||||
 | 
			
		||||
        return tuple(fget(i) for i in vals)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def identifier(self) -> str:
 | 
			
		||||
@ -137,6 +142,12 @@ class BusLevel(IRemote):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_updated(self) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Returns dirty status for this specific channel.
 | 
			
		||||
 | 
			
		||||
        Expected to be used in a callback only.
 | 
			
		||||
        """
 | 
			
		||||
        if self._remote.running:
 | 
			
		||||
            return any(self._remote._bus_comp[self.range[0] : self.range[-1]])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -189,16 +189,21 @@ class StripLevel(IRemote):
 | 
			
		||||
        self.range = self.level_map[self.index]
 | 
			
		||||
 | 
			
		||||
    def getter(self, mode):
 | 
			
		||||
        """Returns a tuple of level values for the channel."""
 | 
			
		||||
        """
 | 
			
		||||
        Returns a tuple of level values for the channel.
 | 
			
		||||
 | 
			
		||||
        If observables thread running fetch values from cache otherwise call CAPI func.
 | 
			
		||||
        """
 | 
			
		||||
 | 
			
		||||
        def fget(i):
 | 
			
		||||
            if self._remote.running and "strip_level" in self._remote.cache:
 | 
			
		||||
                res = self._remote.cache["strip_level"][i]
 | 
			
		||||
            else:
 | 
			
		||||
                res = self._remote.get_level(mode, i)
 | 
			
		||||
            return round(20 * log(res, 10), 1) if res > 0 else -200.0
 | 
			
		||||
            return round(20 * log(i, 10), 1) if i > 0 else -200.0
 | 
			
		||||
 | 
			
		||||
        return tuple(fget(i) for i in range(*self.range))
 | 
			
		||||
        if self._remote.running and "strip_level" in self._remote.cache:
 | 
			
		||||
            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)]
 | 
			
		||||
 | 
			
		||||
        return tuple(fget(i) for i in vals)
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def identifier(self) -> str:
 | 
			
		||||
@ -221,6 +226,12 @@ class StripLevel(IRemote):
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def is_updated(self) -> bool:
 | 
			
		||||
        """
 | 
			
		||||
        Returns dirty status for this specific channel.
 | 
			
		||||
 | 
			
		||||
        Expected to be used in a callback only.
 | 
			
		||||
        """
 | 
			
		||||
        if self._remote.running:
 | 
			
		||||
            return any(self._remote._strip_comp[self.range[0] : self.range[-1]])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import functools
 | 
			
		||||
from typing import Iterator
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def polling(func):
 | 
			
		||||
@ -50,3 +51,13 @@ def script(func):
 | 
			
		||||
        return func(remote, script)
 | 
			
		||||
 | 
			
		||||
    return wrapper
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def comp(t0: tuple, t1: tuple) -> Iterator[bool]:
 | 
			
		||||
    """
 | 
			
		||||
    Generator function, accepts two tuples.
 | 
			
		||||
 | 
			
		||||
    Evaluates equality of each member in both tuples.
 | 
			
		||||
    """
 | 
			
		||||
    for a, b in zip(t0, t1):
 | 
			
		||||
        yield a == b
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user