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