mirror of
https://github.com/onyx-and-iris/vban-cmd-python.git
synced 2026-01-24 17:27:48 +00:00
implement 3d parameters
This commit is contained in:
parent
ecbdd2778f
commit
ad88286509
@ -11,7 +11,7 @@ class TestPublicPacketLower:
|
|||||||
|
|
||||||
def test_it_gets_an_rt0_data_packet(self):
|
def test_it_gets_an_rt0_data_packet(self):
|
||||||
assert vban.public_packets[0].voicemeetertype in (
|
assert vban.public_packets[0].voicemeetertype in (
|
||||||
kind.name for kind in kinds.kinds_all
|
kind.name for kind in kinds.all
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -111,4 +111,4 @@ def request_kind_map(kind_id):
|
|||||||
return KIND_obj
|
return KIND_obj
|
||||||
|
|
||||||
|
|
||||||
kinds_all = list(request_kind_map(kind_id.name.lower()) for kind_id in KindId)
|
all = list(request_kind_map(kind_id.name.lower()) for kind_id in KindId)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
|
|
||||||
from .enums import NBS
|
from .enums import NBS
|
||||||
from .util import cache_bool, cache_string
|
from .util import cache_bool, cache_float, cache_string
|
||||||
|
|
||||||
|
|
||||||
def channel_bool_prop(param):
|
def channel_bool_prop(param):
|
||||||
@ -97,3 +97,46 @@ def action_fn(param, val=1):
|
|||||||
self.setter(param, val)
|
self.setter(param, val)
|
||||||
|
|
||||||
return fdo
|
return fdo
|
||||||
|
|
||||||
|
|
||||||
|
def xy_prop(param):
|
||||||
|
"""meta function for XY pad parameters"""
|
||||||
|
|
||||||
|
@partial(cache_float, param=param)
|
||||||
|
def fget(self):
|
||||||
|
cmd = self._cmd(param)
|
||||||
|
self.logger.debug(f'getter: {cmd}')
|
||||||
|
_type, axis = param.split('_')
|
||||||
|
if self.public_packets[NBS.one] is None:
|
||||||
|
return 0.0
|
||||||
|
x, y = getattr(
|
||||||
|
self.public_packets[NBS.one].strips[self.index], f'position_{_type.lower()}'
|
||||||
|
)
|
||||||
|
return x if axis == 'x' else y
|
||||||
|
|
||||||
|
def fset(self, val):
|
||||||
|
self.setter(param, val)
|
||||||
|
|
||||||
|
return property(fget, fset)
|
||||||
|
|
||||||
|
|
||||||
|
def send_prop(param):
|
||||||
|
"""meta function for send parameters"""
|
||||||
|
|
||||||
|
@partial(cache_float, param=param)
|
||||||
|
def fget(self):
|
||||||
|
cmd = self._cmd(param)
|
||||||
|
self.logger.debug(f'getter: {cmd}')
|
||||||
|
if self.public_packets[NBS.one] is None:
|
||||||
|
return 0.0
|
||||||
|
val = getattr(self.public_packets[NBS.one].strips[self.index], f'send_{param}')
|
||||||
|
match param:
|
||||||
|
case 'reverb' | 'fx1':
|
||||||
|
return val[0]
|
||||||
|
case 'delay' | 'fx2':
|
||||||
|
return val[1]
|
||||||
|
|
||||||
|
def fset(self, val):
|
||||||
|
self.setter(param, val)
|
||||||
|
|
||||||
|
return property(fget, fset)
|
||||||
|
|||||||
@ -365,6 +365,45 @@ class VbanVMParamStrip:
|
|||||||
def mode(self) -> int:
|
def mode(self) -> int:
|
||||||
return int.from_bytes(self._mode, 'little')
|
return int.from_bytes(self._mode, 'little')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position_pan(self) -> tuple[int, int]:
|
||||||
|
return (
|
||||||
|
round(int.from_bytes(self._pos3D_x, 'little', signed=True) * 0.01, 2),
|
||||||
|
round(int.from_bytes(self._pos3D_y, 'little', signed=True) * 0.01, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position_color(self) -> tuple[int, int]:
|
||||||
|
return (
|
||||||
|
round(int.from_bytes(self._posColor_x, 'little', signed=True) * 0.01, 2),
|
||||||
|
round(int.from_bytes(self._posColor_y, 'little', signed=True) * 0.01, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def position_fx(self) -> tuple[int, int]:
|
||||||
|
return (
|
||||||
|
round(int.from_bytes(self._posMod_x, 'little', signed=True) * 0.01, 2),
|
||||||
|
round(int.from_bytes(self._posMod_y, 'little', signed=True) * 0.01, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def send_reverb(self) -> tuple[float, float]:
|
||||||
|
return (
|
||||||
|
round(int.from_bytes(self._send_reverb, 'little', signed=True) * 0.01, 2),
|
||||||
|
round(int.from_bytes(self._send_delay, 'little', signed=True) * 0.01, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
send_delay = send_reverb
|
||||||
|
|
||||||
|
@property
|
||||||
|
def send_fx1(self) -> tuple[float, float]:
|
||||||
|
return (
|
||||||
|
round(int.from_bytes(self._send_fx1, 'little', signed=True) * 0.01, 2),
|
||||||
|
round(int.from_bytes(self._send_fx2, 'little', signed=True) * 0.01, 2),
|
||||||
|
)
|
||||||
|
|
||||||
|
send_fx2 = send_fx1
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def eqgains(self) -> tuple[float, float, float]:
|
def eqgains(self) -> tuple[float, float, float]:
|
||||||
return tuple(
|
return tuple(
|
||||||
|
|||||||
@ -2,10 +2,16 @@ import time
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
|
from . import kinds
|
||||||
from .enums import NBS, EQGains
|
from .enums import NBS, EQGains
|
||||||
from .iremote import IRemote
|
from .iremote import IRemote
|
||||||
from .kinds import kinds_all
|
from .meta import (
|
||||||
from .meta import channel_bool_prop, channel_label_prop, strip_output_prop
|
channel_bool_prop,
|
||||||
|
channel_label_prop,
|
||||||
|
send_prop,
|
||||||
|
strip_output_prop,
|
||||||
|
xy_prop,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Strip(IRemote):
|
class Strip(IRemote):
|
||||||
@ -53,10 +59,11 @@ class Strip(IRemote):
|
|||||||
|
|
||||||
class PhysicalStrip(Strip):
|
class PhysicalStrip(Strip):
|
||||||
@classmethod
|
@classmethod
|
||||||
def make(cls, remote, index):
|
def make(cls, remote, index, is_phys):
|
||||||
|
EFFECTS_cls = _make_effects_mixins(is_phys)[remote.kind.name]
|
||||||
return type(
|
return type(
|
||||||
f'PhysicalStrip{remote.kind}',
|
f'PhysicalStrip{remote.kind}',
|
||||||
(cls,),
|
(cls, EFFECTS_cls),
|
||||||
{
|
{
|
||||||
'comp': StripComp(remote, index),
|
'comp': StripComp(remote, index),
|
||||||
'gate': StripGate(remote, index),
|
'gate': StripGate(remote, index),
|
||||||
@ -254,6 +261,20 @@ class StripEQ(IRemote):
|
|||||||
|
|
||||||
|
|
||||||
class VirtualStrip(Strip):
|
class VirtualStrip(Strip):
|
||||||
|
@classmethod
|
||||||
|
def make(cls, remote, i, is_phys):
|
||||||
|
"""
|
||||||
|
Factory method for VirtualStrip.
|
||||||
|
|
||||||
|
Returns a VirtualStrip class.
|
||||||
|
"""
|
||||||
|
EFFECTS_cls = _make_effects_mixins(is_phys)[remote.kind.name]
|
||||||
|
return type(
|
||||||
|
'VirtualStrip',
|
||||||
|
(cls, EFFECTS_cls),
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f'{type(self).__name__}{self.index}'
|
return f'{type(self).__name__}{self.index}'
|
||||||
|
|
||||||
@ -432,10 +453,64 @@ def _make_channelout_mixin(kind):
|
|||||||
|
|
||||||
|
|
||||||
_make_channelout_mixins = {
|
_make_channelout_mixins = {
|
||||||
kind.name: _make_channelout_mixin(kind) for kind in kinds_all
|
kind.name: _make_channelout_mixin(kind) for kind in kinds.all
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def _make_effects_mixin(kind, is_phys):
|
||||||
|
"""creates an effects mixin for a kind"""
|
||||||
|
|
||||||
|
def _make_xy_cls():
|
||||||
|
pan = {param: xy_prop(param) for param in ['pan_x', 'pan_y']}
|
||||||
|
color = {param: xy_prop(param) for param in ['color_x', 'color_y']}
|
||||||
|
fx = {param: xy_prop(param) for param in ['fx_x', 'fx_y']}
|
||||||
|
if is_phys:
|
||||||
|
return type(
|
||||||
|
'XYPhys',
|
||||||
|
(),
|
||||||
|
{
|
||||||
|
**pan,
|
||||||
|
**color,
|
||||||
|
**fx,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return type(
|
||||||
|
'XYVirt',
|
||||||
|
(),
|
||||||
|
{**pan},
|
||||||
|
)
|
||||||
|
|
||||||
|
def _make_sends_cls():
|
||||||
|
if is_phys:
|
||||||
|
return type(
|
||||||
|
'FX',
|
||||||
|
(),
|
||||||
|
{
|
||||||
|
**{
|
||||||
|
param: send_prop(param)
|
||||||
|
for param in ['reverb', 'delay', 'fx1', 'fx2']
|
||||||
|
},
|
||||||
|
# **{
|
||||||
|
# f'post{param}': bool_prop(f'post{param}')
|
||||||
|
# for param in ['reverb', 'delay', 'fx1', 'fx2']
|
||||||
|
# },
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return type('FX', (), {})
|
||||||
|
|
||||||
|
if kind.name == 'basic':
|
||||||
|
steps = (_make_xy_cls,)
|
||||||
|
elif kind.name == 'banana':
|
||||||
|
steps = (_make_xy_cls,)
|
||||||
|
elif kind.name == 'potato':
|
||||||
|
steps = (_make_xy_cls, _make_sends_cls)
|
||||||
|
return type(f'Effects{kind}', tuple(step() for step in steps), {})
|
||||||
|
|
||||||
|
|
||||||
|
def _make_effects_mixins(is_phys):
|
||||||
|
return {kind.name: _make_effects_mixin(kind, is_phys) for kind in kinds.all}
|
||||||
|
|
||||||
|
|
||||||
def strip_factory(is_phys_strip, remote, i) -> Union[PhysicalStrip, VirtualStrip]:
|
def strip_factory(is_phys_strip, remote, i) -> Union[PhysicalStrip, VirtualStrip]:
|
||||||
"""
|
"""
|
||||||
Factory method for strips
|
Factory method for strips
|
||||||
@ -444,7 +519,11 @@ def strip_factory(is_phys_strip, remote, i) -> Union[PhysicalStrip, VirtualStrip
|
|||||||
|
|
||||||
Returns a physical or virtual strip subclass
|
Returns a physical or virtual strip subclass
|
||||||
"""
|
"""
|
||||||
STRIP_cls = PhysicalStrip.make(remote, i) if is_phys_strip else VirtualStrip
|
STRIP_cls = (
|
||||||
|
PhysicalStrip.make(remote, i, is_phys_strip)
|
||||||
|
if is_phys_strip
|
||||||
|
else VirtualStrip.make(remote, i, is_phys_strip)
|
||||||
|
)
|
||||||
CHANNELOUTMIXIN_cls = _make_channelout_mixins[remote.kind.name]
|
CHANNELOUTMIXIN_cls = _make_channelout_mixins[remote.kind.name]
|
||||||
GAINLAYERMIXIN_cls = _make_gainlayer_mixin(remote, i)
|
GAINLAYERMIXIN_cls = _make_gainlayer_mixin(remote, i)
|
||||||
|
|
||||||
|
|||||||
@ -29,6 +29,20 @@ def cache_string(func, param):
|
|||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
|
def cache_float(func, param):
|
||||||
|
"""Check cache for a float prop"""
|
||||||
|
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
self, *rem = args
|
||||||
|
if self._cmd(param) in self._remote.cache:
|
||||||
|
return round(self._remote.cache.pop(self._cmd(param)), 2)
|
||||||
|
if self._remote.sync:
|
||||||
|
self._remote.clear_dirty()
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|
||||||
|
|
||||||
def depth(d):
|
def depth(d):
|
||||||
if isinstance(d, dict):
|
if isinstance(d, dict):
|
||||||
return 1 + (max(map(depth, d.values())) if d else 0)
|
return 1 + (max(map(depth, d.values())) if d else 0)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from . import kinds
|
||||||
from .iremote import IRemote
|
from .iremote import IRemote
|
||||||
from .kinds import kinds_all
|
|
||||||
|
|
||||||
|
|
||||||
class VbanStream(IRemote):
|
class VbanStream(IRemote):
|
||||||
@ -194,7 +194,7 @@ def _make_stream_pair(remote, kind):
|
|||||||
|
|
||||||
|
|
||||||
def _make_stream_pairs(remote):
|
def _make_stream_pairs(remote):
|
||||||
return {kind.name: _make_stream_pair(remote, kind) for kind in kinds_all}
|
return {kind.name: _make_stream_pair(remote, kind) for kind in kinds.all}
|
||||||
|
|
||||||
|
|
||||||
class Vban:
|
class Vban:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user