mirror of
				https://github.com/onyx-and-iris/voicemeeter-api-python.git
				synced 2025-10-31 22:01:45 +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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user