2022-07-24 14:38:16 +01:00
|
|
|
from typing import Optional
|
|
|
|
|
2022-07-16 21:20:56 +01:00
|
|
|
from .iremote import IRemote
|
2022-07-21 23:13:53 +01:00
|
|
|
from .kinds import kinds_all
|
2022-07-16 21:20:56 +01:00
|
|
|
|
|
|
|
|
|
|
|
class FX(IRemote):
|
2022-07-21 23:13:53 +01:00
|
|
|
def __str__(self):
|
|
|
|
return f"{type(self).__name__}"
|
|
|
|
|
2022-07-16 21:20:56 +01:00
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
2022-07-16 23:21:55 +01:00
|
|
|
return "FX"
|
2022-07-16 21:20:56 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def reverb(self) -> bool:
|
|
|
|
return self.getter("reverb.On") == 1
|
|
|
|
|
|
|
|
@reverb.setter
|
|
|
|
def reverb(self, val: bool):
|
|
|
|
self.setter("reverb.On", 1 if val else 0)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def reverb_ab(self) -> bool:
|
|
|
|
return self.getter("reverb.ab") == 1
|
|
|
|
|
|
|
|
@reverb_ab.setter
|
|
|
|
def reverb_ab(self, val: bool):
|
|
|
|
self.setter("reverb.ab", 1 if val else 0)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def delay(self) -> bool:
|
|
|
|
return self.getter("delay.On") == 1
|
|
|
|
|
|
|
|
@delay.setter
|
|
|
|
def delay(self, val: bool):
|
|
|
|
self.setter("delay.On", 1 if val else 0)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def delay_ab(self) -> bool:
|
|
|
|
return self.getter("delay.ab") == 1
|
|
|
|
|
|
|
|
@delay_ab.setter
|
|
|
|
def delay_ab(self, val: bool):
|
|
|
|
self.setter("delay.ab", 1 if val else 0)
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class Patch(IRemote):
|
|
|
|
@classmethod
|
|
|
|
def make(cls, remote):
|
|
|
|
"""
|
|
|
|
Factory method for Patch.
|
|
|
|
|
|
|
|
Mixes in required classes.
|
|
|
|
|
|
|
|
Returns a Patch class of a kind.
|
|
|
|
"""
|
|
|
|
ASIO_cls = _make_asio_mixins(remote)[remote.kind.name]
|
|
|
|
return type(
|
|
|
|
f"Patch{remote.kind}",
|
|
|
|
(cls, ASIO_cls),
|
|
|
|
{
|
|
|
|
"composite": tuple(Composite(remote, i) for i in range(8)),
|
|
|
|
"insert": tuple(Insert(remote, i) for i in range(remote.kind.insert)),
|
|
|
|
},
|
|
|
|
)(remote)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return f"{type(self).__name__}"
|
|
|
|
|
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
|
|
|
return f"patch"
|
|
|
|
|
|
|
|
@property
|
|
|
|
def postfadercomp(self) -> bool:
|
|
|
|
return self.getter("postfadercomposite") == 1
|
|
|
|
|
|
|
|
@postfadercomp.setter
|
|
|
|
def postfadercomp(self, val: bool):
|
|
|
|
self.setter("postfadercomposite", 1 if val else 0)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def postfxinsert(self) -> bool:
|
|
|
|
return self.getter("postfxinsert") == 1
|
|
|
|
|
|
|
|
@postfxinsert.setter
|
|
|
|
def postfxinsert(self, val: bool):
|
|
|
|
self.setter("postfxinsert", 1 if val else 0)
|
|
|
|
|
|
|
|
|
|
|
|
class Asio(IRemote):
|
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
|
|
|
return f"patch"
|
|
|
|
|
|
|
|
|
|
|
|
class AsioIn(Asio):
|
|
|
|
def get(self) -> int:
|
2022-07-22 15:44:36 +01:00
|
|
|
return int(self.getter(f"asio[{self.index}]"))
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
def set(self, val: int):
|
2022-07-22 15:44:36 +01:00
|
|
|
self.setter(f"asio[{self.index}]", val)
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
class AsioOut(Asio):
|
|
|
|
def __init__(self, remote, i, param):
|
|
|
|
IRemote.__init__(self, remote, i)
|
|
|
|
self._param = param
|
|
|
|
|
|
|
|
def get(self) -> int:
|
2022-07-22 15:44:36 +01:00
|
|
|
return int(self.getter(f"out{self._param}[{self.index}]"))
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
def set(self, val: int):
|
2022-07-22 15:44:36 +01:00
|
|
|
self.setter(f"out{self._param}[{self.index}]", val)
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
|
|
|
|
def _make_asio_mixin(remote, kind):
|
|
|
|
"""Creates an ASIO mixin for a kind"""
|
|
|
|
asio_in, asio_out = kind.asio
|
|
|
|
|
|
|
|
return type(
|
|
|
|
f"ASIO{kind}",
|
|
|
|
(IRemote,),
|
|
|
|
{
|
|
|
|
"asio": tuple(AsioIn(remote, i) for i in range(asio_in)),
|
|
|
|
**{
|
|
|
|
param: tuple(AsioOut(remote, i, param) for i in range(asio_out))
|
|
|
|
for param in ["A2", "A3", "A4", "A5"]
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
def _make_asio_mixins(remote):
|
|
|
|
return {kind.name: _make_asio_mixin(remote, kind) for kind in kinds_all}
|
|
|
|
|
|
|
|
|
|
|
|
class Composite(IRemote):
|
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
2022-07-22 15:44:36 +01:00
|
|
|
return "patch"
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
def get(self) -> int:
|
|
|
|
return int(self.getter(f"composite[{self.index}]"))
|
|
|
|
|
|
|
|
def set(self, val: int):
|
|
|
|
self.setter(f"composite[{self.index}]", val)
|
|
|
|
|
|
|
|
|
|
|
|
class Insert(IRemote):
|
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
2022-07-22 15:44:36 +01:00
|
|
|
return "patch"
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def on(self) -> bool:
|
|
|
|
return self.getter(f"insert[{self.index}]") == 1
|
|
|
|
|
|
|
|
@on.setter
|
|
|
|
def on(self, val: bool):
|
|
|
|
self.setter(f"insert[{self.index}]", 1 if val else 0)
|
|
|
|
|
|
|
|
|
|
|
|
class Option(IRemote):
|
|
|
|
@classmethod
|
|
|
|
def make(cls, remote):
|
|
|
|
"""
|
|
|
|
Factory method for Option.
|
|
|
|
|
|
|
|
Mixes in required classes.
|
|
|
|
|
|
|
|
Returns a Option class of a kind.
|
|
|
|
"""
|
|
|
|
return type(
|
|
|
|
f"Option{remote.kind}",
|
|
|
|
(cls,),
|
|
|
|
{
|
|
|
|
"delay": tuple(Delay(remote, i) for i in range(remote.kind.phys_out)),
|
|
|
|
},
|
|
|
|
)(remote)
|
|
|
|
|
|
|
|
def __str__(self):
|
|
|
|
return f"{type(self).__name__}"
|
|
|
|
|
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
2022-07-22 15:44:36 +01:00
|
|
|
return "option"
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
@property
|
|
|
|
def sr(self) -> int:
|
|
|
|
return int(self.getter("sr"))
|
|
|
|
|
|
|
|
@sr.setter
|
|
|
|
def sr(self, val: int):
|
|
|
|
opts = (44100, 48000, 88200, 96000, 176400, 192000)
|
|
|
|
if val not in opts:
|
2023-07-01 19:50:54 +01:00
|
|
|
self.logger.warning(f"sr got: {val} but expected a value in {opts}")
|
2022-07-21 23:13:53 +01:00
|
|
|
self.setter("sr", val)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def asiosr(self) -> bool:
|
|
|
|
return self.getter("asiosr") == 1
|
|
|
|
|
|
|
|
@asiosr.setter
|
|
|
|
def asiosr(self, val: bool):
|
|
|
|
self.setter("asiosr", 1 if val else 0)
|
|
|
|
|
|
|
|
@property
|
|
|
|
def monitoronsel(self) -> bool:
|
|
|
|
return self.getter("monitoronsel") == 1
|
|
|
|
|
|
|
|
@monitoronsel.setter
|
|
|
|
def monitoronsel(self, val: bool):
|
|
|
|
self.setter("monitoronsel", 1 if val else 0)
|
|
|
|
|
|
|
|
def buffer(self, driver, buffer):
|
|
|
|
self.setter(f"buffer.{driver}", buffer)
|
|
|
|
|
|
|
|
|
|
|
|
class Delay(IRemote):
|
|
|
|
@property
|
|
|
|
def identifier(self) -> str:
|
2022-07-22 15:44:36 +01:00
|
|
|
return "option"
|
2022-07-21 23:13:53 +01:00
|
|
|
|
|
|
|
def get(self) -> int:
|
|
|
|
return int(self.getter(f"delay[{self.index}]"))
|
|
|
|
|
|
|
|
def set(self, val: int):
|
|
|
|
self.setter(f"delay[{self.index}]", val)
|
2022-07-24 14:38:16 +01:00
|
|
|
|
|
|
|
|
|
|
|
class Midi:
|
|
|
|
def __init__(self):
|
|
|
|
self._channel = None
|
|
|
|
self.cache = {}
|
|
|
|
self._most_recent = None
|
|
|
|
|
|
|
|
@property
|
|
|
|
def channel(self) -> int:
|
|
|
|
return self._channel
|
|
|
|
|
|
|
|
@property
|
|
|
|
def current(self) -> int:
|
|
|
|
return self._most_recent
|
|
|
|
|
|
|
|
def get(self, key: int) -> Optional[int]:
|
|
|
|
return self.cache.get(key)
|
|
|
|
|
|
|
|
def _set(self, key: int, velocity: int):
|
|
|
|
self.cache[key] = velocity
|
2023-06-29 18:05:07 +01:00
|
|
|
|
|
|
|
|
|
|
|
class VmGui:
|
|
|
|
_launched = None
|
|
|
|
|
|
|
|
@property
|
|
|
|
def launched(self) -> bool:
|
|
|
|
return self._launched
|
|
|
|
|
|
|
|
@launched.setter
|
|
|
|
def launched(self, val: bool):
|
|
|
|
self._launched = val
|
|
|
|
|
|
|
|
@property
|
|
|
|
def launched_by_api(self):
|
|
|
|
return not self.launched
|