mirror of
https://github.com/onyx-and-iris/vban-cmd-python.git
synced 2024-11-15 17:10:46 +00:00
6c914dafbe
add login, logout functions to base class. add caching to setters and fetch caching to getters. add isdirty function to rt packet dataclass for defining dirty flag. remove sync kwarg.
206 lines
5.7 KiB
Python
206 lines
5.7 KiB
Python
from .errors import VMCMDErrors
|
|
from . import channel
|
|
from .channel import Channel
|
|
from . import kinds
|
|
from .meta import strip_output_prop, strip_bool_prop
|
|
|
|
class InputStrip(Channel):
|
|
""" Base class for input strips. """
|
|
@classmethod
|
|
def make(cls, is_physical, remote, index, **kwargs):
|
|
"""
|
|
Factory function for input strips.
|
|
Returns a physical/virtual strip of a kind.
|
|
"""
|
|
PhysStrip, VirtStrip = _strip_pairs[remote.kind.id]
|
|
InputStrip = PhysStrip if is_physical else VirtStrip
|
|
GainLayerMixin = _make_gainlayer_mixin(remote, index)
|
|
IS_cls = type(f'Strip{remote.kind.name}', (InputStrip, GainLayerMixin), {
|
|
'levels': StripLevel(remote, index),
|
|
})
|
|
return IS_cls(remote, index, **kwargs)
|
|
|
|
@property
|
|
def identifier(self):
|
|
return f'Strip[{self.index}]'
|
|
|
|
mono = strip_bool_prop('mono')
|
|
|
|
solo = strip_bool_prop('solo')
|
|
|
|
mute = strip_bool_prop('mute')
|
|
|
|
@property
|
|
def limit(self) -> int:
|
|
return
|
|
|
|
@limit.setter
|
|
def limit(self, val: int):
|
|
if val not in range(-40,13):
|
|
raise VMCMDErrors('Expected value from -40 to 12')
|
|
self.setter('limit', val)
|
|
|
|
@property
|
|
def label(self) -> str:
|
|
val = self.getter('label')
|
|
if val is None:
|
|
val = self.public_packet.striplabels[self.index]
|
|
self._remote.cache[f'{self.identifier}.label'] = [val, False]
|
|
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
|
|
def gain(self) -> float:
|
|
val = self.getter('GainLayer[0]')
|
|
if val is None:
|
|
val = self.gainlayer[0].gain
|
|
self._remote.cache[f'{self.identifier}.GainLayer[0]'] = [val, False]
|
|
return round(val, 1)
|
|
|
|
@gain.setter
|
|
def gain(self, val: float):
|
|
self.setter('gain', val)
|
|
|
|
|
|
class PhysicalInputStrip(InputStrip):
|
|
@property
|
|
def comp(self) -> float:
|
|
return
|
|
|
|
@comp.setter
|
|
def comp(self, val: float):
|
|
self.setter('Comp', val)
|
|
|
|
@property
|
|
def gate(self) -> float:
|
|
return
|
|
|
|
@gate.setter
|
|
def gate(self, val: float):
|
|
self.setter('gate', val)
|
|
|
|
@property
|
|
def device(self):
|
|
return
|
|
|
|
@property
|
|
def sr(self):
|
|
return
|
|
|
|
|
|
class VirtualInputStrip(InputStrip):
|
|
@property
|
|
def mc(self) -> bool:
|
|
return
|
|
|
|
@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
|
|
|
|
@property
|
|
def k(self) -> int:
|
|
return
|
|
|
|
@k.setter
|
|
def k(self, val: int):
|
|
if val not in range(5):
|
|
raise VMCMDErrors('Expected value from 0 to 4')
|
|
self.setter('karaoke', val)
|
|
|
|
|
|
class StripLevel(InputStrip):
|
|
def __init__(self, remote, index):
|
|
super().__init__(remote, index)
|
|
self.level_map = _strip_maps[remote.kind.id]
|
|
|
|
def getter_level(self, mode=None):
|
|
def fget(i, data):
|
|
val = data.inputlevels[i]
|
|
return -val * 0.01
|
|
|
|
range_ = self.level_map[self.index]
|
|
data = self.public_packet
|
|
levels = tuple(round(fget(i, data), 1) for i in range(*range_))
|
|
return levels
|
|
|
|
@property
|
|
def prefader(self) -> tuple:
|
|
return self.getter_level()
|
|
|
|
@property
|
|
def postfader(self) -> tuple:
|
|
return
|
|
|
|
@property
|
|
def postmute(self) -> tuple:
|
|
return
|
|
|
|
|
|
class GainLayer(InputStrip):
|
|
def __init__(self, remote, index, i):
|
|
super().__init__(remote, index)
|
|
self._i = i
|
|
|
|
@property
|
|
def gain(self) -> float:
|
|
def fget():
|
|
val = getattr(self.public_packet, f'stripgainlayer{self._i+1}')[self.index]
|
|
if val < 10000:
|
|
return -val
|
|
elif val == ((1 << 16) - 1):
|
|
return 0
|
|
else:
|
|
return ((1 << 16) - 1) - val
|
|
val = self.getter(f'GainLayer[{self._i}]')
|
|
if val is None:
|
|
val = round((fget() * 0.01), 1)
|
|
self._remote.cache[f'{self.identifier}.GainLayer[{self._i}]'] = [val, False]
|
|
return val
|
|
return round(val, 1)
|
|
|
|
@gain.setter
|
|
def gain(self, val: float):
|
|
self.setter(f'GainLayer[{self._i}]', val)
|
|
|
|
|
|
def _make_gainlayer_mixin(remote, index):
|
|
""" Creates a GainLayer mixin """
|
|
return type(f'GainlayerMixin', (), {
|
|
'gainlayer': tuple(GainLayer(remote, index, i) for i in range(8))
|
|
})
|
|
|
|
def _make_strip_mixin(kind):
|
|
""" Creates a mixin with the kind's strip layout set as class variables. """
|
|
num_A, num_B = kind.outs
|
|
return type(f'StripMixin{kind.name}', (), {
|
|
**{f'A{i}': strip_output_prop(f'A{i}') for i in range(1, num_A+1)},
|
|
**{f'B{i}': strip_output_prop(f'B{i}') for i in range(1, num_B+1)}
|
|
})
|
|
|
|
_strip_mixins = {kind.id: _make_strip_mixin(kind) for kind in kinds.all}
|
|
|
|
def _make_strip_pair(kind):
|
|
""" Creates a PhysicalInputStrip and a VirtualInputStrip of a kind. """
|
|
StripMixin = _strip_mixins[kind.id]
|
|
PhysStrip = type(f'PhysicalInputStrip{kind.name}', (PhysicalInputStrip, StripMixin), {})
|
|
VirtStrip = type(f'VirtualInputStrip{kind.name}', (VirtualInputStrip, StripMixin), {})
|
|
return (PhysStrip, VirtStrip)
|
|
|
|
_strip_pairs = {kind.id: _make_strip_pair(kind) for kind in kinds.all}
|
|
|
|
def _make_strip_level_map(kind):
|
|
phys_in, virt_in = kind.ins
|
|
phys_map = tuple((i, i+2) for i in range(0, phys_in*2, 2))
|
|
virt_map = tuple((i, i+8) for i in range(phys_in*2, phys_in*2+virt_in*8, 8))
|
|
return phys_map+virt_map
|
|
|
|
_strip_maps = {kind.id: _make_strip_level_map(kind) for kind in kinds.all}
|