mirror of
https://github.com/onyx-and-iris/voicemeeter-api-python.git
synced 2025-01-18 09:00:48 +00:00
re-run through ruff formatter
This commit is contained in:
parent
7b725a51e3
commit
da1d5132a8
53
README.md
53
README.md
@ -44,24 +44,24 @@ class ManyThings:
|
|||||||
self.vm = vm
|
self.vm = vm
|
||||||
|
|
||||||
def things(self):
|
def things(self):
|
||||||
self.vm.strip[0].label = "podmic"
|
self.vm.strip[0].label = 'podmic'
|
||||||
self.vm.strip[0].mute = True
|
self.vm.strip[0].mute = True
|
||||||
print(
|
print(
|
||||||
f"strip 0 ({self.vm.strip[0].label}) mute has been set to {self.vm.strip[0].mute}"
|
f'strip 0 ({self.vm.strip[0].label}) mute has been set to {self.vm.strip[0].mute}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def other_things(self):
|
def other_things(self):
|
||||||
self.vm.bus[3].gain = -6.3
|
self.vm.bus[3].gain = -6.3
|
||||||
self.vm.bus[4].eq.on = True
|
self.vm.bus[4].eq.on = True
|
||||||
info = (
|
info = (
|
||||||
f"bus 3 gain has been set to {self.vm.bus[3].gain}",
|
f'bus 3 gain has been set to {self.vm.bus[3].gain}',
|
||||||
f"bus 4 eq has been set to {self.vm.bus[4].eq.on}",
|
f'bus 4 eq has been set to {self.vm.bus[4].eq.on}',
|
||||||
)
|
)
|
||||||
print("\n".join(info))
|
print('\n'.join(info))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
KIND_ID = "banana"
|
KIND_ID = 'banana'
|
||||||
|
|
||||||
with voicemeeterlib.api(KIND_ID) as vm:
|
with voicemeeterlib.api(KIND_ID) as vm:
|
||||||
do = ManyThings(vm)
|
do = ManyThings(vm)
|
||||||
@ -71,18 +71,17 @@ def main():
|
|||||||
# set many parameters at once
|
# set many parameters at once
|
||||||
vm.apply(
|
vm.apply(
|
||||||
{
|
{
|
||||||
"strip-2": {"A1": True, "B1": True, "gain": -6.0},
|
'strip-2': {'A1': True, 'B1': True, 'gain': -6.0},
|
||||||
"bus-2": {"mute": True, "eq": {"on": True}},
|
'bus-2': {'mute': True, 'eq': {'on': True}},
|
||||||
"button-0": {"state": True},
|
'button-0': {'state': True},
|
||||||
"vban-in-0": {"on": True},
|
'vban-in-0': {'on': True},
|
||||||
"vban-out-1": {"name": "streamname"},
|
'vban-out-1': {'name': 'streamname'},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Otherwise you must remember to call `vm.login()`, `vm.logout()` at the start/end of your code.
|
Otherwise you must remember to call `vm.login()`, `vm.logout()` at the start/end of your code.
|
||||||
@ -149,8 +148,8 @@ Set mute state as value for the app matching name.
|
|||||||
example:
|
example:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
vm.strip[5].appmute("Spotify", True)
|
vm.strip[5].appmute('Spotify', True)
|
||||||
vm.strip[5].appgain("Spotify", 0.5)
|
vm.strip[5].appgain('Spotify', 0.5)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Strip.Comp
|
#### Strip.Comp
|
||||||
@ -366,7 +365,7 @@ example:
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
print(vm.strip[0].device.name)
|
print(vm.strip[0].device.name)
|
||||||
vm.bus[0].device.asio = "Audient USB Audio ASIO Driver"
|
vm.bus[0].device.asio = 'Audient USB Audio ASIO Driver'
|
||||||
```
|
```
|
||||||
|
|
||||||
strip|bus device parameters are defined for physical channels only.
|
strip|bus device parameters are defined for physical channels only.
|
||||||
@ -425,7 +424,7 @@ vm.recorder.B2 = False
|
|||||||
vm.recorder.load(r'C:\music\mytune.mp3')
|
vm.recorder.load(r'C:\music\mytune.mp3')
|
||||||
|
|
||||||
# set the goto time to 1m 30s
|
# set the goto time to 1m 30s
|
||||||
vm.recorder.goto("00:01:30")
|
vm.recorder.goto('00:01:30')
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Recorder.Mode
|
#### Recorder.Mode
|
||||||
@ -679,11 +678,11 @@ get() may return None if no value for requested key in midi cache
|
|||||||
```python
|
```python
|
||||||
vm.apply(
|
vm.apply(
|
||||||
{
|
{
|
||||||
"strip-2": {"A1": True, "B1": True, "gain": -6.0},
|
'strip-2': {'A1': True, 'B1': True, 'gain': -6.0},
|
||||||
"bus-2": {"mute": True, "eq": {"on": True}},
|
'bus-2': {'mute': True, 'eq': {'on': True}},
|
||||||
"button-0": {"state": True},
|
'button-0': {'state': True},
|
||||||
"vban-in-0": {"on": True},
|
'vban-in-0': {'on': True},
|
||||||
"vban-out-1": {"name": "streamname"},
|
'vban-out-1': {'name': 'streamname'},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
```
|
```
|
||||||
@ -691,8 +690,8 @@ vm.apply(
|
|||||||
Or for each class you may do:
|
Or for each class you may do:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
vm.strip[0].apply({"mute": True, "gain": 3.2, "A1": True})
|
vm.strip[0].apply({'mute': True, 'gain': 3.2, 'A1': True})
|
||||||
vm.vban.outstream[0].apply({"on": True, "name": "streamname", "bit": 24})
|
vm.vban.outstream[0].apply({'on': True, 'name': 'streamname', 'bit': 24})
|
||||||
```
|
```
|
||||||
|
|
||||||
## Config Files
|
## Config Files
|
||||||
@ -793,7 +792,7 @@ The following methods are available:
|
|||||||
example:
|
example:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
vm.event.remove(["pdirty", "mdirty", "midi"])
|
vm.event.remove(['pdirty', 'mdirty', 'midi'])
|
||||||
|
|
||||||
# get a list of currently subscribed
|
# get a list of currently subscribed
|
||||||
print(vm.event.get())
|
print(vm.event.get())
|
||||||
@ -863,8 +862,8 @@ import voicemeeterlib
|
|||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
|
||||||
with voicemeeterlib.api("banana") as vm:
|
with voicemeeterlib.api('banana') as vm:
|
||||||
...
|
...
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
24
__main__.py
24
__main__.py
@ -6,24 +6,24 @@ class ManyThings:
|
|||||||
self.vm = vm
|
self.vm = vm
|
||||||
|
|
||||||
def things(self):
|
def things(self):
|
||||||
self.vm.strip[0].label = "podmic"
|
self.vm.strip[0].label = 'podmic'
|
||||||
self.vm.strip[0].mute = True
|
self.vm.strip[0].mute = True
|
||||||
print(
|
print(
|
||||||
f"strip 0 ({self.vm.strip[0].label}) mute has been set to {self.vm.strip[0].mute}"
|
f'strip 0 ({self.vm.strip[0].label}) mute has been set to {self.vm.strip[0].mute}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def other_things(self):
|
def other_things(self):
|
||||||
self.vm.bus[3].gain = -6.3
|
self.vm.bus[3].gain = -6.3
|
||||||
self.vm.bus[4].eq.on = True
|
self.vm.bus[4].eq.on = True
|
||||||
info = (
|
info = (
|
||||||
f"bus 3 gain has been set to {self.vm.bus[3].gain}",
|
f'bus 3 gain has been set to {self.vm.bus[3].gain}',
|
||||||
f"bus 4 eq has been set to {self.vm.bus[4].eq.on}",
|
f'bus 4 eq has been set to {self.vm.bus[4].eq.on}',
|
||||||
)
|
)
|
||||||
print("\n".join(info))
|
print('\n'.join(info))
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
KIND_ID = "banana"
|
KIND_ID = 'banana'
|
||||||
|
|
||||||
with voicemeeterlib.api(KIND_ID) as vm:
|
with voicemeeterlib.api(KIND_ID) as vm:
|
||||||
do = ManyThings(vm)
|
do = ManyThings(vm)
|
||||||
@ -33,14 +33,14 @@ def main():
|
|||||||
# set many parameters at once
|
# set many parameters at once
|
||||||
vm.apply(
|
vm.apply(
|
||||||
{
|
{
|
||||||
"strip-2": {"A1": True, "B1": True, "gain": -6.0},
|
'strip-2': {'A1': True, 'B1': True, 'gain': -6.0},
|
||||||
"bus-2": {"mute": True, "eq": {"on": True}},
|
'bus-2': {'mute': True, 'eq': {'on': True}},
|
||||||
"button-0": {"state": True},
|
'button-0': {'state': True},
|
||||||
"vban-in-0": {"on": True},
|
'vban-in-0': {'on': True},
|
||||||
"vban-out-1": {"name": "streamname"},
|
'vban-out-1': {'name': 'streamname'},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -21,14 +21,14 @@ logging.basicConfig(level=logging.DEBUG)
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
argparser = argparse.ArgumentParser(description="creates a basic dsl")
|
argparser = argparse.ArgumentParser(description='creates a basic dsl')
|
||||||
argparser.add_argument("-i", action="store_true")
|
argparser.add_argument('-i', action='store_true')
|
||||||
args = argparser.parse_args()
|
args = argparser.parse_args()
|
||||||
|
|
||||||
|
|
||||||
ParamKinds = IntEnum(
|
ParamKinds = IntEnum(
|
||||||
"ParamKinds",
|
'ParamKinds',
|
||||||
"bool float string",
|
'bool float string',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -51,12 +51,12 @@ class BoolStrategy(Strategy):
|
|||||||
"""Convert a string representation of truth to it's numeric form."""
|
"""Convert a string representation of truth to it's numeric form."""
|
||||||
|
|
||||||
val = val.lower()
|
val = val.lower()
|
||||||
if val in ("y", "yes", "t", "true", "on", "1"):
|
if val in ('y', 'yes', 't', 'true', 'on', '1'):
|
||||||
return 1
|
return 1
|
||||||
elif val in ("n", "no", "f", "false", "off", "0"):
|
elif val in ('n', 'no', 'f', 'false', 'off', '0'):
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
raise ValueError("invalid truth value %r" % (val,))
|
raise ValueError('invalid truth value %r' % (val,))
|
||||||
|
|
||||||
|
|
||||||
class FloatStrategy(Strategy):
|
class FloatStrategy(Strategy):
|
||||||
@ -66,7 +66,7 @@ class FloatStrategy(Strategy):
|
|||||||
|
|
||||||
class StringStrategy(Strategy):
|
class StringStrategy(Strategy):
|
||||||
def run(self):
|
def run(self):
|
||||||
setattr(self.target, self.param, " ".join(self.val))
|
setattr(self.target, self.param, ' '.join(self.val))
|
||||||
|
|
||||||
|
|
||||||
class Context:
|
class Context:
|
||||||
@ -86,16 +86,16 @@ class Context:
|
|||||||
|
|
||||||
|
|
||||||
class Parser:
|
class Parser:
|
||||||
IS_STRING = ("label",)
|
IS_STRING = ('label',)
|
||||||
|
|
||||||
def __init__(self, vm):
|
def __init__(self, vm):
|
||||||
self.logger = logger.getChild(self.__class__.__name__)
|
self.logger = logger.getChild(self.__class__.__name__)
|
||||||
self.vm = vm
|
self.vm = vm
|
||||||
self.kls = Group(OneOrMore(Word(alphanums)))
|
self.kls = Group(OneOrMore(Word(alphanums)))
|
||||||
self.token = Suppress("->")
|
self.token = Suppress('->')
|
||||||
self.param = Group(OneOrMore(Word(alphanums)))
|
self.param = Group(OneOrMore(Word(alphanums)))
|
||||||
self.value = Combine(
|
self.value = Combine(
|
||||||
Optional("-") + Word(nums) + Optional(".") + Optional(Word(nums))
|
Optional('-') + Word(nums) + Optional('.') + Optional(Word(nums))
|
||||||
) | Group(OneOrMore(Word(alphanums)))
|
) | Group(OneOrMore(Word(alphanums)))
|
||||||
self.event = (
|
self.event = (
|
||||||
self.kls
|
self.kls
|
||||||
@ -110,7 +110,7 @@ class Parser:
|
|||||||
|
|
||||||
res = list()
|
res = list()
|
||||||
for cmd in cmds:
|
for cmd in cmds:
|
||||||
self.logger.debug(f"running command: {cmd}")
|
self.logger.debug(f'running command: {cmd}')
|
||||||
match cmd_parsed := self.event.parseString(cmd):
|
match cmd_parsed := self.event.parseString(cmd):
|
||||||
case [[kls, index], [param]]:
|
case [[kls, index], [param]]:
|
||||||
target = getattr(self.vm, kls)[int(index)]
|
target = getattr(self.vm, kls)[int(index)]
|
||||||
@ -125,7 +125,7 @@ class Parser:
|
|||||||
context = self._get_context(ParamKinds.bool, target, param, val)
|
context = self._get_context(ParamKinds.bool, target, param, val)
|
||||||
context.run()
|
context.run()
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.logger.error(f"{e}... switching to float strategy")
|
self.logger.error(f'{e}... switching to float strategy')
|
||||||
context.strategy = FloatStrategy(target, param, val)
|
context.strategy = FloatStrategy(target, param, val)
|
||||||
context.run()
|
context.run()
|
||||||
case [
|
case [
|
||||||
@ -140,12 +140,12 @@ class Parser:
|
|||||||
context = self._get_context(ParamKinds.bool, target, param, val)
|
context = self._get_context(ParamKinds.bool, target, param, val)
|
||||||
context.run()
|
context.run()
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
self.logger.error(f"{e}... switching to float strategy")
|
self.logger.error(f'{e}... switching to float strategy')
|
||||||
context.strategy = FloatStrategy(target, param, val)
|
context.strategy = FloatStrategy(target, param, val)
|
||||||
context.run()
|
context.run()
|
||||||
case _:
|
case _:
|
||||||
self.logger.error(
|
self.logger.error(
|
||||||
f"unable to determine the kind of parameter from {cmd_parsed}"
|
f'unable to determine the kind of parameter from {cmd_parsed}'
|
||||||
)
|
)
|
||||||
time.sleep(0.05)
|
time.sleep(0.05)
|
||||||
return res
|
return res
|
||||||
@ -166,7 +166,7 @@ class Parser:
|
|||||||
|
|
||||||
|
|
||||||
def interactive_mode(parser):
|
def interactive_mode(parser):
|
||||||
while cmd := input("Please enter command (Press <Enter> to exit)\n"):
|
while cmd := input('Please enter command (Press <Enter> to exit)\n'):
|
||||||
if res := parser.parse((cmd,)):
|
if res := parser.parse((cmd,)):
|
||||||
print(res)
|
print(res)
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ def main():
|
|||||||
)
|
)
|
||||||
# fmt: on
|
# fmt: on
|
||||||
|
|
||||||
with voicemeeterlib.api("potato") as vm:
|
with voicemeeterlib.api('potato') as vm:
|
||||||
parser = Parser(vm)
|
parser = Parser(vm)
|
||||||
if args.i:
|
if args.i:
|
||||||
interactive_mode(parser)
|
interactive_mode(parser)
|
||||||
@ -194,5 +194,5 @@ def main():
|
|||||||
print(res)
|
print(res)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -22,10 +22,10 @@ class App:
|
|||||||
self.vm.end_thread()
|
self.vm.end_thread()
|
||||||
|
|
||||||
def on_pdirty(self):
|
def on_pdirty(self):
|
||||||
print("pdirty!")
|
print('pdirty!')
|
||||||
|
|
||||||
def on_mdirty(self):
|
def on_mdirty(self):
|
||||||
print("mdirty!")
|
print('mdirty!')
|
||||||
|
|
||||||
def on_ldirty(self):
|
def on_ldirty(self):
|
||||||
for bus in self.vm.bus:
|
for bus in self.vm.bus:
|
||||||
@ -34,20 +34,20 @@ class App:
|
|||||||
|
|
||||||
def on_midi(self):
|
def on_midi(self):
|
||||||
current = self.vm.midi.current
|
current = self.vm.midi.current
|
||||||
print(f"Value of midi button {current} is {self.vm.midi.get(current)}")
|
print(f'Value of midi button {current} is {self.vm.midi.get(current)}')
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
KIND_ID = "banana"
|
KIND_ID = 'banana'
|
||||||
|
|
||||||
with voicemeeterlib.api(KIND_ID) as vm:
|
with voicemeeterlib.api(KIND_ID) as vm:
|
||||||
with App(vm):
|
with App(vm):
|
||||||
for i in range(5, 0, -1):
|
for i in range(5, 0, -1):
|
||||||
print(f"events start in {i} seconds")
|
print(f'events start in {i} seconds')
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
vm.event.add(["pdirty", "ldirty", "midi", "mdirty"])
|
vm.event.add(['pdirty', 'ldirty', 'midi', 'mdirty'])
|
||||||
time.sleep(30)
|
time.sleep(30)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -13,7 +13,7 @@ class App(tk.Tk):
|
|||||||
def __init__(self, vm):
|
def __init__(self, vm):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.vm = vm
|
self.vm = vm
|
||||||
self.title(f"{vm} - version {vm.version}")
|
self.title(f'{vm} - version {vm.version}')
|
||||||
self.vm.observer.add(self.on_ldirty)
|
self.vm.observer.add(self.on_ldirty)
|
||||||
|
|
||||||
# create widget variables
|
# create widget variables
|
||||||
@ -24,10 +24,10 @@ class App(tk.Tk):
|
|||||||
|
|
||||||
# initialize style table
|
# initialize style table
|
||||||
self.style = ttk.Style()
|
self.style = ttk.Style()
|
||||||
self.style.theme_use("clam")
|
self.style.theme_use('clam')
|
||||||
self.style.configure(
|
self.style.configure(
|
||||||
"Mute.TButton",
|
'Mute.TButton',
|
||||||
foreground="#cd5c5c" if vm.strip[self.INDEX].mute else "#5a5a5a",
|
foreground='#cd5c5c' if vm.strip[self.INDEX].mute else '#5a5a5a',
|
||||||
)
|
)
|
||||||
|
|
||||||
# create labelframe and grid it onto the mainframe
|
# create labelframe and grid it onto the mainframe
|
||||||
@ -39,7 +39,7 @@ class App(tk.Tk):
|
|||||||
self.labelframe,
|
self.labelframe,
|
||||||
from_=12,
|
from_=12,
|
||||||
to_=-60,
|
to_=-60,
|
||||||
orient="vertical",
|
orient='vertical',
|
||||||
variable=self.slider_var,
|
variable=self.slider_var,
|
||||||
command=lambda arg: self.on_slider_move(arg),
|
command=lambda arg: self.on_slider_move(arg),
|
||||||
)
|
)
|
||||||
@ -47,15 +47,15 @@ class App(tk.Tk):
|
|||||||
column=0,
|
column=0,
|
||||||
row=0,
|
row=0,
|
||||||
)
|
)
|
||||||
slider.bind("<Double-Button-1>", self.on_button_double_click)
|
slider.bind('<Double-Button-1>', self.on_button_double_click)
|
||||||
|
|
||||||
# create level meter and grid it onto the labelframe
|
# create level meter and grid it onto the labelframe
|
||||||
level_meter = ttk.Progressbar(
|
level_meter = ttk.Progressbar(
|
||||||
self.labelframe,
|
self.labelframe,
|
||||||
orient="vertical",
|
orient='vertical',
|
||||||
variable=self.meter_var,
|
variable=self.meter_var,
|
||||||
maximum=72,
|
maximum=72,
|
||||||
mode="determinate",
|
mode='determinate',
|
||||||
)
|
)
|
||||||
level_meter.grid(column=1, row=0)
|
level_meter.grid(column=1, row=0)
|
||||||
|
|
||||||
@ -66,8 +66,8 @@ class App(tk.Tk):
|
|||||||
# create button and grid it onto the labelframe
|
# create button and grid it onto the labelframe
|
||||||
button = ttk.Button(
|
button = ttk.Button(
|
||||||
self.labelframe,
|
self.labelframe,
|
||||||
text="Mute",
|
text='Mute',
|
||||||
style="Mute.TButton",
|
style='Mute.TButton',
|
||||||
command=lambda: self.on_button_press(),
|
command=lambda: self.on_button_press(),
|
||||||
)
|
)
|
||||||
button.grid(column=0, row=2, columnspan=2, padx=1, pady=2)
|
button.grid(column=0, row=2, columnspan=2, padx=1, pady=2)
|
||||||
@ -83,7 +83,7 @@ class App(tk.Tk):
|
|||||||
self.button_var.set(not self.button_var.get())
|
self.button_var.set(not self.button_var.get())
|
||||||
self.vm.strip[self.INDEX].mute = self.button_var.get()
|
self.vm.strip[self.INDEX].mute = self.button_var.get()
|
||||||
self.style.configure(
|
self.style.configure(
|
||||||
"Mute.TButton", foreground="#cd5c5c" if self.button_var.get() else "#5a5a5a"
|
'Mute.TButton', foreground='#cd5c5c' if self.button_var.get() else '#5a5a5a'
|
||||||
)
|
)
|
||||||
|
|
||||||
def on_button_double_click(self, e):
|
def on_button_double_click(self, e):
|
||||||
@ -100,10 +100,10 @@ class App(tk.Tk):
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with voicemeeterlib.api("banana", ldirty=True) as vm:
|
with voicemeeterlib.api('banana', ldirty=True) as vm:
|
||||||
app = App(vm)
|
app = App(vm)
|
||||||
app.mainloop()
|
app.mainloop()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -7,16 +7,16 @@ logging.basicConfig(level=logging.INFO)
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
KIND_ID = "potato"
|
KIND_ID = 'potato'
|
||||||
|
|
||||||
vm = voicemeeterlib.api(KIND_ID)
|
vm = voicemeeterlib.api(KIND_ID)
|
||||||
vm.login()
|
vm.login()
|
||||||
for _ in range(500):
|
for _ in range(500):
|
||||||
print(
|
print(
|
||||||
"\n".join(
|
'\n'.join(
|
||||||
[
|
[
|
||||||
f"{vm.strip[5]}: {vm.strip[5].levels.postmute}",
|
f'{vm.strip[5]}: {vm.strip[5].levels.postmute}',
|
||||||
f"{vm.bus[0]}: {vm.bus[0].levels.all}",
|
f'{vm.bus[0]}: {vm.bus[0].levels.all}',
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -24,5 +24,5 @@ def main():
|
|||||||
vm.logout()
|
vm.logout()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -19,7 +19,7 @@ class App:
|
|||||||
|
|
||||||
def get_info(self):
|
def get_info(self):
|
||||||
current = self.vm.midi.current
|
current = self.vm.midi.current
|
||||||
print(f"Value of midi button {current} is {self.vm.midi.get(current)}")
|
print(f'Value of midi button {current} is {self.vm.midi.get(current)}')
|
||||||
return current
|
return current
|
||||||
|
|
||||||
def on_midi_press(self):
|
def on_midi_press(self):
|
||||||
@ -30,7 +30,7 @@ class App:
|
|||||||
and max(self.vm.strip[3].levels.postfader) > -40
|
and max(self.vm.strip[3].levels.postfader) > -40
|
||||||
):
|
):
|
||||||
print(
|
print(
|
||||||
f"Strip 3 level max is greater than -40 and midi button {self.MIDI_BUTTON} is pressed"
|
f'Strip 3 level max is greater than -40 and midi button {self.MIDI_BUTTON} is pressed'
|
||||||
)
|
)
|
||||||
self.vm.button[self.MACROBUTTON].trigger = True
|
self.vm.button[self.MACROBUTTON].trigger = True
|
||||||
else:
|
else:
|
||||||
@ -38,14 +38,14 @@ class App:
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
KIND_ID = "banana"
|
KIND_ID = 'banana'
|
||||||
|
|
||||||
with voicemeeterlib.api(KIND_ID, midi=True) as vm:
|
with voicemeeterlib.api(KIND_ID, midi=True) as vm:
|
||||||
App(vm)
|
App(vm)
|
||||||
|
|
||||||
while _ := input("Press <Enter> to exit\n"):
|
while _ := input('Press <Enter> to exit\n'):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
from .factory import request_remote_obj as api
|
from .factory import request_remote_obj as api
|
||||||
|
|
||||||
__ALL__ = ["api"]
|
__ALL__ = ['api']
|
||||||
|
@ -9,8 +9,8 @@ from .iremote import IRemote
|
|||||||
from .meta import bus_mode_prop, device_prop, float_prop
|
from .meta import bus_mode_prop, device_prop, float_prop
|
||||||
|
|
||||||
BusModes = IntEnum(
|
BusModes = IntEnum(
|
||||||
"BusModes",
|
'BusModes',
|
||||||
"normal amix bmix repeat composite tvmix upmix21 upmix41 upmix61 centeronly lfeonly rearonly",
|
'normal amix bmix repeat composite tvmix upmix21 upmix41 upmix61 centeronly lfeonly rearonly',
|
||||||
start=0,
|
start=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -28,85 +28,85 @@ class Bus(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"bus[{self.index}]"
|
return f'bus[{self.index}]'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mute(self) -> bool:
|
def mute(self) -> bool:
|
||||||
return self.getter("mute") == 1
|
return self.getter('mute') == 1
|
||||||
|
|
||||||
@mute.setter
|
@mute.setter
|
||||||
def mute(self, val: bool):
|
def mute(self, val: bool):
|
||||||
self.setter("mute", 1 if val else 0)
|
self.setter('mute', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mono(self) -> bool:
|
def mono(self) -> bool:
|
||||||
return self.getter("mono") == 1
|
return self.getter('mono') == 1
|
||||||
|
|
||||||
@mono.setter
|
@mono.setter
|
||||||
def mono(self, val: bool):
|
def mono(self, val: bool):
|
||||||
self.setter("mono", 1 if val else 0)
|
self.setter('mono', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sel(self) -> bool:
|
def sel(self) -> bool:
|
||||||
return self.getter("sel") == 1
|
return self.getter('sel') == 1
|
||||||
|
|
||||||
@sel.setter
|
@sel.setter
|
||||||
def sel(self, val: bool):
|
def sel(self, val: bool):
|
||||||
self.setter("sel", 1 if val else 0)
|
self.setter('sel', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self) -> str:
|
def label(self) -> str:
|
||||||
return self.getter("Label", is_string=True)
|
return self.getter('Label', is_string=True)
|
||||||
|
|
||||||
@label.setter
|
@label.setter
|
||||||
def label(self, val: str):
|
def label(self, val: str):
|
||||||
self.setter("Label", str(val))
|
self.setter('Label', str(val))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gain(self) -> float:
|
def gain(self) -> float:
|
||||||
return round(self.getter("gain"), 1)
|
return round(self.getter('gain'), 1)
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val: float):
|
def gain(self, val: float):
|
||||||
self.setter("gain", val)
|
self.setter('gain', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def monitor(self) -> bool:
|
def monitor(self) -> bool:
|
||||||
return self.getter("monitor") == 1
|
return self.getter('monitor') == 1
|
||||||
|
|
||||||
@monitor.setter
|
@monitor.setter
|
||||||
def monitor(self, val: bool):
|
def monitor(self, val: bool):
|
||||||
self.setter("monitor", 1 if val else 0)
|
self.setter('monitor', 1 if val else 0)
|
||||||
|
|
||||||
def fadeto(self, target: float, time_: int):
|
def fadeto(self, target: float, time_: int):
|
||||||
self.setter("FadeTo", f"({target}, {time_})")
|
self.setter('FadeTo', f'({target}, {time_})')
|
||||||
time.sleep(self._remote.DELAY)
|
time.sleep(self._remote.DELAY)
|
||||||
|
|
||||||
def fadeby(self, change: float, time_: int):
|
def fadeby(self, change: float, time_: int):
|
||||||
self.setter("FadeBy", f"({change}, {time_})")
|
self.setter('FadeBy', f'({change}, {time_})')
|
||||||
time.sleep(self._remote.DELAY)
|
time.sleep(self._remote.DELAY)
|
||||||
|
|
||||||
|
|
||||||
class BusEQ(IRemote):
|
class BusEQ(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Bus[{self.index}].eq"
|
return f'Bus[{self.index}].eq'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def on(self) -> bool:
|
def on(self) -> bool:
|
||||||
return self.getter("on") == 1
|
return self.getter('on') == 1
|
||||||
|
|
||||||
@on.setter
|
@on.setter
|
||||||
def on(self, val: bool):
|
def on(self, val: bool):
|
||||||
self.setter("on", 1 if val else 0)
|
self.setter('on', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ab(self) -> bool:
|
def ab(self) -> bool:
|
||||||
return self.getter("ab") == 1
|
return self.getter('ab') == 1
|
||||||
|
|
||||||
@ab.setter
|
@ab.setter
|
||||||
def ab(self, val: bool):
|
def ab(self, val: bool):
|
||||||
self.setter("ab", 1 if val else 0)
|
self.setter('ab', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class PhysicalBus(Bus):
|
class PhysicalBus(Bus):
|
||||||
@ -118,19 +118,19 @@ class PhysicalBus(Bus):
|
|||||||
Returns a PhysicalBus class.
|
Returns a PhysicalBus class.
|
||||||
"""
|
"""
|
||||||
kls = (cls,)
|
kls = (cls,)
|
||||||
if kind.name == "potato":
|
if kind.name == 'potato':
|
||||||
EFFECTS_cls = _make_effects_mixin()
|
EFFECTS_cls = _make_effects_mixin()
|
||||||
kls += (EFFECTS_cls,)
|
kls += (EFFECTS_cls,)
|
||||||
return type(
|
return type(
|
||||||
"PhysicalBus",
|
'PhysicalBus',
|
||||||
kls,
|
kls,
|
||||||
{
|
{
|
||||||
"device": BusDevice.make(remote, i),
|
'device': BusDevice.make(remote, i),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self.index}"
|
return f'{type(self).__name__}{self.index}'
|
||||||
|
|
||||||
|
|
||||||
class BusDevice(IRemote):
|
class BusDevice(IRemote):
|
||||||
@ -142,16 +142,16 @@ class BusDevice(IRemote):
|
|||||||
Returns a BusDevice class of a kind.
|
Returns a BusDevice class of a kind.
|
||||||
"""
|
"""
|
||||||
DEVICE_cls = type(
|
DEVICE_cls = type(
|
||||||
f"BusDevice{remote.kind}",
|
f'BusDevice{remote.kind}',
|
||||||
(cls,),
|
(cls,),
|
||||||
{
|
{
|
||||||
**{
|
**{
|
||||||
param: device_prop(param)
|
param: device_prop(param)
|
||||||
for param in [
|
for param in [
|
||||||
"wdm",
|
'wdm',
|
||||||
"ks",
|
'ks',
|
||||||
"mme",
|
'mme',
|
||||||
"asio",
|
'asio',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -160,15 +160,15 @@ class BusDevice(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Bus[{self.index}].device"
|
return f'Bus[{self.index}].device'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return self.getter("name", is_string=True)
|
return self.getter('name', is_string=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sr(self) -> int:
|
def sr(self) -> int:
|
||||||
return int(self.getter("sr"))
|
return int(self.getter('sr'))
|
||||||
|
|
||||||
|
|
||||||
class VirtualBus(Bus):
|
class VirtualBus(Bus):
|
||||||
@ -182,21 +182,21 @@ class VirtualBus(Bus):
|
|||||||
Returns a VirtualBus class.
|
Returns a VirtualBus class.
|
||||||
"""
|
"""
|
||||||
kls = (cls,)
|
kls = (cls,)
|
||||||
if kind.name == "basic":
|
if kind.name == 'basic':
|
||||||
return type(
|
return type(
|
||||||
"VirtualBus",
|
'VirtualBus',
|
||||||
kls,
|
kls,
|
||||||
{
|
{
|
||||||
"device": BusDevice.make(remote, i),
|
'device': BusDevice.make(remote, i),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
elif kind.name == "potato":
|
elif kind.name == 'potato':
|
||||||
EFFECTS_cls = _make_effects_mixin()
|
EFFECTS_cls = _make_effects_mixin()
|
||||||
kls += (EFFECTS_cls,)
|
kls += (EFFECTS_cls,)
|
||||||
return type("VirtualBus", kls, {})
|
return type('VirtualBus', kls, {})
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self.index}"
|
return f'{type(self).__name__}{self.index}'
|
||||||
|
|
||||||
|
|
||||||
class BusLevel(IRemote):
|
class BusLevel(IRemote):
|
||||||
@ -217,7 +217,7 @@ class BusLevel(IRemote):
|
|||||||
return round(20 * log(x, 10), 1) if x > 0 else -200.0
|
return round(20 * log(x, 10), 1) if x > 0 else -200.0
|
||||||
|
|
||||||
if not self._remote.stopped() and self._remote.event.ldirty:
|
if not self._remote.stopped() and self._remote.event.ldirty:
|
||||||
vals = self._remote.cache["bus_level"][self.range[0] : self.range[-1]]
|
vals = self._remote.cache['bus_level'][self.range[0] : self.range[-1]]
|
||||||
else:
|
else:
|
||||||
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
|
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
|
||||||
|
|
||||||
@ -225,7 +225,7 @@ class BusLevel(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Bus[{self.index}]"
|
return f'Bus[{self.index}]'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def all(self) -> tuple:
|
def all(self) -> tuple:
|
||||||
@ -255,7 +255,7 @@ def _make_bus_mode_mixin():
|
|||||||
"""Creates a mixin of Bus Modes."""
|
"""Creates a mixin of Bus Modes."""
|
||||||
|
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Bus[{self.index}].mode"
|
return f'Bus[{self.index}].mode'
|
||||||
|
|
||||||
def get(self) -> str:
|
def get(self) -> str:
|
||||||
time.sleep(0.01)
|
time.sleep(0.01)
|
||||||
@ -276,15 +276,15 @@ def _make_bus_mode_mixin():
|
|||||||
):
|
):
|
||||||
if val:
|
if val:
|
||||||
return BusModes(i + 1).name
|
return BusModes(i + 1).name
|
||||||
return "normal"
|
return 'normal'
|
||||||
|
|
||||||
return type(
|
return type(
|
||||||
"BusModeMixin",
|
'BusModeMixin',
|
||||||
(IRemote,),
|
(IRemote,),
|
||||||
{
|
{
|
||||||
"identifier": property(identifier),
|
'identifier': property(identifier),
|
||||||
**{mode.name: bus_mode_prop(mode.name) for mode in BusModes},
|
**{mode.name: bus_mode_prop(mode.name) for mode in BusModes},
|
||||||
"get": get,
|
'get': get,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -292,12 +292,12 @@ def _make_bus_mode_mixin():
|
|||||||
def _make_effects_mixin():
|
def _make_effects_mixin():
|
||||||
"""creates an fx mixin"""
|
"""creates an fx mixin"""
|
||||||
return type(
|
return type(
|
||||||
"FX",
|
'FX',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
**{
|
**{
|
||||||
f"return{param}": float_prop(f"return{param}")
|
f'return{param}': float_prop(f'return{param}')
|
||||||
for param in ["reverb", "delay", "fx1", "fx2"]
|
for param in ['reverb', 'delay', 'fx1', 'fx2']
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -316,12 +316,12 @@ def bus_factory(is_phys_bus, remote, i) -> Union[PhysicalBus, VirtualBus]:
|
|||||||
)
|
)
|
||||||
BUSMODEMIXIN_cls = _make_bus_mode_mixin()
|
BUSMODEMIXIN_cls = _make_bus_mode_mixin()
|
||||||
return type(
|
return type(
|
||||||
f"{BUS_cls.__name__}{remote.kind}",
|
f'{BUS_cls.__name__}{remote.kind}',
|
||||||
(BUS_cls,),
|
(BUS_cls,),
|
||||||
{
|
{
|
||||||
"levels": BusLevel(remote, i),
|
'levels': BusLevel(remote, i),
|
||||||
"mode": BUSMODEMIXIN_cls(remote, i),
|
'mode': BUSMODEMIXIN_cls(remote, i),
|
||||||
"eq": BusEQ(remote, i),
|
'eq': BusEQ(remote, i),
|
||||||
},
|
},
|
||||||
)(remote, i)
|
)(remote, i)
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ class CBindings(metaclass=ABCMeta):
|
|||||||
Maps expected ctype argument and res types for each binding.
|
Maps expected ctype argument and res types for each binding.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger_cbindings = logger.getChild("CBindings")
|
logger_cbindings = logger.getChild('CBindings')
|
||||||
|
|
||||||
bind_login = libc.VBVMR_Login
|
bind_login = libc.VBVMR_Login
|
||||||
bind_login.restype = LONG
|
bind_login.restype = LONG
|
||||||
@ -38,17 +38,17 @@ class CBindings(metaclass=ABCMeta):
|
|||||||
bind_get_voicemeeter_version.restype = LONG
|
bind_get_voicemeeter_version.restype = LONG
|
||||||
bind_get_voicemeeter_version.argtypes = [ct.POINTER(LONG)]
|
bind_get_voicemeeter_version.argtypes = [ct.POINTER(LONG)]
|
||||||
|
|
||||||
if hasattr(libc, "VBVMR_MacroButton_IsDirty"):
|
if hasattr(libc, 'VBVMR_MacroButton_IsDirty'):
|
||||||
bind_macro_button_is_dirty = libc.VBVMR_MacroButton_IsDirty
|
bind_macro_button_is_dirty = libc.VBVMR_MacroButton_IsDirty
|
||||||
bind_macro_button_is_dirty.restype = LONG
|
bind_macro_button_is_dirty.restype = LONG
|
||||||
bind_macro_button_is_dirty.argtypes = None
|
bind_macro_button_is_dirty.argtypes = None
|
||||||
|
|
||||||
if hasattr(libc, "VBVMR_MacroButton_GetStatus"):
|
if hasattr(libc, 'VBVMR_MacroButton_GetStatus'):
|
||||||
bind_macro_button_get_status = libc.VBVMR_MacroButton_GetStatus
|
bind_macro_button_get_status = libc.VBVMR_MacroButton_GetStatus
|
||||||
bind_macro_button_get_status.restype = LONG
|
bind_macro_button_get_status.restype = LONG
|
||||||
bind_macro_button_get_status.argtypes = [LONG, ct.POINTER(FLOAT), LONG]
|
bind_macro_button_get_status.argtypes = [LONG, ct.POINTER(FLOAT), LONG]
|
||||||
|
|
||||||
if hasattr(libc, "VBVMR_MacroButton_SetStatus"):
|
if hasattr(libc, 'VBVMR_MacroButton_SetStatus'):
|
||||||
bind_macro_button_set_status = libc.VBVMR_MacroButton_SetStatus
|
bind_macro_button_set_status = libc.VBVMR_MacroButton_SetStatus
|
||||||
bind_macro_button_set_status.restype = LONG
|
bind_macro_button_set_status.restype = LONG
|
||||||
bind_macro_button_set_status.argtypes = [LONG, FLOAT, LONG]
|
bind_macro_button_set_status.argtypes = [LONG, FLOAT, LONG]
|
||||||
@ -121,5 +121,5 @@ class CBindings(metaclass=ABCMeta):
|
|||||||
raise CAPIError(func.__name__, res)
|
raise CAPIError(func.__name__, res)
|
||||||
return res
|
return res
|
||||||
except CAPIError as e:
|
except CAPIError as e:
|
||||||
self.logger_cbindings.exception(f"{type(e).__name__}: {e}")
|
self.logger_cbindings.exception(f'{type(e).__name__}: {e}')
|
||||||
raise
|
raise
|
||||||
|
@ -17,33 +17,33 @@ class Command(IRemote):
|
|||||||
Returns a Command class of a kind.
|
Returns a Command class of a kind.
|
||||||
"""
|
"""
|
||||||
CMD_cls = type(
|
CMD_cls = type(
|
||||||
f"Command{remote.kind}",
|
f'Command{remote.kind}',
|
||||||
(cls,),
|
(cls,),
|
||||||
{
|
{
|
||||||
**{
|
**{
|
||||||
param: action_fn(param) for param in ["show", "shutdown", "restart"]
|
param: action_fn(param) for param in ['show', 'shutdown', 'restart']
|
||||||
},
|
},
|
||||||
"hide": action_fn("show", val=0),
|
'hide': action_fn('show', val=0),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return CMD_cls(remote)
|
return CMD_cls(remote)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}"
|
return f'{type(self).__name__}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "Command"
|
return 'Command'
|
||||||
|
|
||||||
def set_showvbanchat(self, val: bool):
|
def set_showvbanchat(self, val: bool):
|
||||||
self.setter("DialogShow.VBANCHAT", 1 if val else 0)
|
self.setter('DialogShow.VBANCHAT', 1 if val else 0)
|
||||||
|
|
||||||
showvbanchat = property(fset=set_showvbanchat)
|
showvbanchat = property(fset=set_showvbanchat)
|
||||||
|
|
||||||
def set_lock(self, val: bool):
|
def set_lock(self, val: bool):
|
||||||
self.setter("lock", 1 if val else 0)
|
self.setter('lock', 1 if val else 0)
|
||||||
|
|
||||||
lock = property(fset=set_lock)
|
lock = property(fset=set_lock)
|
||||||
|
|
||||||
def reset(self):
|
def reset(self):
|
||||||
self._remote.apply_config("reset")
|
self._remote.apply_config('reset')
|
||||||
|
@ -20,72 +20,72 @@ class TOMLStrBuilder:
|
|||||||
def __init__(self, kind):
|
def __init__(self, kind):
|
||||||
self.kind = kind
|
self.kind = kind
|
||||||
self.higher = itertools.chain(
|
self.higher = itertools.chain(
|
||||||
[f"strip-{i}" for i in range(kind.num_strip)],
|
[f'strip-{i}' for i in range(kind.num_strip)],
|
||||||
[f"bus-{i}" for i in range(kind.num_bus)],
|
[f'bus-{i}' for i in range(kind.num_bus)],
|
||||||
)
|
)
|
||||||
|
|
||||||
def init_config(self, profile=None):
|
def init_config(self, profile=None):
|
||||||
self.virt_strip_params = (
|
self.virt_strip_params = (
|
||||||
[
|
[
|
||||||
"mute = false",
|
'mute = false',
|
||||||
"mono = false",
|
'mono = false',
|
||||||
"solo = false",
|
'solo = false',
|
||||||
"gain = 0.0",
|
'gain = 0.0',
|
||||||
]
|
]
|
||||||
+ [f"A{i} = false" for i in range(1, self.kind.phys_out + 1)]
|
+ [f'A{i} = false' for i in range(1, self.kind.phys_out + 1)]
|
||||||
+ [f"B{i} = false" for i in range(1, self.kind.virt_out + 1)]
|
+ [f'B{i} = false' for i in range(1, self.kind.virt_out + 1)]
|
||||||
)
|
)
|
||||||
self.phys_strip_params = self.virt_strip_params + [
|
self.phys_strip_params = self.virt_strip_params + [
|
||||||
"comp.knob = 0.0",
|
'comp.knob = 0.0',
|
||||||
"gate.knob = 0.0",
|
'gate.knob = 0.0',
|
||||||
"denoiser.knob = 0.0",
|
'denoiser.knob = 0.0',
|
||||||
"eq.on = false",
|
'eq.on = false',
|
||||||
]
|
]
|
||||||
self.bus_params = [
|
self.bus_params = [
|
||||||
"mono = false",
|
'mono = false',
|
||||||
"eq.on = false",
|
'eq.on = false',
|
||||||
"mute = false",
|
'mute = false',
|
||||||
"gain = 0.0",
|
'gain = 0.0',
|
||||||
]
|
]
|
||||||
|
|
||||||
if profile == "reset":
|
if profile == 'reset':
|
||||||
self.reset_config()
|
self.reset_config()
|
||||||
|
|
||||||
def reset_config(self):
|
def reset_config(self):
|
||||||
self.phys_strip_params = list(
|
self.phys_strip_params = list(
|
||||||
map(lambda x: x.replace("B1 = false", "B1 = true"), self.phys_strip_params)
|
map(lambda x: x.replace('B1 = false', 'B1 = true'), self.phys_strip_params)
|
||||||
)
|
)
|
||||||
self.virt_strip_params = list(
|
self.virt_strip_params = list(
|
||||||
map(lambda x: x.replace("A1 = false", "A1 = true"), self.virt_strip_params)
|
map(lambda x: x.replace('A1 = false', 'A1 = true'), self.virt_strip_params)
|
||||||
)
|
)
|
||||||
|
|
||||||
def build(self, profile="reset"):
|
def build(self, profile='reset'):
|
||||||
self.init_config(profile)
|
self.init_config(profile)
|
||||||
toml_str = str()
|
toml_str = str()
|
||||||
for eachclass in self.higher:
|
for eachclass in self.higher:
|
||||||
toml_str += f"[{eachclass}]\n"
|
toml_str += f'[{eachclass}]\n'
|
||||||
toml_str = self.join(eachclass, toml_str)
|
toml_str = self.join(eachclass, toml_str)
|
||||||
return toml_str
|
return toml_str
|
||||||
|
|
||||||
def join(self, eachclass, toml_str):
|
def join(self, eachclass, toml_str):
|
||||||
kls, index = eachclass.split("-")
|
kls, index = eachclass.split('-')
|
||||||
match kls:
|
match kls:
|
||||||
case "strip":
|
case 'strip':
|
||||||
toml_str += ("\n").join(
|
toml_str += ('\n').join(
|
||||||
self.phys_strip_params
|
self.phys_strip_params
|
||||||
if int(index) < self.kind.phys_in
|
if int(index) < self.kind.phys_in
|
||||||
else self.virt_strip_params
|
else self.virt_strip_params
|
||||||
)
|
)
|
||||||
case "bus":
|
case 'bus':
|
||||||
toml_str += ("\n").join(self.bus_params)
|
toml_str += ('\n').join(self.bus_params)
|
||||||
case _:
|
case _:
|
||||||
pass
|
pass
|
||||||
return toml_str + "\n"
|
return toml_str + '\n'
|
||||||
|
|
||||||
|
|
||||||
class TOMLDataExtractor:
|
class TOMLDataExtractor:
|
||||||
def __init__(self, file):
|
def __init__(self, file):
|
||||||
with open(file, "rb") as f:
|
with open(file, 'rb') as f:
|
||||||
self._data = tomllib.load(f)
|
self._data = tomllib.load(f)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@ -103,10 +103,10 @@ def dataextraction_factory(file):
|
|||||||
|
|
||||||
this opens the possibility for other parsers to be added
|
this opens the possibility for other parsers to be added
|
||||||
"""
|
"""
|
||||||
if file.suffix == ".toml":
|
if file.suffix == '.toml':
|
||||||
extractor = TOMLDataExtractor
|
extractor = TOMLDataExtractor
|
||||||
else:
|
else:
|
||||||
raise ValueError("Cannot extract data from {}".format(file))
|
raise ValueError('Cannot extract data from {}'.format(file))
|
||||||
return extractor(file)
|
return extractor(file)
|
||||||
|
|
||||||
|
|
||||||
@ -140,25 +140,25 @@ class Loader(metaclass=SingletonType):
|
|||||||
def defaults(self, kind):
|
def defaults(self, kind):
|
||||||
self.builder = TOMLStrBuilder(kind)
|
self.builder = TOMLStrBuilder(kind)
|
||||||
toml_str = self.builder.build()
|
toml_str = self.builder.build()
|
||||||
self.register("reset", tomllib.loads(toml_str))
|
self.register('reset', tomllib.loads(toml_str))
|
||||||
|
|
||||||
def parse(self, identifier, data):
|
def parse(self, identifier, data):
|
||||||
if identifier in self._configs:
|
if identifier in self._configs:
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
f"config file with name {identifier} already in memory, skipping.."
|
f'config file with name {identifier} already in memory, skipping..'
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.parser = dataextraction_factory(data)
|
self.parser = dataextraction_factory(data)
|
||||||
except tomllib.TOMLDecodeError as e:
|
except tomllib.TOMLDecodeError as e:
|
||||||
ERR_MSG = (str(e), f"When attempting to load {identifier}.toml")
|
ERR_MSG = (str(e), f'When attempting to load {identifier}.toml')
|
||||||
self.logger.error(f"{type(e).__name__}: {' '.join(ERR_MSG)}")
|
self.logger.error(f"{type(e).__name__}: {' '.join(ERR_MSG)}")
|
||||||
return
|
return
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def register(self, identifier, data=None):
|
def register(self, identifier, data=None):
|
||||||
self._configs[identifier] = data if data else self.parser.data
|
self._configs[identifier] = data if data else self.parser.data
|
||||||
self.logger.info(f"config {self.name}/{identifier} loaded into memory")
|
self.logger.info(f'config {self.name}/{identifier} loaded into memory')
|
||||||
|
|
||||||
def deregister(self):
|
def deregister(self):
|
||||||
self._configs.clear()
|
self._configs.clear()
|
||||||
@ -181,18 +181,18 @@ def loader(kind):
|
|||||||
|
|
||||||
returns configs loaded into memory
|
returns configs loaded into memory
|
||||||
"""
|
"""
|
||||||
logger_loader = logger.getChild("loader")
|
logger_loader = logger.getChild('loader')
|
||||||
loader = Loader(kind)
|
loader = Loader(kind)
|
||||||
|
|
||||||
for path in (
|
for path in (
|
||||||
Path.cwd() / "configs" / kind.name,
|
Path.cwd() / 'configs' / kind.name,
|
||||||
Path.home() / ".config" / "voicemeeter" / kind.name,
|
Path.home() / '.config' / 'voicemeeter' / kind.name,
|
||||||
Path.home() / "Documents" / "Voicemeeter" / "configs" / kind.name,
|
Path.home() / 'Documents' / 'Voicemeeter' / 'configs' / kind.name,
|
||||||
):
|
):
|
||||||
if path.is_dir():
|
if path.is_dir():
|
||||||
logger_loader.info(f"Checking [{path}] for TOML config files:")
|
logger_loader.info(f'Checking [{path}] for TOML config files:')
|
||||||
for file in path.glob("*.toml"):
|
for file in path.glob('*.toml'):
|
||||||
identifier = file.with_suffix("").stem
|
identifier = file.with_suffix('').stem
|
||||||
if loader.parse(identifier, file):
|
if loader.parse(identifier, file):
|
||||||
loader.register(identifier)
|
loader.register(identifier)
|
||||||
return loader.configs
|
return loader.configs
|
||||||
@ -207,5 +207,5 @@ def request_config(kind_id: str):
|
|||||||
try:
|
try:
|
||||||
configs = loader(kindmap(kind_id))
|
configs = loader(kindmap(kind_id))
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
raise VMError(f"Unknown Voicemeeter kind {kind_id}") from e
|
raise VMError(f'Unknown Voicemeeter kind {kind_id}') from e
|
||||||
return configs
|
return configs
|
||||||
|
@ -31,8 +31,8 @@ class Adapter(IRemote):
|
|||||||
return self._remote.get_num_devices(direction)
|
return self._remote.get_num_devices(direction)
|
||||||
|
|
||||||
vals = self._remote.get_device_description(index, direction)
|
vals = self._remote.get_device_description(index, direction)
|
||||||
types = {1: "mme", 3: "wdm", 4: "ks", 5: "asio"}
|
types = {1: 'mme', 3: 'wdm', 4: 'ks', 5: 'asio'}
|
||||||
return {"name": vals[0], "type": types[vals[1]], "id": vals[2]}
|
return {'name': vals[0], 'type': types[vals[1]], 'id': vals[2]}
|
||||||
|
|
||||||
|
|
||||||
class Device(Adapter):
|
class Device(Adapter):
|
||||||
@ -47,26 +47,26 @@ class Device(Adapter):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def num_ins(cls) -> int:
|
def num_ins(cls) -> int:
|
||||||
return cls.getter(direction="in")
|
return cls.getter(direction='in')
|
||||||
|
|
||||||
def num_outs(cls) -> int:
|
def num_outs(cls) -> int:
|
||||||
return cls.getter(direction="out")
|
return cls.getter(direction='out')
|
||||||
|
|
||||||
DEVICE_cls = type(
|
DEVICE_cls = type(
|
||||||
f"Device{remote.kind}",
|
f'Device{remote.kind}',
|
||||||
(cls,),
|
(cls,),
|
||||||
{
|
{
|
||||||
"ins": property(num_ins),
|
'ins': property(num_ins),
|
||||||
"outs": property(num_outs),
|
'outs': property(num_outs),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return DEVICE_cls(remote)
|
return DEVICE_cls(remote)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}"
|
return f'{type(self).__name__}'
|
||||||
|
|
||||||
def input(self, index: int) -> dict:
|
def input(self, index: int) -> dict:
|
||||||
return self.getter(index=index, direction="in")
|
return self.getter(index=index, direction='in')
|
||||||
|
|
||||||
def output(self, index: int) -> dict:
|
def output(self, index: int) -> dict:
|
||||||
return self.getter(index=index, direction="out")
|
return self.getter(index=index, direction='out')
|
||||||
|
@ -13,12 +13,12 @@ class CAPIError(VMError):
|
|||||||
self.fn_name = fn_name
|
self.fn_name = fn_name
|
||||||
self.code = code
|
self.code = code
|
||||||
if self.code == -9:
|
if self.code == -9:
|
||||||
message = " ".join(
|
message = ' '.join(
|
||||||
(
|
(
|
||||||
f"no bind for {self.fn_name}.",
|
f'no bind for {self.fn_name}.',
|
||||||
"are you using an old version of the API?",
|
'are you using an old version of the API?',
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
message = f"{self.fn_name} returned {self.code}"
|
message = f'{self.fn_name} returned {self.code}'
|
||||||
super().__init__(message)
|
super().__init__(message)
|
||||||
|
@ -12,47 +12,47 @@ class Event:
|
|||||||
self.logger = logger.getChild(self.__class__.__name__)
|
self.logger = logger.getChild(self.__class__.__name__)
|
||||||
|
|
||||||
def info(self, msg=None):
|
def info(self, msg=None):
|
||||||
info = (f"{msg} events",) if msg else ()
|
info = (f'{msg} events',) if msg else ()
|
||||||
if self.any():
|
if self.any():
|
||||||
info += (f"now listening for {', '.join(self.get())} events",)
|
info += (f"now listening for {', '.join(self.get())} events",)
|
||||||
else:
|
else:
|
||||||
info += ("not listening for any events",)
|
info += ('not listening for any events',)
|
||||||
self.logger.info(", ".join(info))
|
self.logger.info(', '.join(info))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pdirty(self) -> bool:
|
def pdirty(self) -> bool:
|
||||||
return self.subs["pdirty"]
|
return self.subs['pdirty']
|
||||||
|
|
||||||
@pdirty.setter
|
@pdirty.setter
|
||||||
def pdirty(self, val: bool):
|
def pdirty(self, val: bool):
|
||||||
self.subs["pdirty"] = val
|
self.subs['pdirty'] = val
|
||||||
self.info(f"pdirty {'added to' if val else 'removed from'}")
|
self.info(f"pdirty {'added to' if val else 'removed from'}")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mdirty(self) -> bool:
|
def mdirty(self) -> bool:
|
||||||
return self.subs["mdirty"]
|
return self.subs['mdirty']
|
||||||
|
|
||||||
@mdirty.setter
|
@mdirty.setter
|
||||||
def mdirty(self, val: bool):
|
def mdirty(self, val: bool):
|
||||||
self.subs["mdirty"] = val
|
self.subs['mdirty'] = val
|
||||||
self.info(f"mdirty {'added to' if val else 'removed from'}")
|
self.info(f"mdirty {'added to' if val else 'removed from'}")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def midi(self) -> bool:
|
def midi(self) -> bool:
|
||||||
return self.subs["midi"]
|
return self.subs['midi']
|
||||||
|
|
||||||
@midi.setter
|
@midi.setter
|
||||||
def midi(self, val: bool):
|
def midi(self, val: bool):
|
||||||
self.subs["midi"] = val
|
self.subs['midi'] = val
|
||||||
self.info(f"midi {'added to' if val else 'removed from'}")
|
self.info(f"midi {'added to' if val else 'removed from'}")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ldirty(self) -> bool:
|
def ldirty(self) -> bool:
|
||||||
return self.subs["ldirty"]
|
return self.subs['ldirty']
|
||||||
|
|
||||||
@ldirty.setter
|
@ldirty.setter
|
||||||
def ldirty(self, val: bool):
|
def ldirty(self, val: bool):
|
||||||
self.subs["ldirty"] = val
|
self.subs['ldirty'] = val
|
||||||
self.info(f"ldirty {'added to' if val else 'removed from'}")
|
self.info(f"ldirty {'added to' if val else 'removed from'}")
|
||||||
|
|
||||||
def get(self) -> list:
|
def get(self) -> list:
|
||||||
|
@ -29,8 +29,8 @@ class FactoryBuilder:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
BuilderProgress = IntEnum(
|
BuilderProgress = IntEnum(
|
||||||
"BuilderProgress",
|
'BuilderProgress',
|
||||||
"strip bus command macrobutton vban device option recorder patch fx",
|
'strip bus command macrobutton vban device option recorder patch fx',
|
||||||
start=0,
|
start=0,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,22 +38,22 @@ class FactoryBuilder:
|
|||||||
self._factory = factory
|
self._factory = factory
|
||||||
self.kind = kind
|
self.kind = kind
|
||||||
self._info = (
|
self._info = (
|
||||||
f"Finished building strips for {self._factory}",
|
f'Finished building strips for {self._factory}',
|
||||||
f"Finished building buses for {self._factory}",
|
f'Finished building buses for {self._factory}',
|
||||||
f"Finished building commands for {self._factory}",
|
f'Finished building commands for {self._factory}',
|
||||||
f"Finished building macrobuttons for {self._factory}",
|
f'Finished building macrobuttons for {self._factory}',
|
||||||
f"Finished building vban in/out streams for {self._factory}",
|
f'Finished building vban in/out streams for {self._factory}',
|
||||||
f"Finished building device for {self._factory}",
|
f'Finished building device for {self._factory}',
|
||||||
f"Finished building option for {self._factory}",
|
f'Finished building option for {self._factory}',
|
||||||
f"Finished building recorder for {self._factory}",
|
f'Finished building recorder for {self._factory}',
|
||||||
f"Finished building patch for {self._factory}",
|
f'Finished building patch for {self._factory}',
|
||||||
f"Finished building fx for {self._factory}",
|
f'Finished building fx for {self._factory}',
|
||||||
)
|
)
|
||||||
self.logger = logger.getChild(self.__class__.__name__)
|
self.logger = logger.getChild(self.__class__.__name__)
|
||||||
|
|
||||||
def _pinfo(self, name: str) -> None:
|
def _pinfo(self, name: str) -> None:
|
||||||
"""prints progress status for each step"""
|
"""prints progress status for each step"""
|
||||||
name = name.split("_")[1]
|
name = name.split('_')[1]
|
||||||
self.logger.debug(self._info[int(getattr(self.BuilderProgress, name))])
|
self.logger.debug(self._info[int(getattr(self.BuilderProgress, name))])
|
||||||
|
|
||||||
def make_strip(self):
|
def make_strip(self):
|
||||||
@ -108,17 +108,17 @@ class FactoryBase(Remote):
|
|||||||
|
|
||||||
def __init__(self, kind_id: str, **kwargs):
|
def __init__(self, kind_id: str, **kwargs):
|
||||||
defaultkwargs = {
|
defaultkwargs = {
|
||||||
"sync": False,
|
'sync': False,
|
||||||
"ratelimit": 0.033,
|
'ratelimit': 0.033,
|
||||||
"pdirty": False,
|
'pdirty': False,
|
||||||
"mdirty": False,
|
'mdirty': False,
|
||||||
"midi": False,
|
'midi': False,
|
||||||
"ldirty": False,
|
'ldirty': False,
|
||||||
"timeout": 2,
|
'timeout': 2,
|
||||||
"bits": 64,
|
'bits': 64,
|
||||||
}
|
}
|
||||||
if "subs" in kwargs:
|
if 'subs' in kwargs:
|
||||||
defaultkwargs |= kwargs.pop("subs") # for backwards compatibility
|
defaultkwargs |= kwargs.pop('subs') # for backwards compatibility
|
||||||
kwargs = defaultkwargs | kwargs
|
kwargs = defaultkwargs | kwargs
|
||||||
self.kind = kindmap(kind_id)
|
self.kind = kindmap(kind_id)
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
@ -135,7 +135,7 @@ class FactoryBase(Remote):
|
|||||||
self._configs = None
|
self._configs = None
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return f"Voicemeeter {self.kind}"
|
return f'Voicemeeter {self.kind}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
@ -225,15 +225,15 @@ def remote_factory(kind_id: str, **kwargs) -> Remote:
|
|||||||
Returns a Remote class of a kind
|
Returns a Remote class of a kind
|
||||||
"""
|
"""
|
||||||
match kind_id:
|
match kind_id:
|
||||||
case "basic":
|
case 'basic':
|
||||||
_factory = BasicFactory
|
_factory = BasicFactory
|
||||||
case "banana":
|
case 'banana':
|
||||||
_factory = BananaFactory
|
_factory = BananaFactory
|
||||||
case "potato":
|
case 'potato':
|
||||||
_factory = PotatoFactory
|
_factory = PotatoFactory
|
||||||
case _:
|
case _:
|
||||||
raise ValueError(f"Unknown Voicemeeter kind '{kind_id}'")
|
raise ValueError(f"Unknown Voicemeeter kind '{kind_id}'")
|
||||||
return type(f"Remote{kind_id.capitalize()}", (_factory,), {})(kind_id, **kwargs)
|
return type(f'Remote{kind_id.capitalize()}', (_factory,), {})(kind_id, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def request_remote_obj(kind_id: str, **kwargs) -> Remote:
|
def request_remote_obj(kind_id: str, **kwargs) -> Remote:
|
||||||
@ -243,12 +243,12 @@ def request_remote_obj(kind_id: str, **kwargs) -> Remote:
|
|||||||
Returns a reference to a Remote class of a kind
|
Returns a reference to a Remote class of a kind
|
||||||
"""
|
"""
|
||||||
|
|
||||||
logger_entry = logger.getChild("request_remote_obj")
|
logger_entry = logger.getChild('request_remote_obj')
|
||||||
|
|
||||||
REMOTE_obj = None
|
REMOTE_obj = None
|
||||||
try:
|
try:
|
||||||
REMOTE_obj = remote_factory(kind_id, **kwargs)
|
REMOTE_obj = remote_factory(kind_id, **kwargs)
|
||||||
except (ValueError, TypeError) as e:
|
except (ValueError, TypeError) as e:
|
||||||
logger_entry.exception(f"{type(e).__name__}: {e}")
|
logger_entry.exception(f'{type(e).__name__}: {e}')
|
||||||
raise VMError(str(e)) from e
|
raise VMError(str(e)) from e
|
||||||
return REMOTE_obj
|
return REMOTE_obj
|
||||||
|
@ -7,21 +7,21 @@ from .error import InstallError
|
|||||||
|
|
||||||
BITS = 64 if ct.sizeof(ct.c_void_p) == 8 else 32
|
BITS = 64 if ct.sizeof(ct.c_void_p) == 8 else 32
|
||||||
|
|
||||||
if platform.system() != "Windows":
|
if platform.system() != 'Windows':
|
||||||
raise InstallError("Only Windows OS supported")
|
raise InstallError('Only Windows OS supported')
|
||||||
|
|
||||||
|
|
||||||
VM_KEY = "VB:Voicemeeter {17359A74-1236-5467}"
|
VM_KEY = 'VB:Voicemeeter {17359A74-1236-5467}'
|
||||||
REG_KEY = "\\".join(
|
REG_KEY = '\\'.join(
|
||||||
filter(
|
filter(
|
||||||
None,
|
None,
|
||||||
(
|
(
|
||||||
"SOFTWARE",
|
'SOFTWARE',
|
||||||
"WOW6432Node" if BITS == 64 else "",
|
'WOW6432Node' if BITS == 64 else '',
|
||||||
"Microsoft",
|
'Microsoft',
|
||||||
"Windows",
|
'Windows',
|
||||||
"CurrentVersion",
|
'CurrentVersion',
|
||||||
"Uninstall",
|
'Uninstall',
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -29,20 +29,20 @@ REG_KEY = "\\".join(
|
|||||||
|
|
||||||
def get_vmpath():
|
def get_vmpath():
|
||||||
with winreg.OpenKey(
|
with winreg.OpenKey(
|
||||||
winreg.HKEY_LOCAL_MACHINE, r"{}".format("\\".join((REG_KEY, VM_KEY)))
|
winreg.HKEY_LOCAL_MACHINE, r'{}'.format('\\'.join((REG_KEY, VM_KEY)))
|
||||||
) as vm_key:
|
) as vm_key:
|
||||||
return winreg.QueryValueEx(vm_key, r"UninstallString")[0].strip('"')
|
return winreg.QueryValueEx(vm_key, r'UninstallString')[0].strip('"')
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
vm_parent = Path(get_vmpath()).parent
|
vm_parent = Path(get_vmpath()).parent
|
||||||
except FileNotFoundError as e:
|
except FileNotFoundError as e:
|
||||||
raise InstallError("Unable to fetch DLL path from the registry") from e
|
raise InstallError('Unable to fetch DLL path from the registry') from e
|
||||||
|
|
||||||
DLL_NAME = f'VoicemeeterRemote{"64" if BITS == 64 else ""}.dll'
|
DLL_NAME = f'VoicemeeterRemote{"64" if BITS == 64 else ""}.dll'
|
||||||
|
|
||||||
dll_path = vm_parent.joinpath(DLL_NAME)
|
dll_path = vm_parent.joinpath(DLL_NAME)
|
||||||
if not dll_path.is_file():
|
if not dll_path.is_file():
|
||||||
raise InstallError(f"Could not find {dll_path}")
|
raise InstallError(f'Could not find {dll_path}')
|
||||||
|
|
||||||
libc = ct.CDLL(str(dll_path))
|
libc = ct.CDLL(str(dll_path))
|
||||||
|
@ -19,19 +19,19 @@ class IRemote(metaclass=ABCMeta):
|
|||||||
|
|
||||||
def getter(self, param, **kwargs):
|
def getter(self, param, **kwargs):
|
||||||
"""Gets a parameter value"""
|
"""Gets a parameter value"""
|
||||||
self.logger.debug(f"getter: {self._cmd(param)}")
|
self.logger.debug(f'getter: {self._cmd(param)}')
|
||||||
return self._remote.get(self._cmd(param), **kwargs)
|
return self._remote.get(self._cmd(param), **kwargs)
|
||||||
|
|
||||||
def setter(self, param, val):
|
def setter(self, param, val):
|
||||||
"""Sets a parameter value"""
|
"""Sets a parameter value"""
|
||||||
self.logger.debug(f"setter: {self._cmd(param)}={val}")
|
self.logger.debug(f'setter: {self._cmd(param)}={val}')
|
||||||
self._remote.set(self._cmd(param), val)
|
self._remote.set(self._cmd(param), val)
|
||||||
|
|
||||||
def _cmd(self, param):
|
def _cmd(self, param):
|
||||||
cmd = (self.identifier,)
|
cmd = (self.identifier,)
|
||||||
if param:
|
if param:
|
||||||
cmd += (f".{param}",)
|
cmd += (f'.{param}',)
|
||||||
return "".join(cmd)
|
return ''.join(cmd)
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
@ -39,7 +39,7 @@ class IRemote(metaclass=ABCMeta):
|
|||||||
|
|
||||||
def apply(self, data: dict):
|
def apply(self, data: dict):
|
||||||
def fget(attr, val):
|
def fget(attr, val):
|
||||||
if attr == "mode":
|
if attr == 'mode':
|
||||||
return (getattr(self, attr), val, 1)
|
return (getattr(self, attr), val, 1)
|
||||||
return (self, attr, val)
|
return (self, attr, val)
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ class IRemote(metaclass=ABCMeta):
|
|||||||
target, attr, val = fget(attr, val)
|
target, attr, val = fget(attr, val)
|
||||||
setattr(target, attr, val)
|
setattr(target, attr, val)
|
||||||
else:
|
else:
|
||||||
self.logger.error(f"invalid attribute {attr} for {self}")
|
self.logger.error(f'invalid attribute {attr} for {self}')
|
||||||
else:
|
else:
|
||||||
target = getattr(self, attr)
|
target = getattr(self, attr)
|
||||||
target.apply(val)
|
target.apply(val)
|
||||||
|
@ -100,14 +100,14 @@ class PotatoMap(KindMapClass):
|
|||||||
|
|
||||||
def kind_factory(kind_id):
|
def kind_factory(kind_id):
|
||||||
match kind_id:
|
match kind_id:
|
||||||
case "basic":
|
case 'basic':
|
||||||
_kind_map = BasicMap
|
_kind_map = BasicMap
|
||||||
case "banana":
|
case 'banana':
|
||||||
_kind_map = BananaMap
|
_kind_map = BananaMap
|
||||||
case "potato":
|
case 'potato':
|
||||||
_kind_map = PotatoMap
|
_kind_map = PotatoMap
|
||||||
case _:
|
case _:
|
||||||
raise ValueError(f"Unknown Voicemeeter kind {kind_id}")
|
raise ValueError(f'Unknown Voicemeeter kind {kind_id}')
|
||||||
return _kind_map(name=kind_id)
|
return _kind_map(name=kind_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,8 +3,8 @@ from enum import IntEnum
|
|||||||
from .iremote import IRemote
|
from .iremote import IRemote
|
||||||
|
|
||||||
ButtonModes = IntEnum(
|
ButtonModes = IntEnum(
|
||||||
"ButtonModes",
|
'ButtonModes',
|
||||||
"state stateonly trigger",
|
'state stateonly trigger',
|
||||||
start=1,
|
start=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,12 +16,12 @@ class Adapter(IRemote):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def getter(self, mode):
|
def getter(self, mode):
|
||||||
self.logger.debug(f"getter: button[{self.index}].{ButtonModes(mode).name}")
|
self.logger.debug(f'getter: button[{self.index}].{ButtonModes(mode).name}')
|
||||||
return self._remote.get_buttonstatus(self.index, mode)
|
return self._remote.get_buttonstatus(self.index, mode)
|
||||||
|
|
||||||
def setter(self, mode, val):
|
def setter(self, mode, val):
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
f"setter: button[{self.index}].{ButtonModes(mode).name}={val}"
|
f'setter: button[{self.index}].{ButtonModes(mode).name}={val}'
|
||||||
)
|
)
|
||||||
self._remote.set_buttonstatus(self.index, val, mode)
|
self._remote.set_buttonstatus(self.index, val, mode)
|
||||||
|
|
||||||
@ -30,7 +30,7 @@ class MacroButton(Adapter):
|
|||||||
"""Defines concrete implementation for macrobutton"""
|
"""Defines concrete implementation for macrobutton"""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self._remote.kind}{self.index}"
|
return f'{type(self).__name__}{self._remote.kind}{self.index}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def state(self) -> bool:
|
def state(self) -> bool:
|
||||||
|
@ -6,43 +6,43 @@ from .iremote import IRemote
|
|||||||
|
|
||||||
class FX(IRemote):
|
class FX(IRemote):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}"
|
return f'{type(self).__name__}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "FX"
|
return 'FX'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reverb(self) -> bool:
|
def reverb(self) -> bool:
|
||||||
return self.getter("reverb.On") == 1
|
return self.getter('reverb.On') == 1
|
||||||
|
|
||||||
@reverb.setter
|
@reverb.setter
|
||||||
def reverb(self, val: bool):
|
def reverb(self, val: bool):
|
||||||
self.setter("reverb.On", 1 if val else 0)
|
self.setter('reverb.On', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reverb_ab(self) -> bool:
|
def reverb_ab(self) -> bool:
|
||||||
return self.getter("reverb.ab") == 1
|
return self.getter('reverb.ab') == 1
|
||||||
|
|
||||||
@reverb_ab.setter
|
@reverb_ab.setter
|
||||||
def reverb_ab(self, val: bool):
|
def reverb_ab(self, val: bool):
|
||||||
self.setter("reverb.ab", 1 if val else 0)
|
self.setter('reverb.ab', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def delay(self) -> bool:
|
def delay(self) -> bool:
|
||||||
return self.getter("delay.On") == 1
|
return self.getter('delay.On') == 1
|
||||||
|
|
||||||
@delay.setter
|
@delay.setter
|
||||||
def delay(self, val: bool):
|
def delay(self, val: bool):
|
||||||
self.setter("delay.On", 1 if val else 0)
|
self.setter('delay.On', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def delay_ab(self) -> bool:
|
def delay_ab(self) -> bool:
|
||||||
return self.getter("delay.ab") == 1
|
return self.getter('delay.ab') == 1
|
||||||
|
|
||||||
@delay_ab.setter
|
@delay_ab.setter
|
||||||
def delay_ab(self, val: bool):
|
def delay_ab(self, val: bool):
|
||||||
self.setter("delay.ab", 1 if val else 0)
|
self.setter('delay.ab', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class Patch(IRemote):
|
class Patch(IRemote):
|
||||||
@ -57,50 +57,50 @@ class Patch(IRemote):
|
|||||||
"""
|
"""
|
||||||
ASIO_cls = _make_asio_mixins(remote)[remote.kind.name]
|
ASIO_cls = _make_asio_mixins(remote)[remote.kind.name]
|
||||||
return type(
|
return type(
|
||||||
f"Patch{remote.kind}",
|
f'Patch{remote.kind}',
|
||||||
(cls, ASIO_cls),
|
(cls, ASIO_cls),
|
||||||
{
|
{
|
||||||
"composite": tuple(Composite(remote, i) for i in range(8)),
|
'composite': tuple(Composite(remote, i) for i in range(8)),
|
||||||
"insert": tuple(Insert(remote, i) for i in range(remote.kind.insert)),
|
'insert': tuple(Insert(remote, i) for i in range(remote.kind.insert)),
|
||||||
},
|
},
|
||||||
)(remote)
|
)(remote)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}"
|
return f'{type(self).__name__}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "patch"
|
return 'patch'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def postfadercomp(self) -> bool:
|
def postfadercomp(self) -> bool:
|
||||||
return self.getter("postfadercomposite") == 1
|
return self.getter('postfadercomposite') == 1
|
||||||
|
|
||||||
@postfadercomp.setter
|
@postfadercomp.setter
|
||||||
def postfadercomp(self, val: bool):
|
def postfadercomp(self, val: bool):
|
||||||
self.setter("postfadercomposite", 1 if val else 0)
|
self.setter('postfadercomposite', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def postfxinsert(self) -> bool:
|
def postfxinsert(self) -> bool:
|
||||||
return self.getter("postfxinsert") == 1
|
return self.getter('postfxinsert') == 1
|
||||||
|
|
||||||
@postfxinsert.setter
|
@postfxinsert.setter
|
||||||
def postfxinsert(self, val: bool):
|
def postfxinsert(self, val: bool):
|
||||||
self.setter("postfxinsert", 1 if val else 0)
|
self.setter('postfxinsert', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class Asio(IRemote):
|
class Asio(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "patch"
|
return 'patch'
|
||||||
|
|
||||||
|
|
||||||
class AsioIn(Asio):
|
class AsioIn(Asio):
|
||||||
def get(self) -> int:
|
def get(self) -> int:
|
||||||
return int(self.getter(f"asio[{self.index}]"))
|
return int(self.getter(f'asio[{self.index}]'))
|
||||||
|
|
||||||
def set(self, val: int):
|
def set(self, val: int):
|
||||||
self.setter(f"asio[{self.index}]", val)
|
self.setter(f'asio[{self.index}]', val)
|
||||||
|
|
||||||
|
|
||||||
class AsioOut(Asio):
|
class AsioOut(Asio):
|
||||||
@ -109,10 +109,10 @@ class AsioOut(Asio):
|
|||||||
self._param = param
|
self._param = param
|
||||||
|
|
||||||
def get(self) -> int:
|
def get(self) -> int:
|
||||||
return int(self.getter(f"out{self._param}[{self.index}]"))
|
return int(self.getter(f'out{self._param}[{self.index}]'))
|
||||||
|
|
||||||
def set(self, val: int):
|
def set(self, val: int):
|
||||||
self.setter(f"out{self._param}[{self.index}]", val)
|
self.setter(f'out{self._param}[{self.index}]', val)
|
||||||
|
|
||||||
|
|
||||||
def _make_asio_mixin(remote, kind):
|
def _make_asio_mixin(remote, kind):
|
||||||
@ -120,13 +120,13 @@ def _make_asio_mixin(remote, kind):
|
|||||||
asio_in, asio_out = kind.asio
|
asio_in, asio_out = kind.asio
|
||||||
|
|
||||||
return type(
|
return type(
|
||||||
f"ASIO{kind}",
|
f'ASIO{kind}',
|
||||||
(IRemote,),
|
(IRemote,),
|
||||||
{
|
{
|
||||||
"asio": tuple(AsioIn(remote, i) for i in range(asio_in)),
|
'asio': tuple(AsioIn(remote, i) for i in range(asio_in)),
|
||||||
**{
|
**{
|
||||||
param: tuple(AsioOut(remote, i, param) for i in range(asio_out))
|
param: tuple(AsioOut(remote, i, param) for i in range(asio_out))
|
||||||
for param in ["A2", "A3", "A4", "A5"]
|
for param in ['A2', 'A3', 'A4', 'A5']
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
@ -139,27 +139,27 @@ def _make_asio_mixins(remote):
|
|||||||
class Composite(IRemote):
|
class Composite(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "patch"
|
return 'patch'
|
||||||
|
|
||||||
def get(self) -> int:
|
def get(self) -> int:
|
||||||
return int(self.getter(f"composite[{self.index}]"))
|
return int(self.getter(f'composite[{self.index}]'))
|
||||||
|
|
||||||
def set(self, val: int):
|
def set(self, val: int):
|
||||||
self.setter(f"composite[{self.index}]", val)
|
self.setter(f'composite[{self.index}]', val)
|
||||||
|
|
||||||
|
|
||||||
class Insert(IRemote):
|
class Insert(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "patch"
|
return 'patch'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def on(self) -> bool:
|
def on(self) -> bool:
|
||||||
return self.getter(f"insert[{self.index}]") == 1
|
return self.getter(f'insert[{self.index}]') == 1
|
||||||
|
|
||||||
@on.setter
|
@on.setter
|
||||||
def on(self, val: bool):
|
def on(self, val: bool):
|
||||||
self.setter(f"insert[{self.index}]", 1 if val else 0)
|
self.setter(f'insert[{self.index}]', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class Option(IRemote):
|
class Option(IRemote):
|
||||||
@ -173,61 +173,61 @@ class Option(IRemote):
|
|||||||
Returns a Option class of a kind.
|
Returns a Option class of a kind.
|
||||||
"""
|
"""
|
||||||
return type(
|
return type(
|
||||||
f"Option{remote.kind}",
|
f'Option{remote.kind}',
|
||||||
(cls,),
|
(cls,),
|
||||||
{
|
{
|
||||||
"delay": tuple(Delay(remote, i) for i in range(remote.kind.phys_out)),
|
'delay': tuple(Delay(remote, i) for i in range(remote.kind.phys_out)),
|
||||||
},
|
},
|
||||||
)(remote)
|
)(remote)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}"
|
return f'{type(self).__name__}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "option"
|
return 'option'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sr(self) -> int:
|
def sr(self) -> int:
|
||||||
return int(self.getter("sr"))
|
return int(self.getter('sr'))
|
||||||
|
|
||||||
@sr.setter
|
@sr.setter
|
||||||
def sr(self, val: int):
|
def sr(self, val: int):
|
||||||
opts = (44100, 48000, 88200, 96000, 176400, 192000)
|
opts = (44100, 48000, 88200, 96000, 176400, 192000)
|
||||||
if val not in opts:
|
if val not in opts:
|
||||||
self.logger.warning(f"sr got: {val} but expected a value in {opts}")
|
self.logger.warning(f'sr got: {val} but expected a value in {opts}')
|
||||||
self.setter("sr", val)
|
self.setter('sr', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def asiosr(self) -> bool:
|
def asiosr(self) -> bool:
|
||||||
return self.getter("asiosr") == 1
|
return self.getter('asiosr') == 1
|
||||||
|
|
||||||
@asiosr.setter
|
@asiosr.setter
|
||||||
def asiosr(self, val: bool):
|
def asiosr(self, val: bool):
|
||||||
self.setter("asiosr", 1 if val else 0)
|
self.setter('asiosr', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def monitoronsel(self) -> bool:
|
def monitoronsel(self) -> bool:
|
||||||
return self.getter("monitoronsel") == 1
|
return self.getter('monitoronsel') == 1
|
||||||
|
|
||||||
@monitoronsel.setter
|
@monitoronsel.setter
|
||||||
def monitoronsel(self, val: bool):
|
def monitoronsel(self, val: bool):
|
||||||
self.setter("monitoronsel", 1 if val else 0)
|
self.setter('monitoronsel', 1 if val else 0)
|
||||||
|
|
||||||
def buffer(self, driver, buffer):
|
def buffer(self, driver, buffer):
|
||||||
self.setter(f"buffer.{driver}", buffer)
|
self.setter(f'buffer.{driver}', buffer)
|
||||||
|
|
||||||
|
|
||||||
class Delay(IRemote):
|
class Delay(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "option"
|
return 'option'
|
||||||
|
|
||||||
def get(self) -> int:
|
def get(self) -> int:
|
||||||
return int(self.getter(f"delay[{self.index}]"))
|
return int(self.getter(f'delay[{self.index}]'))
|
||||||
|
|
||||||
def set(self, val: int):
|
def set(self, val: int):
|
||||||
self.setter(f"delay[{self.index}]", val)
|
self.setter(f'delay[{self.index}]', val)
|
||||||
|
|
||||||
|
|
||||||
class Midi:
|
class Midi:
|
||||||
|
@ -23,91 +23,91 @@ class Recorder(IRemote):
|
|||||||
CHANNELOUTMIXIN_cls = _make_channelout_mixins[remote.kind.name]
|
CHANNELOUTMIXIN_cls = _make_channelout_mixins[remote.kind.name]
|
||||||
ARMCHANNELMIXIN_cls = _make_armchannel_mixins(remote)[remote.kind.name]
|
ARMCHANNELMIXIN_cls = _make_armchannel_mixins(remote)[remote.kind.name]
|
||||||
REC_cls = type(
|
REC_cls = type(
|
||||||
f"Recorder{remote.kind}",
|
f'Recorder{remote.kind}',
|
||||||
(cls, CHANNELOUTMIXIN_cls, ARMCHANNELMIXIN_cls),
|
(cls, CHANNELOUTMIXIN_cls, ARMCHANNELMIXIN_cls),
|
||||||
{
|
{
|
||||||
**{
|
**{
|
||||||
param: action_fn(param)
|
param: action_fn(param)
|
||||||
for param in [
|
for param in [
|
||||||
"play",
|
'play',
|
||||||
"stop",
|
'stop',
|
||||||
"pause",
|
'pause',
|
||||||
"replay",
|
'replay',
|
||||||
"record",
|
'record',
|
||||||
"ff",
|
'ff',
|
||||||
"rew",
|
'rew',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"mode": RecorderMode(remote),
|
'mode': RecorderMode(remote),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return REC_cls(remote)
|
return REC_cls(remote)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}"
|
return f'{type(self).__name__}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return "recorder"
|
return 'recorder'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def samplerate(self) -> int:
|
def samplerate(self) -> int:
|
||||||
return int(self.getter("samplerate"))
|
return int(self.getter('samplerate'))
|
||||||
|
|
||||||
@samplerate.setter
|
@samplerate.setter
|
||||||
def samplerate(self, val: int):
|
def samplerate(self, val: int):
|
||||||
opts = (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
opts = (22050, 24000, 32000, 44100, 48000, 88200, 96000, 176400, 192000)
|
||||||
if val not in opts:
|
if val not in opts:
|
||||||
self.logger.warning(f"samplerate got: {val} but expected a value in {opts}")
|
self.logger.warning(f'samplerate got: {val} but expected a value in {opts}')
|
||||||
self.setter("samplerate", val)
|
self.setter('samplerate', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bitresolution(self) -> int:
|
def bitresolution(self) -> int:
|
||||||
return int(self.getter("bitresolution"))
|
return int(self.getter('bitresolution'))
|
||||||
|
|
||||||
@bitresolution.setter
|
@bitresolution.setter
|
||||||
def bitresolution(self, val: int):
|
def bitresolution(self, val: int):
|
||||||
opts = (8, 16, 24, 32)
|
opts = (8, 16, 24, 32)
|
||||||
if val not in opts:
|
if val not in opts:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
f"bitresolution got: {val} but expected a value in {opts}"
|
f'bitresolution got: {val} but expected a value in {opts}'
|
||||||
)
|
)
|
||||||
self.setter("bitresolution", val)
|
self.setter('bitresolution', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def channel(self) -> int:
|
def channel(self) -> int:
|
||||||
return int(self.getter("channel"))
|
return int(self.getter('channel'))
|
||||||
|
|
||||||
@channel.setter
|
@channel.setter
|
||||||
def channel(self, val: int):
|
def channel(self, val: int):
|
||||||
if not 1 <= val <= 8:
|
if not 1 <= val <= 8:
|
||||||
self.logger.warning(f"channel got: {val} but expected a value from 1 to 8")
|
self.logger.warning(f'channel got: {val} but expected a value from 1 to 8')
|
||||||
self.setter("channel", val)
|
self.setter('channel', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kbps(self):
|
def kbps(self):
|
||||||
return int(self.getter("kbps"))
|
return int(self.getter('kbps'))
|
||||||
|
|
||||||
@kbps.setter
|
@kbps.setter
|
||||||
def kbps(self, val: int):
|
def kbps(self, val: int):
|
||||||
opts = (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
|
opts = (32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320)
|
||||||
if val not in opts:
|
if val not in opts:
|
||||||
self.logger.warning(f"kbps got: {val} but expected a value in {opts}")
|
self.logger.warning(f'kbps got: {val} but expected a value in {opts}')
|
||||||
self.setter("kbps", val)
|
self.setter('kbps', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gain(self) -> float:
|
def gain(self) -> float:
|
||||||
return round(self.getter("gain"), 1)
|
return round(self.getter('gain'), 1)
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val: float):
|
def gain(self, val: float):
|
||||||
self.setter("gain", val)
|
self.setter('gain', val)
|
||||||
|
|
||||||
def load(self, file: str):
|
def load(self, file: str):
|
||||||
try:
|
try:
|
||||||
self.setter("load", file)
|
self.setter('load', file)
|
||||||
except UnicodeError:
|
except UnicodeError:
|
||||||
raise VMError("File full directory must be a raw string")
|
raise VMError('File full directory must be a raw string')
|
||||||
|
|
||||||
# loop forwarder methods, for backwards compatibility
|
# loop forwarder methods, for backwards compatibility
|
||||||
@property
|
@property
|
||||||
@ -121,69 +121,69 @@ class Recorder(IRemote):
|
|||||||
def goto(self, time_str):
|
def goto(self, time_str):
|
||||||
def get_sec():
|
def get_sec():
|
||||||
"""Get seconds from time string"""
|
"""Get seconds from time string"""
|
||||||
h, m, s = time_str.split(":")
|
h, m, s = time_str.split(':')
|
||||||
return int(h) * 3600 + int(m) * 60 + int(s)
|
return int(h) * 3600 + int(m) * 60 + int(s)
|
||||||
|
|
||||||
time_str = str(time_str) # coerce the type
|
time_str = str(time_str) # coerce the type
|
||||||
if (
|
if (
|
||||||
re.match(
|
re.match(
|
||||||
r"^(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)$",
|
r'^(?:[01]\d|2[0123]):(?:[012345]\d):(?:[012345]\d)$',
|
||||||
time_str,
|
time_str,
|
||||||
)
|
)
|
||||||
is not None
|
is not None
|
||||||
):
|
):
|
||||||
self.setter("goto", get_sec())
|
self.setter('goto', get_sec())
|
||||||
else:
|
else:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
"goto expects a string that matches the format 'hh:mm:ss'"
|
"goto expects a string that matches the format 'hh:mm:ss'"
|
||||||
)
|
)
|
||||||
|
|
||||||
def filetype(self, val: str):
|
def filetype(self, val: str):
|
||||||
opts = {"wav": 1, "aiff": 2, "bwf": 3, "mp3": 100}
|
opts = {'wav': 1, 'aiff': 2, 'bwf': 3, 'mp3': 100}
|
||||||
try:
|
try:
|
||||||
self.setter("filetype", opts[val.lower()])
|
self.setter('filetype', opts[val.lower()])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
f"filetype got: {val} but expected a value in {list(opts.keys())}"
|
f'filetype got: {val} but expected a value in {list(opts.keys())}'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class RecorderMode(IRemote):
|
class RecorderMode(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
return "recorder.mode"
|
return 'recorder.mode'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def recbus(self) -> bool:
|
def recbus(self) -> bool:
|
||||||
return self.getter("recbus") == 1
|
return self.getter('recbus') == 1
|
||||||
|
|
||||||
@recbus.setter
|
@recbus.setter
|
||||||
def recbus(self, val: bool):
|
def recbus(self, val: bool):
|
||||||
self.setter("recbus", 1 if val else 0)
|
self.setter('recbus', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def playonload(self) -> bool:
|
def playonload(self) -> bool:
|
||||||
return self.getter("playonload") == 1
|
return self.getter('playonload') == 1
|
||||||
|
|
||||||
@playonload.setter
|
@playonload.setter
|
||||||
def playonload(self, val: bool):
|
def playonload(self, val: bool):
|
||||||
self.setter("playonload", 1 if val else 0)
|
self.setter('playonload', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def loop(self) -> bool:
|
def loop(self) -> bool:
|
||||||
return self.getter("loop") == 1
|
return self.getter('loop') == 1
|
||||||
|
|
||||||
@loop.setter
|
@loop.setter
|
||||||
def loop(self, val: bool):
|
def loop(self, val: bool):
|
||||||
self.setter("loop", 1 if val else 0)
|
self.setter('loop', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def multitrack(self) -> bool:
|
def multitrack(self) -> bool:
|
||||||
return self.getter("multitrack") == 1
|
return self.getter('multitrack') == 1
|
||||||
|
|
||||||
@multitrack.setter
|
@multitrack.setter
|
||||||
def multitrack(self, val: bool):
|
def multitrack(self, val: bool):
|
||||||
self.setter("multitrack", 1 if val else 0)
|
self.setter('multitrack', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class RecorderArmChannel(IRemote):
|
class RecorderArmChannel(IRemote):
|
||||||
@ -192,31 +192,31 @@ class RecorderArmChannel(IRemote):
|
|||||||
self._i = i
|
self._i = i
|
||||||
|
|
||||||
def set(self, val: bool):
|
def set(self, val: bool):
|
||||||
self.setter("", 1 if val else 0)
|
self.setter('', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class RecorderArmStrip(RecorderArmChannel):
|
class RecorderArmStrip(RecorderArmChannel):
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
return f"recorder.armstrip[{self._i}]"
|
return f'recorder.armstrip[{self._i}]'
|
||||||
|
|
||||||
|
|
||||||
class RecorderArmBus(RecorderArmChannel):
|
class RecorderArmBus(RecorderArmChannel):
|
||||||
@property
|
@property
|
||||||
def identifier(self):
|
def identifier(self):
|
||||||
return f"recorder.armbus[{self._i}]"
|
return f'recorder.armbus[{self._i}]'
|
||||||
|
|
||||||
|
|
||||||
def _make_armchannel_mixin(remote, kind):
|
def _make_armchannel_mixin(remote, kind):
|
||||||
"""Creates an armchannel out mixin"""
|
"""Creates an armchannel out mixin"""
|
||||||
return type(
|
return type(
|
||||||
f"ArmChannelMixin{kind}",
|
f'ArmChannelMixin{kind}',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
"armstrip": tuple(
|
'armstrip': tuple(
|
||||||
RecorderArmStrip(remote, i) for i in range(kind.num_strip)
|
RecorderArmStrip(remote, i) for i in range(kind.num_strip)
|
||||||
),
|
),
|
||||||
"armbus": tuple(RecorderArmBus(remote, i) for i in range(kind.num_bus)),
|
'armbus': tuple(RecorderArmBus(remote, i) for i in range(kind.num_bus)),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -228,11 +228,11 @@ def _make_armchannel_mixins(remote):
|
|||||||
def _make_channelout_mixin(kind):
|
def _make_channelout_mixin(kind):
|
||||||
"""Creates a channel out mixin"""
|
"""Creates a channel out mixin"""
|
||||||
return type(
|
return type(
|
||||||
f"ChannelOutMixin{kind}",
|
f'ChannelOutMixin{kind}',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
**{f"A{i}": bool_prop(f"A{i}") for i in range(1, kind.phys_out + 1)},
|
**{f'A{i}': bool_prop(f'A{i}') for i in range(1, kind.phys_out + 1)},
|
||||||
**{f"B{i}": bool_prop(f"B{i}") for i in range(1, kind.virt_out + 1)},
|
**{f'B{i}': bool_prop(f'B{i}') for i in range(1, kind.virt_out + 1)},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class Remote(CBindings):
|
|||||||
self.midi = Midi()
|
self.midi = Midi()
|
||||||
self.subject = self.observer = Subject()
|
self.subject = self.observer = Subject()
|
||||||
self.event = Event(
|
self.event = Event(
|
||||||
{k: kwargs.pop(k) for k in ("pdirty", "mdirty", "midi", "ldirty")}
|
{k: kwargs.pop(k) for k in ('pdirty', 'mdirty', 'midi', 'ldirty')}
|
||||||
)
|
)
|
||||||
self.gui = VmGui()
|
self.gui = VmGui()
|
||||||
self.stop_event = None
|
self.stop_event = None
|
||||||
@ -41,7 +41,7 @@ class Remote(CBindings):
|
|||||||
|
|
||||||
if self.bits not in (32, 64):
|
if self.bits not in (32, 64):
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
f"kwarg bits got {self.bits}, expected either 32 or 64, defaulting to 64"
|
f'kwarg bits got {self.bits}, expected either 32 or 64, defaulting to 64'
|
||||||
)
|
)
|
||||||
self.bits = 64
|
self.bits = 64
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ class Remote(CBindings):
|
|||||||
"""Starts updates thread."""
|
"""Starts updates thread."""
|
||||||
self.event.info()
|
self.event.info()
|
||||||
|
|
||||||
self.logger.debug("initiating events thread")
|
self.logger.debug('initiating events thread')
|
||||||
self.stop_event = threading.Event()
|
self.stop_event = threading.Event()
|
||||||
self.stop_event.clear()
|
self.stop_event.clear()
|
||||||
queue = Queue()
|
queue = Queue()
|
||||||
@ -79,7 +79,7 @@ class Remote(CBindings):
|
|||||||
self.gui.launched = self.call(self.bind_login, ok=(0, 1)) == 0
|
self.gui.launched = self.call(self.bind_login, ok=(0, 1)) == 0
|
||||||
if not self.gui.launched:
|
if not self.gui.launched:
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
"Voicemeeter engine running but GUI not launched. Launching the GUI now."
|
'Voicemeeter engine running but GUI not launched. Launching the GUI now.'
|
||||||
)
|
)
|
||||||
self.run_voicemeeter(self.kind.name)
|
self.run_voicemeeter(self.kind.name)
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ class Remote(CBindings):
|
|||||||
"""Returns Voicemeeter's version as a string"""
|
"""Returns Voicemeeter's version as a string"""
|
||||||
ver = ct.c_long()
|
ver = ct.c_long()
|
||||||
self.call(self.bind_get_voicemeeter_version, ct.byref(ver))
|
self.call(self.bind_get_voicemeeter_version, ct.byref(ver))
|
||||||
return "{}.{}.{}.{}".format(
|
return '{}.{}.{}.{}'.format(
|
||||||
(ver.value & 0xFF000000) >> 24,
|
(ver.value & 0xFF000000) >> 24,
|
||||||
(ver.value & 0x00FF0000) >> 16,
|
(ver.value & 0x00FF0000) >> 16,
|
||||||
(ver.value & 0x0000FF00) >> 8,
|
(ver.value & 0x0000FF00) >> 8,
|
||||||
@ -121,16 +121,16 @@ class Remote(CBindings):
|
|||||||
try:
|
try:
|
||||||
return self.call(self.bind_macro_button_is_dirty, ok=(0, 1)) == 1
|
return self.call(self.bind_macro_button_is_dirty, ok=(0, 1)) == 1
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
self.logger.exception(f"{type(e).__name__}: {e}")
|
self.logger.exception(f'{type(e).__name__}: {e}')
|
||||||
raise CAPIError("VBVMR_MacroButton_IsDirty", -9) from e
|
raise CAPIError('VBVMR_MacroButton_IsDirty', -9) from e
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ldirty(self) -> bool:
|
def ldirty(self) -> bool:
|
||||||
"""True iff levels have been updated."""
|
"""True iff levels have been updated."""
|
||||||
self._strip_buf, self._bus_buf = self._get_levels()
|
self._strip_buf, self._bus_buf = self._get_levels()
|
||||||
return not (
|
return not (
|
||||||
self.cache.get("strip_level") == self._strip_buf
|
self.cache.get('strip_level') == self._strip_buf
|
||||||
and self.cache.get("bus_level") == self._bus_buf
|
and self.cache.get('bus_level') == self._bus_buf
|
||||||
)
|
)
|
||||||
|
|
||||||
def clear_dirty(self) -> None:
|
def clear_dirty(self) -> None:
|
||||||
@ -138,9 +138,9 @@ class Remote(CBindings):
|
|||||||
while self.pdirty or self.mdirty:
|
while self.pdirty or self.mdirty:
|
||||||
pass
|
pass
|
||||||
except CAPIError as e:
|
except CAPIError as e:
|
||||||
if not (e.fn_name == "VBVMR_MacroButton_IsDirty" and e.code == -9):
|
if not (e.fn_name == 'VBVMR_MacroButton_IsDirty' and e.code == -9):
|
||||||
raise
|
raise
|
||||||
self.logger.error(f"{e} clearing pdirty only.")
|
self.logger.error(f'{e} clearing pdirty only.')
|
||||||
while self.pdirty:
|
while self.pdirty:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -159,7 +159,7 @@ class Remote(CBindings):
|
|||||||
"""Sets a string or float parameter. Caches value"""
|
"""Sets a string or float parameter. Caches value"""
|
||||||
if isinstance(val, str):
|
if isinstance(val, str):
|
||||||
if len(val) >= 512:
|
if len(val) >= 512:
|
||||||
raise VMError("String is too long")
|
raise VMError('String is too long')
|
||||||
self.call(
|
self.call(
|
||||||
self.bind_set_parameter_string_w, param.encode(), ct.c_wchar_p(val)
|
self.bind_set_parameter_string_w, param.encode(), ct.c_wchar_p(val)
|
||||||
)
|
)
|
||||||
@ -181,8 +181,8 @@ class Remote(CBindings):
|
|||||||
ct.c_long(mode),
|
ct.c_long(mode),
|
||||||
)
|
)
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
self.logger.exception(f"{type(e).__name__}: {e}")
|
self.logger.exception(f'{type(e).__name__}: {e}')
|
||||||
raise CAPIError("VBVMR_MacroButton_GetStatus", -9) from e
|
raise CAPIError('VBVMR_MacroButton_GetStatus', -9) from e
|
||||||
return int(c_state.value)
|
return int(c_state.value)
|
||||||
|
|
||||||
def set_buttonstatus(self, id_: int, val: int, mode: int) -> None:
|
def set_buttonstatus(self, id_: int, val: int, mode: int) -> None:
|
||||||
@ -196,26 +196,26 @@ class Remote(CBindings):
|
|||||||
ct.c_long(mode),
|
ct.c_long(mode),
|
||||||
)
|
)
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
self.logger.exception(f"{type(e).__name__}: {e}")
|
self.logger.exception(f'{type(e).__name__}: {e}')
|
||||||
raise CAPIError("VBVMR_MacroButton_SetStatus", -9) from e
|
raise CAPIError('VBVMR_MacroButton_SetStatus', -9) from e
|
||||||
self.cache[f"mb_{id_}_{mode}"] = int(c_state.value)
|
self.cache[f'mb_{id_}_{mode}'] = int(c_state.value)
|
||||||
|
|
||||||
def get_num_devices(self, direction: str = None) -> int:
|
def get_num_devices(self, direction: str = None) -> int:
|
||||||
"""Retrieves number of physical devices connected"""
|
"""Retrieves number of physical devices connected"""
|
||||||
if direction not in ("in", "out"):
|
if direction not in ('in', 'out'):
|
||||||
raise VMError("Expected a direction: in or out")
|
raise VMError('Expected a direction: in or out')
|
||||||
func = getattr(self, f"bind_{direction}put_get_device_number")
|
func = getattr(self, f'bind_{direction}put_get_device_number')
|
||||||
res = self.call(func, ok_exp=lambda r: r >= 0)
|
res = self.call(func, ok_exp=lambda r: r >= 0)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_device_description(self, index: int, direction: str = None) -> tuple:
|
def get_device_description(self, index: int, direction: str = None) -> tuple:
|
||||||
"""Returns a tuple of device parameters"""
|
"""Returns a tuple of device parameters"""
|
||||||
if direction not in ("in", "out"):
|
if direction not in ('in', 'out'):
|
||||||
raise VMError("Expected a direction: in or out")
|
raise VMError('Expected a direction: in or out')
|
||||||
type_ = ct.c_long()
|
type_ = ct.c_long()
|
||||||
name = ct.create_unicode_buffer(256)
|
name = ct.create_unicode_buffer(256)
|
||||||
hwid = ct.create_unicode_buffer(256)
|
hwid = ct.create_unicode_buffer(256)
|
||||||
func = getattr(self, f"bind_{direction}put_get_device_desc_w")
|
func = getattr(self, f'bind_{direction}put_get_device_desc_w')
|
||||||
self.call(
|
self.call(
|
||||||
func,
|
func,
|
||||||
ct.c_long(index),
|
ct.c_long(index),
|
||||||
@ -257,7 +257,7 @@ class Remote(CBindings):
|
|||||||
)
|
)
|
||||||
if res > 0:
|
if res > 0:
|
||||||
vals = tuple(
|
vals = tuple(
|
||||||
grouper(3, (int.from_bytes(buf[i], "little") for i in range(res)))
|
grouper(3, (int.from_bytes(buf[i], 'little') for i in range(res)))
|
||||||
)
|
)
|
||||||
for msg in vals:
|
for msg in vals:
|
||||||
ch, pitch, vel = msg
|
ch, pitch, vel = msg
|
||||||
@ -271,7 +271,7 @@ class Remote(CBindings):
|
|||||||
def sendtext(self, script: str):
|
def sendtext(self, script: str):
|
||||||
"""Sets many parameters from a script"""
|
"""Sets many parameters from a script"""
|
||||||
if len(script) > 48000:
|
if len(script) > 48000:
|
||||||
raise ValueError("Script too large, max size 48kB")
|
raise ValueError('Script too large, max size 48kB')
|
||||||
self.call(self.bind_set_parameters, script.encode())
|
self.call(self.bind_set_parameters, script.encode())
|
||||||
time.sleep(self.DELAY * 5)
|
time.sleep(self.DELAY * 5)
|
||||||
|
|
||||||
@ -283,15 +283,15 @@ class Remote(CBindings):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def target(key):
|
def target(key):
|
||||||
match key.split("-"):
|
match key.split('-'):
|
||||||
case ["strip" | "bus" | "button" as kls, index] if index.isnumeric():
|
case ['strip' | 'bus' | 'button' as kls, index] if index.isnumeric():
|
||||||
target = getattr(self, kls)
|
target = getattr(self, kls)
|
||||||
case [
|
case [
|
||||||
"vban",
|
'vban',
|
||||||
"in"
|
'in'
|
||||||
| "instream"
|
| 'instream'
|
||||||
| "out"
|
| 'out'
|
||||||
| "outstream" as direction,
|
| 'outstream' as direction,
|
||||||
index,
|
index,
|
||||||
] if index.isnumeric():
|
] if index.isnumeric():
|
||||||
target = getattr(
|
target = getattr(
|
||||||
@ -309,20 +309,20 @@ class Remote(CBindings):
|
|||||||
"""applies a config from memory"""
|
"""applies a config from memory"""
|
||||||
ERR_MSG = (
|
ERR_MSG = (
|
||||||
f"No config with name '{name}' is loaded into memory",
|
f"No config with name '{name}' is loaded into memory",
|
||||||
f"Known configs: {list(self.configs.keys())}",
|
f'Known configs: {list(self.configs.keys())}',
|
||||||
)
|
)
|
||||||
try:
|
try:
|
||||||
config = self.configs[name]
|
config = self.configs[name]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
self.logger.error(("\n").join(ERR_MSG))
|
self.logger.error(('\n').join(ERR_MSG))
|
||||||
raise VMError(("\n").join(ERR_MSG)) from e
|
raise VMError(('\n').join(ERR_MSG)) from e
|
||||||
|
|
||||||
if "extends" in config:
|
if 'extends' in config:
|
||||||
extended = config["extends"]
|
extended = config['extends']
|
||||||
config = {
|
config = {
|
||||||
k: v
|
k: v
|
||||||
for k, v in deep_merge(self.configs[extended], config)
|
for k, v in deep_merge(self.configs[extended], config)
|
||||||
if k not in ("extends")
|
if k not in ('extends')
|
||||||
}
|
}
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
f"profile '{name}' extends '{extended}', profiles merged.."
|
f"profile '{name}' extends '{extended}', profiles merged.."
|
||||||
@ -332,7 +332,7 @@ class Remote(CBindings):
|
|||||||
|
|
||||||
def end_thread(self):
|
def end_thread(self):
|
||||||
if not self.stopped():
|
if not self.stopped():
|
||||||
self.logger.debug("events thread shutdown started")
|
self.logger.debug('events thread shutdown started')
|
||||||
self.stop_event.set()
|
self.stop_event.set()
|
||||||
self.producer.join() # wait for producer thread to complete cycle
|
self.producer.join() # wait for producer thread to complete cycle
|
||||||
|
|
||||||
@ -340,7 +340,7 @@ class Remote(CBindings):
|
|||||||
"""Logout of the API"""
|
"""Logout of the API"""
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
self.call(self.bind_logout)
|
self.call(self.bind_logout)
|
||||||
self.logger.info(f"{type(self).__name__}: Successfully logged out of {self}")
|
self.logger.info(f'{type(self).__name__}: Successfully logged out of {self}')
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
|
def __exit__(self, exc_type, exc_value, exc_traceback) -> None:
|
||||||
"""teardown procedures"""
|
"""teardown procedures"""
|
||||||
|
@ -21,62 +21,62 @@ class Strip(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"strip[{self.index}]"
|
return f'strip[{self.index}]'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mono(self) -> bool:
|
def mono(self) -> bool:
|
||||||
return self.getter("mono") == 1
|
return self.getter('mono') == 1
|
||||||
|
|
||||||
@mono.setter
|
@mono.setter
|
||||||
def mono(self, val: bool):
|
def mono(self, val: bool):
|
||||||
self.setter("mono", 1 if val else 0)
|
self.setter('mono', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def solo(self) -> bool:
|
def solo(self) -> bool:
|
||||||
return self.getter("solo") == 1
|
return self.getter('solo') == 1
|
||||||
|
|
||||||
@solo.setter
|
@solo.setter
|
||||||
def solo(self, val: bool):
|
def solo(self, val: bool):
|
||||||
self.setter("solo", 1 if val else 0)
|
self.setter('solo', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mute(self) -> bool:
|
def mute(self) -> bool:
|
||||||
return self.getter("mute") == 1
|
return self.getter('mute') == 1
|
||||||
|
|
||||||
@mute.setter
|
@mute.setter
|
||||||
def mute(self, val: bool):
|
def mute(self, val: bool):
|
||||||
self.setter("mute", 1 if val else 0)
|
self.setter('mute', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def limit(self) -> int:
|
def limit(self) -> int:
|
||||||
return int(self.getter("limit"))
|
return int(self.getter('limit'))
|
||||||
|
|
||||||
@limit.setter
|
@limit.setter
|
||||||
def limit(self, val: int):
|
def limit(self, val: int):
|
||||||
self.setter("limit", val)
|
self.setter('limit', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def label(self) -> str:
|
def label(self) -> str:
|
||||||
return self.getter("Label", is_string=True)
|
return self.getter('Label', is_string=True)
|
||||||
|
|
||||||
@label.setter
|
@label.setter
|
||||||
def label(self, val: str):
|
def label(self, val: str):
|
||||||
self.setter("Label", str(val))
|
self.setter('Label', str(val))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gain(self) -> float:
|
def gain(self) -> float:
|
||||||
return round(self.getter("gain"), 1)
|
return round(self.getter('gain'), 1)
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val: float):
|
def gain(self, val: float):
|
||||||
self.setter("gain", val)
|
self.setter('gain', val)
|
||||||
|
|
||||||
def fadeto(self, target: float, time_: int):
|
def fadeto(self, target: float, time_: int):
|
||||||
self.setter("FadeTo", f"({target}, {time_})")
|
self.setter('FadeTo', f'({target}, {time_})')
|
||||||
time.sleep(self._remote.DELAY)
|
time.sleep(self._remote.DELAY)
|
||||||
|
|
||||||
def fadeby(self, change: float, time_: int):
|
def fadeby(self, change: float, time_: int):
|
||||||
self.setter("FadeBy", f"({change}, {time_})")
|
self.setter('FadeBy', f'({change}, {time_})')
|
||||||
time.sleep(self._remote.DELAY)
|
time.sleep(self._remote.DELAY)
|
||||||
|
|
||||||
|
|
||||||
@ -90,203 +90,203 @@ class PhysicalStrip(Strip):
|
|||||||
"""
|
"""
|
||||||
EFFECTS_cls = _make_effects_mixins(is_phys)[remote.kind.name]
|
EFFECTS_cls = _make_effects_mixins(is_phys)[remote.kind.name]
|
||||||
return type(
|
return type(
|
||||||
"PhysicalStrip",
|
'PhysicalStrip',
|
||||||
(cls, EFFECTS_cls),
|
(cls, EFFECTS_cls),
|
||||||
{
|
{
|
||||||
"comp": StripComp(remote, i),
|
'comp': StripComp(remote, i),
|
||||||
"gate": StripGate(remote, i),
|
'gate': StripGate(remote, i),
|
||||||
"denoiser": StripDenoiser(remote, i),
|
'denoiser': StripDenoiser(remote, i),
|
||||||
"eq": StripEQ(remote, i),
|
'eq': StripEQ(remote, i),
|
||||||
"device": StripDevice.make(remote, i),
|
'device': StripDevice.make(remote, i),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self.index}"
|
return f'{type(self).__name__}{self.index}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def audibility(self) -> float:
|
def audibility(self) -> float:
|
||||||
return round(self.getter("audibility"), 1)
|
return round(self.getter('audibility'), 1)
|
||||||
|
|
||||||
@audibility.setter
|
@audibility.setter
|
||||||
def audibility(self, val: float):
|
def audibility(self, val: float):
|
||||||
self.setter("audibility", val)
|
self.setter('audibility', val)
|
||||||
|
|
||||||
|
|
||||||
class StripComp(IRemote):
|
class StripComp(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}].comp"
|
return f'Strip[{self.index}].comp'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def knob(self) -> float:
|
def knob(self) -> float:
|
||||||
return round(self.getter(""), 1)
|
return round(self.getter(''), 1)
|
||||||
|
|
||||||
@knob.setter
|
@knob.setter
|
||||||
def knob(self, val: float):
|
def knob(self, val: float):
|
||||||
self.setter("", val)
|
self.setter('', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gainin(self) -> float:
|
def gainin(self) -> float:
|
||||||
return round(self.getter("GainIn"), 1)
|
return round(self.getter('GainIn'), 1)
|
||||||
|
|
||||||
@gainin.setter
|
@gainin.setter
|
||||||
def gainin(self, val: float):
|
def gainin(self, val: float):
|
||||||
self.setter("GainIn", val)
|
self.setter('GainIn', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ratio(self) -> float:
|
def ratio(self) -> float:
|
||||||
return round(self.getter("Ratio"), 1)
|
return round(self.getter('Ratio'), 1)
|
||||||
|
|
||||||
@ratio.setter
|
@ratio.setter
|
||||||
def ratio(self, val: float):
|
def ratio(self, val: float):
|
||||||
self.setter("Ratio", val)
|
self.setter('Ratio', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def threshold(self) -> float:
|
def threshold(self) -> float:
|
||||||
return round(self.getter("Threshold"), 1)
|
return round(self.getter('Threshold'), 1)
|
||||||
|
|
||||||
@threshold.setter
|
@threshold.setter
|
||||||
def threshold(self, val: float):
|
def threshold(self, val: float):
|
||||||
self.setter("Threshold", val)
|
self.setter('Threshold', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attack(self) -> float:
|
def attack(self) -> float:
|
||||||
return round(self.getter("Attack"), 1)
|
return round(self.getter('Attack'), 1)
|
||||||
|
|
||||||
@attack.setter
|
@attack.setter
|
||||||
def attack(self, val: float):
|
def attack(self, val: float):
|
||||||
self.setter("Attack", val)
|
self.setter('Attack', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def release(self) -> float:
|
def release(self) -> float:
|
||||||
return round(self.getter("Release"), 1)
|
return round(self.getter('Release'), 1)
|
||||||
|
|
||||||
@release.setter
|
@release.setter
|
||||||
def release(self, val: float):
|
def release(self, val: float):
|
||||||
self.setter("Release", val)
|
self.setter('Release', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def knee(self) -> float:
|
def knee(self) -> float:
|
||||||
return round(self.getter("Knee"), 2)
|
return round(self.getter('Knee'), 2)
|
||||||
|
|
||||||
@knee.setter
|
@knee.setter
|
||||||
def knee(self, val: float):
|
def knee(self, val: float):
|
||||||
self.setter("Knee", val)
|
self.setter('Knee', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gainout(self) -> float:
|
def gainout(self) -> float:
|
||||||
return round(self.getter("GainOut"), 1)
|
return round(self.getter('GainOut'), 1)
|
||||||
|
|
||||||
@gainout.setter
|
@gainout.setter
|
||||||
def gainout(self, val: float):
|
def gainout(self, val: float):
|
||||||
self.setter("GainOut", val)
|
self.setter('GainOut', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def makeup(self) -> bool:
|
def makeup(self) -> bool:
|
||||||
return self.getter("makeup") == 1
|
return self.getter('makeup') == 1
|
||||||
|
|
||||||
@makeup.setter
|
@makeup.setter
|
||||||
def makeup(self, val: bool):
|
def makeup(self, val: bool):
|
||||||
self.setter("makeup", 1 if val else 0)
|
self.setter('makeup', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class StripGate(IRemote):
|
class StripGate(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}].gate"
|
return f'Strip[{self.index}].gate'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def knob(self) -> float:
|
def knob(self) -> float:
|
||||||
return round(self.getter(""), 1)
|
return round(self.getter(''), 1)
|
||||||
|
|
||||||
@knob.setter
|
@knob.setter
|
||||||
def knob(self, val: float):
|
def knob(self, val: float):
|
||||||
self.setter("", val)
|
self.setter('', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def threshold(self) -> float:
|
def threshold(self) -> float:
|
||||||
return round(self.getter("Threshold"), 1)
|
return round(self.getter('Threshold'), 1)
|
||||||
|
|
||||||
@threshold.setter
|
@threshold.setter
|
||||||
def threshold(self, val: float):
|
def threshold(self, val: float):
|
||||||
self.setter("Threshold", val)
|
self.setter('Threshold', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def damping(self) -> float:
|
def damping(self) -> float:
|
||||||
return round(self.getter("Damping"), 1)
|
return round(self.getter('Damping'), 1)
|
||||||
|
|
||||||
@damping.setter
|
@damping.setter
|
||||||
def damping(self, val: float):
|
def damping(self, val: float):
|
||||||
self.setter("Damping", val)
|
self.setter('Damping', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bpsidechain(self) -> int:
|
def bpsidechain(self) -> int:
|
||||||
return int(self.getter("BPSidechain"))
|
return int(self.getter('BPSidechain'))
|
||||||
|
|
||||||
@bpsidechain.setter
|
@bpsidechain.setter
|
||||||
def bpsidechain(self, val: int):
|
def bpsidechain(self, val: int):
|
||||||
self.setter("BPSidechain", val)
|
self.setter('BPSidechain', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attack(self) -> float:
|
def attack(self) -> float:
|
||||||
return round(self.getter("Attack"), 1)
|
return round(self.getter('Attack'), 1)
|
||||||
|
|
||||||
@attack.setter
|
@attack.setter
|
||||||
def attack(self, val: float):
|
def attack(self, val: float):
|
||||||
self.setter("Attack", val)
|
self.setter('Attack', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hold(self) -> float:
|
def hold(self) -> float:
|
||||||
return round(self.getter("Hold"), 1)
|
return round(self.getter('Hold'), 1)
|
||||||
|
|
||||||
@hold.setter
|
@hold.setter
|
||||||
def hold(self, val: float):
|
def hold(self, val: float):
|
||||||
self.setter("Hold", val)
|
self.setter('Hold', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def release(self) -> float:
|
def release(self) -> float:
|
||||||
return round(self.getter("Release"), 1)
|
return round(self.getter('Release'), 1)
|
||||||
|
|
||||||
@release.setter
|
@release.setter
|
||||||
def release(self, val: float):
|
def release(self, val: float):
|
||||||
self.setter("Release", val)
|
self.setter('Release', val)
|
||||||
|
|
||||||
|
|
||||||
class StripDenoiser(IRemote):
|
class StripDenoiser(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}].denoiser"
|
return f'Strip[{self.index}].denoiser'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def knob(self) -> float:
|
def knob(self) -> float:
|
||||||
return round(self.getter(""), 1)
|
return round(self.getter(''), 1)
|
||||||
|
|
||||||
@knob.setter
|
@knob.setter
|
||||||
def knob(self, val: float):
|
def knob(self, val: float):
|
||||||
self.setter("", val)
|
self.setter('', val)
|
||||||
|
|
||||||
|
|
||||||
class StripEQ(IRemote):
|
class StripEQ(IRemote):
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}].eq"
|
return f'Strip[{self.index}].eq'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def on(self) -> bool:
|
def on(self) -> bool:
|
||||||
return self.getter("on") == 1
|
return self.getter('on') == 1
|
||||||
|
|
||||||
@on.setter
|
@on.setter
|
||||||
def on(self, val: bool):
|
def on(self, val: bool):
|
||||||
self.setter("on", 1 if val else 0)
|
self.setter('on', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ab(self) -> bool:
|
def ab(self) -> bool:
|
||||||
return self.getter("ab") == 1
|
return self.getter('ab') == 1
|
||||||
|
|
||||||
@ab.setter
|
@ab.setter
|
||||||
def ab(self, val: bool):
|
def ab(self, val: bool):
|
||||||
self.setter("ab", 1 if val else 0)
|
self.setter('ab', 1 if val else 0)
|
||||||
|
|
||||||
|
|
||||||
class StripDevice(IRemote):
|
class StripDevice(IRemote):
|
||||||
@ -298,16 +298,16 @@ class StripDevice(IRemote):
|
|||||||
Returns a StripDevice class of a kind.
|
Returns a StripDevice class of a kind.
|
||||||
"""
|
"""
|
||||||
DEVICE_cls = type(
|
DEVICE_cls = type(
|
||||||
f"StripDevice{remote.kind}",
|
f'StripDevice{remote.kind}',
|
||||||
(cls,),
|
(cls,),
|
||||||
{
|
{
|
||||||
**{
|
**{
|
||||||
param: device_prop(param)
|
param: device_prop(param)
|
||||||
for param in [
|
for param in [
|
||||||
"wdm",
|
'wdm',
|
||||||
"ks",
|
'ks',
|
||||||
"mme",
|
'mme',
|
||||||
"asio",
|
'asio',
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -316,15 +316,15 @@ class StripDevice(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}].device"
|
return f'Strip[{self.index}].device'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return self.getter("name", is_string=True)
|
return self.getter('name', is_string=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sr(self) -> int:
|
def sr(self) -> int:
|
||||||
return int(self.getter("sr"))
|
return int(self.getter('sr'))
|
||||||
|
|
||||||
|
|
||||||
class VirtualStrip(Strip):
|
class VirtualStrip(Strip):
|
||||||
@ -337,65 +337,65 @@ class VirtualStrip(Strip):
|
|||||||
"""
|
"""
|
||||||
EFFECTS_cls = _make_effects_mixins(is_phys)[remote.kind.name]
|
EFFECTS_cls = _make_effects_mixins(is_phys)[remote.kind.name]
|
||||||
return type(
|
return type(
|
||||||
"VirtualStrip",
|
'VirtualStrip',
|
||||||
(cls, EFFECTS_cls),
|
(cls, EFFECTS_cls),
|
||||||
{},
|
{},
|
||||||
)
|
)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self.index}"
|
return f'{type(self).__name__}{self.index}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mc(self) -> bool:
|
def mc(self) -> bool:
|
||||||
return self.getter("mc") == 1
|
return self.getter('mc') == 1
|
||||||
|
|
||||||
@mc.setter
|
@mc.setter
|
||||||
def mc(self, val: bool):
|
def mc(self, val: bool):
|
||||||
self.setter("mc", 1 if val else 0)
|
self.setter('mc', 1 if val else 0)
|
||||||
|
|
||||||
mono = mc
|
mono = mc
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def k(self) -> int:
|
def k(self) -> int:
|
||||||
return int(self.getter("karaoke"))
|
return int(self.getter('karaoke'))
|
||||||
|
|
||||||
@k.setter
|
@k.setter
|
||||||
def k(self, val: int):
|
def k(self, val: int):
|
||||||
self.setter("karaoke", val)
|
self.setter('karaoke', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bass(self) -> float:
|
def bass(self) -> float:
|
||||||
return round(self.getter("EQGain1"), 1)
|
return round(self.getter('EQGain1'), 1)
|
||||||
|
|
||||||
@bass.setter
|
@bass.setter
|
||||||
def bass(self, val: float):
|
def bass(self, val: float):
|
||||||
self.setter("EQGain1", val)
|
self.setter('EQGain1', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def mid(self) -> float:
|
def mid(self) -> float:
|
||||||
return round(self.getter("EQGain2"), 1)
|
return round(self.getter('EQGain2'), 1)
|
||||||
|
|
||||||
@mid.setter
|
@mid.setter
|
||||||
def mid(self, val: float):
|
def mid(self, val: float):
|
||||||
self.setter("EQGain2", val)
|
self.setter('EQGain2', val)
|
||||||
|
|
||||||
med = mid
|
med = mid
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def treble(self) -> float:
|
def treble(self) -> float:
|
||||||
return round(self.getter("EQGain3"), 1)
|
return round(self.getter('EQGain3'), 1)
|
||||||
|
|
||||||
high = treble
|
high = treble
|
||||||
|
|
||||||
@treble.setter
|
@treble.setter
|
||||||
def treble(self, val: float):
|
def treble(self, val: float):
|
||||||
self.setter("EQGain3", val)
|
self.setter('EQGain3', val)
|
||||||
|
|
||||||
def appgain(self, name: str, gain: float):
|
def appgain(self, name: str, gain: float):
|
||||||
self.setter("AppGain", f'("{name}", {gain})')
|
self.setter('AppGain', f'("{name}", {gain})')
|
||||||
|
|
||||||
def appmute(self, name: str, mute: bool = None):
|
def appmute(self, name: str, mute: bool = None):
|
||||||
self.setter("AppMute", f'("{name}", {1 if mute else 0})')
|
self.setter('AppMute', f'("{name}", {1 if mute else 0})')
|
||||||
|
|
||||||
|
|
||||||
class StripLevel(IRemote):
|
class StripLevel(IRemote):
|
||||||
@ -416,7 +416,7 @@ class StripLevel(IRemote):
|
|||||||
return round(20 * log(x, 10), 1) if x > 0 else -200.0
|
return round(20 * log(x, 10), 1) if x > 0 else -200.0
|
||||||
|
|
||||||
if not self._remote.stopped() and self._remote.event.ldirty:
|
if not self._remote.stopped() and self._remote.event.ldirty:
|
||||||
vals = self._remote.cache["strip_level"][self.range[0] : self.range[-1]]
|
vals = self._remote.cache['strip_level'][self.range[0] : self.range[-1]]
|
||||||
else:
|
else:
|
||||||
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
|
vals = [self._remote.get_level(mode, i) for i in range(*self.range)]
|
||||||
|
|
||||||
@ -424,7 +424,7 @@ class StripLevel(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}]"
|
return f'Strip[{self.index}]'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def prefader(self) -> tuple:
|
def prefader(self) -> tuple:
|
||||||
@ -477,24 +477,24 @@ class GainLayer(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"Strip[{self.index}]"
|
return f'Strip[{self.index}]'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gain(self):
|
def gain(self):
|
||||||
return self.getter(f"GainLayer[{self._i}]")
|
return self.getter(f'GainLayer[{self._i}]')
|
||||||
|
|
||||||
@gain.setter
|
@gain.setter
|
||||||
def gain(self, val):
|
def gain(self, val):
|
||||||
self.setter(f"GainLayer[{self._i}]", val)
|
self.setter(f'GainLayer[{self._i}]', val)
|
||||||
|
|
||||||
|
|
||||||
def _make_gainlayer_mixin(remote, index):
|
def _make_gainlayer_mixin(remote, index):
|
||||||
"""Creates a GainLayer mixin"""
|
"""Creates a GainLayer mixin"""
|
||||||
return type(
|
return type(
|
||||||
"GainlayerMixin",
|
'GainlayerMixin',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
"gainlayer": tuple(
|
'gainlayer': tuple(
|
||||||
GainLayer(remote, index, i) for i in range(remote.kind.num_bus)
|
GainLayer(remote, index, i) for i in range(remote.kind.num_bus)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -504,11 +504,11 @@ def _make_gainlayer_mixin(remote, index):
|
|||||||
def _make_channelout_mixin(kind):
|
def _make_channelout_mixin(kind):
|
||||||
"""Creates a channel out property mixin"""
|
"""Creates a channel out property mixin"""
|
||||||
return type(
|
return type(
|
||||||
f"ChannelOutMixin{kind}",
|
f'ChannelOutMixin{kind}',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
**{f"A{i}": bool_prop(f"A{i}") for i in range(1, kind.phys_out + 1)},
|
**{f'A{i}': bool_prop(f'A{i}') for i in range(1, kind.phys_out + 1)},
|
||||||
**{f"B{i}": bool_prop(f"B{i}") for i in range(1, kind.virt_out + 1)},
|
**{f'B{i}': bool_prop(f'B{i}') for i in range(1, kind.virt_out + 1)},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -522,12 +522,12 @@ def _make_effects_mixin(kind, is_phys):
|
|||||||
"""creates an effects mixin for a kind"""
|
"""creates an effects mixin for a kind"""
|
||||||
|
|
||||||
def _make_xy_cls():
|
def _make_xy_cls():
|
||||||
pan = {param: float_prop(param) for param in ["pan_x", "pan_y"]}
|
pan = {param: float_prop(param) for param in ['pan_x', 'pan_y']}
|
||||||
color = {param: float_prop(param) for param in ["color_x", "color_y"]}
|
color = {param: float_prop(param) for param in ['color_x', 'color_y']}
|
||||||
fx = {param: float_prop(param) for param in ["fx_x", "fx_y"]}
|
fx = {param: float_prop(param) for param in ['fx_x', 'fx_y']}
|
||||||
if is_phys:
|
if is_phys:
|
||||||
return type(
|
return type(
|
||||||
"XYPhys",
|
'XYPhys',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
**pan,
|
**pan,
|
||||||
@ -536,7 +536,7 @@ def _make_effects_mixin(kind, is_phys):
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
return type(
|
return type(
|
||||||
"XYVirt",
|
'XYVirt',
|
||||||
(),
|
(),
|
||||||
{**pan},
|
{**pan},
|
||||||
)
|
)
|
||||||
@ -544,28 +544,28 @@ def _make_effects_mixin(kind, is_phys):
|
|||||||
def _make_fx_cls():
|
def _make_fx_cls():
|
||||||
if is_phys:
|
if is_phys:
|
||||||
return type(
|
return type(
|
||||||
"FX",
|
'FX',
|
||||||
(),
|
(),
|
||||||
{
|
{
|
||||||
**{
|
**{
|
||||||
param: float_prop(param)
|
param: float_prop(param)
|
||||||
for param in ["reverb", "delay", "fx1", "fx2"]
|
for param in ['reverb', 'delay', 'fx1', 'fx2']
|
||||||
},
|
},
|
||||||
**{
|
**{
|
||||||
f"post{param}": bool_prop(f"post{param}")
|
f'post{param}': bool_prop(f'post{param}')
|
||||||
for param in ["reverb", "delay", "fx1", "fx2"]
|
for param in ['reverb', 'delay', 'fx1', 'fx2']
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return type("FX", (), {})
|
return type('FX', (), {})
|
||||||
|
|
||||||
if kind.name == "basic":
|
if kind.name == 'basic':
|
||||||
steps = (_make_xy_cls,)
|
steps = (_make_xy_cls,)
|
||||||
elif kind.name == "banana":
|
elif kind.name == 'banana':
|
||||||
steps = (_make_xy_cls,)
|
steps = (_make_xy_cls,)
|
||||||
elif kind.name == "potato":
|
elif kind.name == 'potato':
|
||||||
steps = (_make_xy_cls, _make_fx_cls)
|
steps = (_make_xy_cls, _make_fx_cls)
|
||||||
return type(f"Effects{kind}", tuple(step() for step in steps), {})
|
return type(f'Effects{kind}', tuple(step() for step in steps), {})
|
||||||
|
|
||||||
|
|
||||||
def _make_effects_mixins(is_phys):
|
def _make_effects_mixins(is_phys):
|
||||||
@ -588,14 +588,14 @@ def strip_factory(is_phys_strip, remote, i) -> Union[PhysicalStrip, VirtualStrip
|
|||||||
CHANNELOUTMIXIN_cls = _make_channelout_mixins[remote.kind.name]
|
CHANNELOUTMIXIN_cls = _make_channelout_mixins[remote.kind.name]
|
||||||
|
|
||||||
_kls = (STRIP_cls, CHANNELOUTMIXIN_cls)
|
_kls = (STRIP_cls, CHANNELOUTMIXIN_cls)
|
||||||
if remote.kind.name == "potato":
|
if remote.kind.name == 'potato':
|
||||||
GAINLAYERMIXIN_cls = _make_gainlayer_mixin(remote, i)
|
GAINLAYERMIXIN_cls = _make_gainlayer_mixin(remote, i)
|
||||||
_kls += (GAINLAYERMIXIN_cls,)
|
_kls += (GAINLAYERMIXIN_cls,)
|
||||||
return type(
|
return type(
|
||||||
f"{STRIP_cls.__name__}{remote.kind}",
|
f'{STRIP_cls.__name__}{remote.kind}',
|
||||||
_kls,
|
_kls,
|
||||||
{
|
{
|
||||||
"levels": StripLevel(remote, i),
|
'levels': StripLevel(remote, i),
|
||||||
},
|
},
|
||||||
)(remote, i)
|
)(remote, i)
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ class Subject:
|
|||||||
"""run callbacks on update"""
|
"""run callbacks on update"""
|
||||||
|
|
||||||
for o in self._observers:
|
for o in self._observers:
|
||||||
if hasattr(o, "on_update"):
|
if hasattr(o, 'on_update'):
|
||||||
o.on_update(event)
|
o.on_update(event)
|
||||||
else:
|
else:
|
||||||
if o.__name__ == f"on_{event}":
|
if o.__name__ == f'on_{event}':
|
||||||
o()
|
o()
|
||||||
|
|
||||||
def add(self, observer):
|
def add(self, observer):
|
||||||
@ -34,15 +34,15 @@ class Subject:
|
|||||||
for o in iterator:
|
for o in iterator:
|
||||||
if o not in self._observers:
|
if o not in self._observers:
|
||||||
self._observers.append(o)
|
self._observers.append(o)
|
||||||
self.logger.info(f"{o} added to event observers")
|
self.logger.info(f'{o} added to event observers')
|
||||||
else:
|
else:
|
||||||
self.logger.error(f"Failed to add {o} to event observers")
|
self.logger.error(f'Failed to add {o} to event observers')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
if observer not in self._observers:
|
if observer not in self._observers:
|
||||||
self._observers.append(observer)
|
self._observers.append(observer)
|
||||||
self.logger.info(f"{observer} added to event observers")
|
self.logger.info(f'{observer} added to event observers')
|
||||||
else:
|
else:
|
||||||
self.logger.error(f"Failed to add {observer} to event observers")
|
self.logger.error(f'Failed to add {observer} to event observers')
|
||||||
|
|
||||||
register = add
|
register = add
|
||||||
|
|
||||||
@ -54,15 +54,15 @@ class Subject:
|
|||||||
for o in iterator:
|
for o in iterator:
|
||||||
try:
|
try:
|
||||||
self._observers.remove(o)
|
self._observers.remove(o)
|
||||||
self.logger.info(f"{o} removed from event observers")
|
self.logger.info(f'{o} removed from event observers')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.logger.error(f"Failed to remove {o} from event observers")
|
self.logger.error(f'Failed to remove {o} from event observers')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
try:
|
try:
|
||||||
self._observers.remove(observer)
|
self._observers.remove(observer)
|
||||||
self.logger.info(f"{observer} removed from event observers")
|
self.logger.info(f'{observer} removed from event observers')
|
||||||
except ValueError:
|
except ValueError:
|
||||||
self.logger.error(f"Failed to remove {observer} from event observers")
|
self.logger.error(f'Failed to remove {observer} from event observers')
|
||||||
|
|
||||||
deregister = remove
|
deregister = remove
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ class Producer(threading.Thread):
|
|||||||
"""Continously send job queue to the Updater thread at a rate of self._remote.ratelimit."""
|
"""Continously send job queue to the Updater thread at a rate of self._remote.ratelimit."""
|
||||||
|
|
||||||
def __init__(self, remote, queue, stop_event):
|
def __init__(self, remote, queue, stop_event):
|
||||||
super().__init__(name="producer", daemon=False)
|
super().__init__(name='producer', daemon=False)
|
||||||
self._remote = remote
|
self._remote = remote
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self.stop_event = stop_event
|
self.stop_event = stop_event
|
||||||
@ -23,35 +23,35 @@ class Producer(threading.Thread):
|
|||||||
def run(self):
|
def run(self):
|
||||||
while not self.stopped():
|
while not self.stopped():
|
||||||
if self._remote.event.pdirty:
|
if self._remote.event.pdirty:
|
||||||
self.queue.put("pdirty")
|
self.queue.put('pdirty')
|
||||||
if self._remote.event.mdirty:
|
if self._remote.event.mdirty:
|
||||||
self.queue.put("mdirty")
|
self.queue.put('mdirty')
|
||||||
if self._remote.event.midi:
|
if self._remote.event.midi:
|
||||||
self.queue.put("midi")
|
self.queue.put('midi')
|
||||||
if self._remote.event.ldirty:
|
if self._remote.event.ldirty:
|
||||||
self.queue.put("ldirty")
|
self.queue.put('ldirty')
|
||||||
time.sleep(self._remote.ratelimit)
|
time.sleep(self._remote.ratelimit)
|
||||||
self.logger.debug(f"terminating {self.name} thread")
|
self.logger.debug(f'terminating {self.name} thread')
|
||||||
self.queue.put(None)
|
self.queue.put(None)
|
||||||
|
|
||||||
|
|
||||||
class Updater(threading.Thread):
|
class Updater(threading.Thread):
|
||||||
def __init__(self, remote, queue):
|
def __init__(self, remote, queue):
|
||||||
super().__init__(name="updater", daemon=True)
|
super().__init__(name='updater', daemon=True)
|
||||||
self._remote = remote
|
self._remote = remote
|
||||||
self.queue = queue
|
self.queue = queue
|
||||||
self._remote._strip_comp = [False] * (self._remote.kind.num_strip_levels)
|
self._remote._strip_comp = [False] * (self._remote.kind.num_strip_levels)
|
||||||
self._remote._bus_comp = [False] * (self._remote.kind.num_bus_levels)
|
self._remote._bus_comp = [False] * (self._remote.kind.num_bus_levels)
|
||||||
(
|
(
|
||||||
self._remote.cache["strip_level"],
|
self._remote.cache['strip_level'],
|
||||||
self._remote.cache["bus_level"],
|
self._remote.cache['bus_level'],
|
||||||
) = self._remote._get_levels()
|
) = self._remote._get_levels()
|
||||||
self.logger = logger.getChild(self.__class__.__name__)
|
self.logger = logger.getChild(self.__class__.__name__)
|
||||||
|
|
||||||
def _update_comps(self, strip_level, bus_level):
|
def _update_comps(self, strip_level, bus_level):
|
||||||
self._remote._strip_comp, self._remote._bus_comp = (
|
self._remote._strip_comp, self._remote._bus_comp = (
|
||||||
tuple(not x for x in comp(self._remote.cache["strip_level"], strip_level)),
|
tuple(not x for x in comp(self._remote.cache['strip_level'], strip_level)),
|
||||||
tuple(not x for x in comp(self._remote.cache["bus_level"], bus_level)),
|
tuple(not x for x in comp(self._remote.cache['bus_level'], bus_level)),
|
||||||
)
|
)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@ -61,15 +61,15 @@ class Updater(threading.Thread):
|
|||||||
Generate _strip_comp, _bus_comp and update level cache if ldirty.
|
Generate _strip_comp, _bus_comp and update level cache if ldirty.
|
||||||
"""
|
"""
|
||||||
while event := self.queue.get():
|
while event := self.queue.get():
|
||||||
if event == "pdirty" and self._remote.pdirty:
|
if event == 'pdirty' and self._remote.pdirty:
|
||||||
self._remote.subject.notify(event)
|
self._remote.subject.notify(event)
|
||||||
elif event == "mdirty" and self._remote.mdirty:
|
elif event == 'mdirty' and self._remote.mdirty:
|
||||||
self._remote.subject.notify(event)
|
self._remote.subject.notify(event)
|
||||||
elif event == "midi" and self._remote.get_midi_message():
|
elif event == 'midi' and self._remote.get_midi_message():
|
||||||
self._remote.subject.notify(event)
|
self._remote.subject.notify(event)
|
||||||
elif event == "ldirty" and self._remote.ldirty:
|
elif event == 'ldirty' and self._remote.ldirty:
|
||||||
self._update_comps(self._remote._strip_buf, self._remote._bus_buf)
|
self._update_comps(self._remote._strip_buf, self._remote._bus_buf)
|
||||||
self._remote.cache["strip_level"] = self._remote._strip_buf
|
self._remote.cache['strip_level'] = self._remote._strip_buf
|
||||||
self._remote.cache["bus_level"] = self._remote._bus_buf
|
self._remote.cache['bus_level'] = self._remote._bus_buf
|
||||||
self._remote.subject.notify(event)
|
self._remote.subject.notify(event)
|
||||||
self.logger.debug(f"terminating {self.name} thread")
|
self.logger.debug(f'terminating {self.name} thread')
|
||||||
|
@ -22,16 +22,16 @@ def timeout(func):
|
|||||||
try:
|
try:
|
||||||
time.sleep(0.1) # ensure at least 0.1 delay before clearing dirty
|
time.sleep(0.1) # ensure at least 0.1 delay before clearing dirty
|
||||||
remote.logger.info(
|
remote.logger.info(
|
||||||
f"{type(remote).__name__}: Successfully logged into {remote} version {remote.version}"
|
f'{type(remote).__name__}: Successfully logged into {remote} version {remote.version}'
|
||||||
)
|
)
|
||||||
remote.logger.debug(f"login time: {round(time.time() - start, 2)}")
|
remote.logger.debug(f'login time: {round(time.time() - start, 2)}')
|
||||||
err = None
|
err = None
|
||||||
break
|
break
|
||||||
except CAPIError as e:
|
except CAPIError as e:
|
||||||
err = e
|
err = e
|
||||||
continue
|
continue
|
||||||
if err:
|
if err:
|
||||||
raise VMError("Timeout logging into the api")
|
raise VMError('Timeout logging into the api')
|
||||||
remote.clear_dirty()
|
remote.clear_dirty()
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
@ -48,15 +48,15 @@ def polling(func):
|
|||||||
|
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
def wrapper(*args, **kwargs):
|
def wrapper(*args, **kwargs):
|
||||||
get = func.__name__ == "get"
|
get = func.__name__ == 'get'
|
||||||
mb_get = func.__name__ == "get_buttonstatus"
|
mb_get = func.__name__ == 'get_buttonstatus'
|
||||||
remote, *remaining = args
|
remote, *remaining = args
|
||||||
|
|
||||||
if get:
|
if get:
|
||||||
param, *rem = remaining
|
param, *rem = remaining
|
||||||
elif mb_get:
|
elif mb_get:
|
||||||
id, mode, *rem = remaining
|
id, mode, *rem = remaining
|
||||||
param = f"mb_{id}_{mode}"
|
param = f'mb_{id}_{mode}'
|
||||||
|
|
||||||
if param in remote.cache:
|
if param in remote.cache:
|
||||||
return remote.cache.pop(param)
|
return remote.cache.pop(param)
|
||||||
@ -73,15 +73,15 @@ def script(func):
|
|||||||
def wrapper(*args):
|
def wrapper(*args):
|
||||||
remote, script = args
|
remote, script = args
|
||||||
if isinstance(script, dict):
|
if isinstance(script, dict):
|
||||||
params = ""
|
params = ''
|
||||||
for key, val in script.items():
|
for key, val in script.items():
|
||||||
obj, m2, *rem = key.split("-")
|
obj, m2, *rem = key.split('-')
|
||||||
index = int(m2) if m2.isnumeric() else int(*rem)
|
index = int(m2) if m2.isnumeric() else int(*rem)
|
||||||
params += ";".join(
|
params += ';'.join(
|
||||||
f"{obj}{f'.{m2}stream' if not m2.isnumeric() else ''}[{index}].{k}={int(v) if isinstance(v, bool) else v}"
|
f"{obj}{f'.{m2}stream' if not m2.isnumeric() else ''}[{index}].{k}={int(v) if isinstance(v, bool) else v}"
|
||||||
for k, v in val.items()
|
for k, v in val.items()
|
||||||
)
|
)
|
||||||
params += ";"
|
params += ';'
|
||||||
script = params
|
script = params
|
||||||
return func(remote, script)
|
return func(remote, script)
|
||||||
|
|
||||||
|
@ -17,94 +17,94 @@ class VbanStream(IRemote):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def identifier(self) -> str:
|
def identifier(self) -> str:
|
||||||
return f"vban.{self.direction}stream[{self.index}]"
|
return f'vban.{self.direction}stream[{self.index}]'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def on(self) -> bool:
|
def on(self) -> bool:
|
||||||
return self.getter("on") == 1
|
return self.getter('on') == 1
|
||||||
|
|
||||||
@on.setter
|
@on.setter
|
||||||
def on(self, val: bool):
|
def on(self, val: bool):
|
||||||
self.setter("on", 1 if val else 0)
|
self.setter('on', 1 if val else 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
return self.getter("name", is_string=True)
|
return self.getter('name', is_string=True)
|
||||||
|
|
||||||
@name.setter
|
@name.setter
|
||||||
def name(self, val: str):
|
def name(self, val: str):
|
||||||
self.setter("name", val)
|
self.setter('name', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ip(self) -> str:
|
def ip(self) -> str:
|
||||||
return self.getter("ip", is_string=True)
|
return self.getter('ip', is_string=True)
|
||||||
|
|
||||||
@ip.setter
|
@ip.setter
|
||||||
def ip(self, val: str):
|
def ip(self, val: str):
|
||||||
self.setter("ip", val)
|
self.setter('ip', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def port(self) -> int:
|
def port(self) -> int:
|
||||||
return int(self.getter("port"))
|
return int(self.getter('port'))
|
||||||
|
|
||||||
@port.setter
|
@port.setter
|
||||||
def port(self, val: int):
|
def port(self, val: int):
|
||||||
if not 1024 <= val <= 65535:
|
if not 1024 <= val <= 65535:
|
||||||
self.logger.warning(
|
self.logger.warning(
|
||||||
f"port got: {val} but expected a value from 1024 to 65535"
|
f'port got: {val} but expected a value from 1024 to 65535'
|
||||||
)
|
)
|
||||||
self.setter("port", val)
|
self.setter('port', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sr(self) -> int:
|
def sr(self) -> int:
|
||||||
return int(self.getter("sr"))
|
return int(self.getter('sr'))
|
||||||
|
|
||||||
@sr.setter
|
@sr.setter
|
||||||
def sr(self, val: int):
|
def sr(self, val: int):
|
||||||
opts = (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
opts = (11025, 16000, 22050, 24000, 32000, 44100, 48000, 64000, 88200, 96000)
|
||||||
if val not in opts:
|
if val not in opts:
|
||||||
self.logger.warning(f"sr got: {val} but expected a value in {opts}")
|
self.logger.warning(f'sr got: {val} but expected a value in {opts}')
|
||||||
self.setter("sr", val)
|
self.setter('sr', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def channel(self) -> int:
|
def channel(self) -> int:
|
||||||
return int(self.getter("channel"))
|
return int(self.getter('channel'))
|
||||||
|
|
||||||
@channel.setter
|
@channel.setter
|
||||||
def channel(self, val: int):
|
def channel(self, val: int):
|
||||||
if not 1 <= val <= 8:
|
if not 1 <= val <= 8:
|
||||||
self.logger.warning(f"channel got: {val} but expected a value from 1 to 8")
|
self.logger.warning(f'channel got: {val} but expected a value from 1 to 8')
|
||||||
self.setter("channel", val)
|
self.setter('channel', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def bit(self) -> int:
|
def bit(self) -> int:
|
||||||
return 16 if (int(self.getter("bit") == 1)) else 24
|
return 16 if (int(self.getter('bit') == 1)) else 24
|
||||||
|
|
||||||
@bit.setter
|
@bit.setter
|
||||||
def bit(self, val: int):
|
def bit(self, val: int):
|
||||||
if val not in (16, 24):
|
if val not in (16, 24):
|
||||||
self.logger.warning(f"bit got: {val} but expected value 16 or 24")
|
self.logger.warning(f'bit got: {val} but expected value 16 or 24')
|
||||||
self.setter("bit", 1 if (val == 16) else 2)
|
self.setter('bit', 1 if (val == 16) else 2)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def quality(self) -> int:
|
def quality(self) -> int:
|
||||||
return int(self.getter("quality"))
|
return int(self.getter('quality'))
|
||||||
|
|
||||||
@quality.setter
|
@quality.setter
|
||||||
def quality(self, val: int):
|
def quality(self, val: int):
|
||||||
if not 0 <= val <= 4:
|
if not 0 <= val <= 4:
|
||||||
self.logger.warning(f"quality got: {val} but expected a value from 0 to 4")
|
self.logger.warning(f'quality got: {val} but expected a value from 0 to 4')
|
||||||
self.setter("quality", val)
|
self.setter('quality', val)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def route(self) -> int:
|
def route(self) -> int:
|
||||||
return int(self.getter("route"))
|
return int(self.getter('route'))
|
||||||
|
|
||||||
@route.setter
|
@route.setter
|
||||||
def route(self, val: int):
|
def route(self, val: int):
|
||||||
if not 0 <= val <= 8:
|
if not 0 <= val <= 8:
|
||||||
self.logger.warning(f"route got: {val} but expected a value from 0 to 8")
|
self.logger.warning(f'route got: {val} but expected a value from 0 to 8')
|
||||||
self.setter("route", val)
|
self.setter('route', val)
|
||||||
|
|
||||||
|
|
||||||
class VbanInstream(VbanStream):
|
class VbanInstream(VbanStream):
|
||||||
@ -115,11 +115,11 @@ class VbanInstream(VbanStream):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self._remote.kind}{self.index}"
|
return f'{type(self).__name__}{self._remote.kind}{self.index}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def direction(self) -> str:
|
def direction(self) -> str:
|
||||||
return "in"
|
return 'in'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def sr(self) -> int:
|
def sr(self) -> int:
|
||||||
@ -154,11 +154,11 @@ class VbanOutstream(VbanStream):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{type(self).__name__}{self._remote.kind}{self.index}"
|
return f'{type(self).__name__}{self._remote.kind}{self.index}'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def direction(self) -> str:
|
def direction(self) -> str:
|
||||||
return "out"
|
return 'out'
|
||||||
|
|
||||||
|
|
||||||
class VbanAudioOutstream(VbanOutstream):
|
class VbanAudioOutstream(VbanOutstream):
|
||||||
@ -174,22 +174,22 @@ def _make_stream_pair(remote, kind):
|
|||||||
|
|
||||||
def _make_cls(i, direction):
|
def _make_cls(i, direction):
|
||||||
match direction:
|
match direction:
|
||||||
case "in":
|
case 'in':
|
||||||
if i < num_instream:
|
if i < num_instream:
|
||||||
return VbanAudioInstream(remote, i)
|
return VbanAudioInstream(remote, i)
|
||||||
elif i < num_instream + num_midi:
|
elif i < num_instream + num_midi:
|
||||||
return VbanMidiInstream(remote, i)
|
return VbanMidiInstream(remote, i)
|
||||||
else:
|
else:
|
||||||
return VbanTextInstream(remote, i)
|
return VbanTextInstream(remote, i)
|
||||||
case "out":
|
case 'out':
|
||||||
if i < num_outstream:
|
if i < num_outstream:
|
||||||
return VbanAudioOutstream(remote, i)
|
return VbanAudioOutstream(remote, i)
|
||||||
else:
|
else:
|
||||||
return VbanMidiOutstream(remote, i)
|
return VbanMidiOutstream(remote, i)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
tuple(_make_cls(i, "in") for i in range(num_instream + num_midi + num_text)),
|
tuple(_make_cls(i, 'in') for i in range(num_instream + num_midi + num_text)),
|
||||||
tuple(_make_cls(i, "out") for i in range(num_outstream + num_midi)),
|
tuple(_make_cls(i, 'out') for i in range(num_outstream + num_midi)),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -209,10 +209,10 @@ class Vban:
|
|||||||
self.instream, self.outstream = _make_stream_pairs(remote)[remote.kind.name]
|
self.instream, self.outstream = _make_stream_pairs(remote)[remote.kind.name]
|
||||||
|
|
||||||
def enable(self):
|
def enable(self):
|
||||||
self.remote.set("vban.Enable", 1)
|
self.remote.set('vban.Enable', 1)
|
||||||
|
|
||||||
def disable(self):
|
def disable(self):
|
||||||
self.remote.set("vban.Enable", 0)
|
self.remote.set('vban.Enable', 0)
|
||||||
|
|
||||||
|
|
||||||
def vban_factory(remote) -> Vban:
|
def vban_factory(remote) -> Vban:
|
||||||
@ -222,7 +222,7 @@ def vban_factory(remote) -> Vban:
|
|||||||
Returns a class that represents the VBAN module.
|
Returns a class that represents the VBAN module.
|
||||||
"""
|
"""
|
||||||
VBAN_cls = Vban
|
VBAN_cls = Vban
|
||||||
return type(f"{VBAN_cls.__name__}", (VBAN_cls,), {})(remote)
|
return type(f'{VBAN_cls.__name__}', (VBAN_cls,), {})(remote)
|
||||||
|
|
||||||
|
|
||||||
def request_vban_obj(remote) -> Vban:
|
def request_vban_obj(remote) -> Vban:
|
||||||
|
Loading…
Reference in New Issue
Block a user