mirror of
https://github.com/onyx-and-iris/vban-cmd-python.git
synced 2025-01-18 18:40:47 +00:00
refactor meta functions
add channel_bool_prop and channel_label_prop to strip/bus self.identifier in strip bus now returning only class name add psuedo decorators cache_bool and cache_string to util. fix bug with cache todo. add to cache on multi-set
This commit is contained in:
parent
98c15967d1
commit
3aebd90920
@ -1,8 +1,7 @@
|
|||||||
from .errors import VMCMDErrors
|
from .errors import VMCMDErrors
|
||||||
from . import channel
|
|
||||||
from .channel import Channel
|
from .channel import Channel
|
||||||
from . import kinds
|
from . import kinds
|
||||||
from .meta import bus_mode_prop, bus_bool_prop
|
from .meta import bus_mode_prop, channel_bool_prop, channel_label_prop
|
||||||
|
|
||||||
|
|
||||||
class OutputBus(Channel):
|
class OutputBus(Channel):
|
||||||
@ -22,34 +21,20 @@ class OutputBus(Channel):
|
|||||||
{
|
{
|
||||||
"levels": BusLevel(remote, index),
|
"levels": BusLevel(remote, index),
|
||||||
"mode": BusModeMixin(remote, index),
|
"mode": BusModeMixin(remote, index),
|
||||||
|
**{param: channel_bool_prop(param) for param in ["mute", "mono"]},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return OB_cls(remote, index, *args, **kwargs)
|
return OB_cls(remote, index, *args, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
return f"Bus[{self.index}]"
|
return "bus"
|
||||||
|
|
||||||
mute = bus_bool_prop("mute")
|
eq = channel_bool_prop("eq.On")
|
||||||
|
|
||||||
mono = bus_bool_prop("mono")
|
eq_ab = channel_bool_prop("eq.ab")
|
||||||
|
|
||||||
eq = bus_bool_prop("eq.On")
|
label = channel_label_prop()
|
||||||
|
|
||||||
eq_ab = bus_bool_prop("eq.ab")
|
|
||||||
|
|
||||||
@property
|
|
||||||
def label(self) -> str:
|
|
||||||
val = self.getter("label")
|
|
||||||
if val is None:
|
|
||||||
val = self.public_packet.buslabels[self.index]
|
|
||||||
return val
|
|
||||||
|
|
||||||
@label.setter
|
|
||||||
def label(self, val: str):
|
|
||||||
if not isinstance(val, str):
|
|
||||||
raise VMCMDErrors("label is a string parameter")
|
|
||||||
self.setter("label", val)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gain(self) -> float:
|
def gain(self) -> float:
|
||||||
@ -62,10 +47,10 @@ class OutputBus(Channel):
|
|||||||
else:
|
else:
|
||||||
return ((1 << 16) - 1) - val
|
return ((1 << 16) - 1) - val
|
||||||
|
|
||||||
val = self.getter("gain")
|
val = round(self.getter("gain"), 1)
|
||||||
if val is None:
|
if val is None:
|
||||||
val = round((fget() * 0.01), 1)
|
val = round((fget() * 0.01), 1)
|
||||||
return round(val, 1)
|
return val
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val: float):
|
def gain(self, val: float):
|
||||||
|
@ -11,7 +11,7 @@ class Modes:
|
|||||||
_mute: hex = 0x00000001
|
_mute: hex = 0x00000001
|
||||||
_solo: hex = 0x00000002
|
_solo: hex = 0x00000002
|
||||||
_mono: hex = 0x00000004
|
_mono: hex = 0x00000004
|
||||||
_mutec: hex = 0x00000008
|
_mc: hex = 0x00000008
|
||||||
|
|
||||||
_amix: hex = 0x00000010
|
_amix: hex = 0x00000010
|
||||||
_repeat: hex = 0x00000020
|
_repeat: hex = 0x00000020
|
||||||
@ -85,13 +85,13 @@ class Channel(abc.ABC):
|
|||||||
self._modes = Modes()
|
self._modes = Modes()
|
||||||
|
|
||||||
def getter(self, param):
|
def getter(self, param):
|
||||||
cmd = f"{self.identifier}.{param}"
|
cmd = f"{self.identifier}[{self.index}].{param}"
|
||||||
if cmd in self._remote.cache:
|
if cmd in self._remote.cache:
|
||||||
return self._remote.cache.pop(f"{self.identifier}.{param}")
|
return self._remote.cache.pop(cmd)
|
||||||
|
|
||||||
def setter(self, param, val):
|
def setter(self, param, val):
|
||||||
"""Sends a string request RT packet."""
|
"""Sends a string request RT packet."""
|
||||||
self._remote.set_rt(f"{self.identifier}", param, val)
|
self._remote.set_rt(f"{self.identifier}[{self.index}]", param, val)
|
||||||
|
|
||||||
@abc.abstractmethod
|
@abc.abstractmethod
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
|
@ -1,20 +1,22 @@
|
|||||||
|
from .util import cache_bool, cache_string
|
||||||
from .errors import VMCMDErrors
|
from .errors import VMCMDErrors
|
||||||
from time import sleep
|
|
||||||
|
from functools import partial
|
||||||
|
|
||||||
|
|
||||||
def strip_bool_prop(param):
|
def channel_bool_prop(param):
|
||||||
"""A strip bool prop."""
|
"""A channel bool prop. (strip|bus)"""
|
||||||
|
|
||||||
|
@partial(cache_bool, param=param)
|
||||||
def fget(self):
|
def fget(self):
|
||||||
val = self.getter(param)
|
return (
|
||||||
if val is None:
|
not int.from_bytes(
|
||||||
val = (
|
getattr(self.public_packet, f"{self.identifier}state")[self.index],
|
||||||
not int.from_bytes(self.public_packet.stripstate[self.index], "little")
|
"little",
|
||||||
|
)
|
||||||
& getattr(self._modes, f"_{param}")
|
& getattr(self._modes, f"_{param}")
|
||||||
== 0
|
== 0
|
||||||
)
|
)
|
||||||
return val
|
|
||||||
return val == 1
|
|
||||||
|
|
||||||
def fset(self, val):
|
def fset(self, val):
|
||||||
if not isinstance(val, bool) and val not in (0, 1):
|
if not isinstance(val, bool) and val not in (0, 1):
|
||||||
@ -24,41 +26,31 @@ def strip_bool_prop(param):
|
|||||||
return property(fget, fset)
|
return property(fget, fset)
|
||||||
|
|
||||||
|
|
||||||
def bus_bool_prop(param):
|
def channel_label_prop():
|
||||||
"""A bus bool prop."""
|
"""A channel label prop. (strip|bus)"""
|
||||||
|
|
||||||
def fget(self):
|
@partial(cache_string, param="label")
|
||||||
val = self.getter(param)
|
def fget(self) -> str:
|
||||||
if val is None:
|
return getattr(self.public_packet, f"{self.identifier}labels")[self.index]
|
||||||
val = (
|
|
||||||
not int.from_bytes(self.public_packet.busstate[self.index], "little")
|
|
||||||
& getattr(self._modes, f'_{param.replace(".", "_").lower()}')
|
|
||||||
== 0
|
|
||||||
)
|
|
||||||
return val
|
|
||||||
return val == 1
|
|
||||||
|
|
||||||
def fset(self, val):
|
def fset(self, val: str):
|
||||||
if not isinstance(val, bool) and val not in (0, 1):
|
if not isinstance(val, str):
|
||||||
raise VMCMDErrors(f"{param} is a boolean parameter")
|
raise VMCMDErrors("label is a string parameter")
|
||||||
self.setter(param, 1 if val else 0)
|
self.setter("label", val)
|
||||||
|
|
||||||
return property(fget, fset)
|
return property(fget, fset)
|
||||||
|
|
||||||
|
|
||||||
def strip_output_prop(param):
|
def strip_output_prop(param):
|
||||||
"""A strip output prop."""
|
"""A strip output prop. (A1-A5, B1-B3)"""
|
||||||
|
|
||||||
|
@partial(cache_bool, param=param)
|
||||||
def fget(self):
|
def fget(self):
|
||||||
val = self.getter(param)
|
return (
|
||||||
if val is None:
|
|
||||||
val = (
|
|
||||||
not int.from_bytes(self.public_packet.stripstate[self.index], "little")
|
not int.from_bytes(self.public_packet.stripstate[self.index], "little")
|
||||||
& getattr(self._modes, f"_bus{param.lower()}")
|
& getattr(self._modes, f"_bus{param.lower()}")
|
||||||
== 0
|
== 0
|
||||||
)
|
)
|
||||||
return val
|
|
||||||
return val == 1
|
|
||||||
|
|
||||||
def fset(self, val):
|
def fset(self, val):
|
||||||
if not isinstance(val, bool) and val not in (0, 1):
|
if not isinstance(val, bool) and val not in (0, 1):
|
||||||
@ -71,9 +63,8 @@ def strip_output_prop(param):
|
|||||||
def bus_mode_prop(param):
|
def bus_mode_prop(param):
|
||||||
"""A bus mode prop."""
|
"""A bus mode prop."""
|
||||||
|
|
||||||
|
@partial(cache_bool, param=f"mode.{param}")
|
||||||
def fget(self):
|
def fget(self):
|
||||||
val = self.getter(f"mode.{param}")
|
|
||||||
if val is None:
|
|
||||||
modelist = {
|
modelist = {
|
||||||
"amix": (1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1),
|
"amix": (1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1),
|
||||||
"repeat": (0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2),
|
"repeat": (0, 2, 2, 0, 0, 2, 2, 0, 0, 2, 2),
|
||||||
@ -92,9 +83,8 @@ def bus_mode_prop(param):
|
|||||||
for val in self._modes.modevals
|
for val in self._modes.modevals
|
||||||
)
|
)
|
||||||
if param == "normal":
|
if param == "normal":
|
||||||
return not any(val for val in vals)
|
return not any(vals)
|
||||||
return tuple(round(val / 16) for val in vals) == modelist[param]
|
return tuple(round(val / 16) for val in vals) == modelist[param]
|
||||||
return val == 1
|
|
||||||
|
|
||||||
def fset(self, val):
|
def fset(self, val):
|
||||||
if not isinstance(val, bool) and val not in (0, 1):
|
if not isinstance(val, bool) and val not in (0, 1):
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
from .errors import VMCMDErrors
|
from .errors import VMCMDErrors
|
||||||
from . import channel
|
|
||||||
from .channel import Channel
|
from .channel import Channel
|
||||||
from . import kinds
|
from . import kinds
|
||||||
from .meta import strip_output_prop, strip_bool_prop
|
from .meta import strip_output_prop, channel_bool_prop, channel_label_prop
|
||||||
|
|
||||||
|
|
||||||
class InputStrip(Channel):
|
class InputStrip(Channel):
|
||||||
@ -22,19 +21,19 @@ class InputStrip(Channel):
|
|||||||
(InputStrip, GainLayerMixin),
|
(InputStrip, GainLayerMixin),
|
||||||
{
|
{
|
||||||
"levels": StripLevel(remote, index),
|
"levels": StripLevel(remote, index),
|
||||||
|
**{
|
||||||
|
param: channel_bool_prop(param)
|
||||||
|
for param in ["mono", "solo", "mute"]
|
||||||
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return IS_cls(remote, index, **kwargs)
|
return IS_cls(remote, index, **kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
return f"Strip[{self.index}]"
|
return "strip"
|
||||||
|
|
||||||
mono = strip_bool_prop("mono")
|
label = channel_label_prop()
|
||||||
|
|
||||||
solo = strip_bool_prop("solo")
|
|
||||||
|
|
||||||
mute = strip_bool_prop("mute")
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def limit(self) -> int:
|
def limit(self) -> int:
|
||||||
@ -44,25 +43,12 @@ class InputStrip(Channel):
|
|||||||
def limit(self, val: int):
|
def limit(self, val: int):
|
||||||
self.setter("limit", val)
|
self.setter("limit", val)
|
||||||
|
|
||||||
@property
|
|
||||||
def label(self) -> str:
|
|
||||||
val = self.getter("label")
|
|
||||||
if val is None:
|
|
||||||
val = self.public_packet.striplabels[self.index]
|
|
||||||
return val
|
|
||||||
|
|
||||||
@label.setter
|
|
||||||
def label(self, val: str):
|
|
||||||
if not isinstance(val, str):
|
|
||||||
raise VMCMDErrors("label is a string parameter")
|
|
||||||
self.setter("label", val)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gain(self) -> float:
|
def gain(self) -> float:
|
||||||
val = self.getter("gain")
|
val = round(self.getter("gain"), 1)
|
||||||
if val is None:
|
if val is None:
|
||||||
val = self.gainlayer[0].gain
|
val = self.gainlayer[0].gain
|
||||||
return round(val, 1)
|
return val
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val: float):
|
def gain(self, val: float):
|
||||||
@ -96,23 +82,7 @@ class PhysicalInputStrip(InputStrip):
|
|||||||
|
|
||||||
|
|
||||||
class VirtualInputStrip(InputStrip):
|
class VirtualInputStrip(InputStrip):
|
||||||
@property
|
mc = channel_bool_prop("mc")
|
||||||
def mc(self) -> bool:
|
|
||||||
val = self.getter("mc")
|
|
||||||
if val is None:
|
|
||||||
val = (
|
|
||||||
not int.from_bytes(self.public_packet.stripstate[self.index], "little")
|
|
||||||
& getattr(self._modes, f"_mutec")
|
|
||||||
== 0
|
|
||||||
)
|
|
||||||
return val
|
|
||||||
return val == 1
|
|
||||||
|
|
||||||
@mc.setter
|
|
||||||
def mc(self, val: bool):
|
|
||||||
if not isinstance(val, bool) and val not in (0, 1):
|
|
||||||
raise VMCMDErrors("mc is a boolean parameter")
|
|
||||||
self.setter("mc", 1 if val else 0)
|
|
||||||
|
|
||||||
mono = mc
|
mono = mc
|
||||||
|
|
||||||
@ -169,11 +139,10 @@ class GainLayer(InputStrip):
|
|||||||
else:
|
else:
|
||||||
return ((1 << 16) - 1) - val
|
return ((1 << 16) - 1) - val
|
||||||
|
|
||||||
val = self.getter(f"GainLayer[{self._i}]")
|
val = round(self.getter(f"GainLayer[{self._i}]"), 1)
|
||||||
if val is None:
|
if val is None:
|
||||||
val = round((fget() * 0.01), 1)
|
val = round((fget() * 0.01), 1)
|
||||||
return val
|
return val
|
||||||
return round(val, 1)
|
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val: float):
|
def gain(self, val: float):
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
PROJECT_DIR = str(Path(__file__).parents[1])
|
PROJECT_DIR = str(Path(__file__).parents[1])
|
||||||
|
|
||||||
|
|
||||||
@ -7,14 +8,29 @@ def project_path():
|
|||||||
return PROJECT_DIR
|
return PROJECT_DIR
|
||||||
|
|
||||||
|
|
||||||
def cache(func):
|
def cache_bool(func, param):
|
||||||
"""check if recently cached was an updated value"""
|
"""Check cache for a bool prop"""
|
||||||
|
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
# setup cache check
|
self, *rem = args
|
||||||
res = func(*args, **kwargs)
|
cmd = f"{self.identifier}[{self.index}].{param}"
|
||||||
# update cache
|
if cmd in self._remote.cache:
|
||||||
return res
|
print(self._remote.cache[cmd] == 1)
|
||||||
|
return self._remote.cache.pop(cmd) == 1
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def cache_string(func, param):
|
||||||
|
"""Check cache for a string prop"""
|
||||||
|
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
self, *rem = args
|
||||||
|
cmd = f"{self.identifier}[{self.index}].{param}"
|
||||||
|
if cmd in self._remote.cache:
|
||||||
|
return self._remote.cache.pop(cmd)
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ class VbanCmd(abc.ABC):
|
|||||||
val: Optional[Union[int, float]] = None,
|
val: Optional[Union[int, float]] = None,
|
||||||
):
|
):
|
||||||
"""Sends a string request command over a network."""
|
"""Sends a string request command over a network."""
|
||||||
cmd = id_ if not param and val else f"{id_}.{param}={val}"
|
cmd = id_ if not param else f"{id_}.{param}={val}"
|
||||||
if self._sendrequest_string_socket in self.ready_to_write:
|
if self._sendrequest_string_socket in self.ready_to_write:
|
||||||
self._sendrequest_string_socket.sendto(
|
self._sendrequest_string_socket.sendto(
|
||||||
self._text_header.header + cmd.encode(),
|
self._text_header.header + cmd.encode(),
|
||||||
@ -202,6 +202,7 @@ class VbanCmd(abc.ABC):
|
|||||||
)
|
)
|
||||||
count = int.from_bytes(self._text_header.framecounter, "little") + 1
|
count = int.from_bytes(self._text_header.framecounter, "little") + 1
|
||||||
self._text_header.framecounter = count.to_bytes(4, "little")
|
self._text_header.framecounter = count.to_bytes(4, "little")
|
||||||
|
if param:
|
||||||
self.cache[f"{id_}.{param}"] = val
|
self.cache[f"{id_}.{param}"] = val
|
||||||
if self._sync or self.in_apply:
|
if self._sync or self.in_apply:
|
||||||
sleep(self._delay)
|
sleep(self._delay)
|
||||||
|
Loading…
Reference in New Issue
Block a user