add advanced comproessor slider events

voicemeeter-api version bumped

some of the spoken feedback for sliders corrected.
This commit is contained in:
onyx-and-iris 2023-09-25 18:22:17 +01:00
parent 85527e0749
commit 89d0253591
5 changed files with 342 additions and 58 deletions

View File

@ -271,13 +271,13 @@ files = [
[[package]] [[package]]
name = "voicemeeter-api" name = "voicemeeter-api"
version = "2.4.9" version = "2.4.10"
requires_python = ">=3.10,<4.0" requires_python = ">=3.10,<4.0"
summary = "A Python wrapper for the Voiceemeter API" summary = "A Python wrapper for the Voiceemeter API"
dependencies = [ dependencies = [
"tomli<3.0.0,>=2.0.1; python_version < \"3.11\"", "tomli<3.0.0,>=2.0.1; python_version < \"3.11\"",
] ]
files = [ files = [
{file = "voicemeeter_api-2.4.9-py3-none-any.whl", hash = "sha256:a09fd07fe3799cd5c880d491048da81d94e49aa97ec753aa1f9289acd27be965"}, {file = "voicemeeter_api-2.4.10-py3-none-any.whl", hash = "sha256:2f75acb7b472e56b6bd8d4f1141f32d948c55ef9b30d5a08e085a1c8e76e2464"},
{file = "voicemeeter_api-2.4.9.tar.gz", hash = "sha256:47ad614a8b9ccb0b4e47acf65666ce0f0537a0890fffda9949e995bea70e679c"}, {file = "voicemeeter_api-2.4.10.tar.gz", hash = "sha256:1d8dfc1e8922179f8b97c90b90b9ed051082018c6af5feb1d48250140a02d40c"},
] ]

View File

@ -8,7 +8,7 @@ authors = [
dependencies = [ dependencies = [
"pysimplegui>=4.60.5", "pysimplegui>=4.60.5",
"pyparsing>=3.1.1", "pyparsing>=3.1.1",
"voicemeeter-api>=2.4.9", "voicemeeter-api>=2.4.10",
] ]
requires-python = ">=3.10,<3.12" requires-python = ">=3.10,<3.12"
readme = "README.md" readme = "README.md"

View File

@ -41,7 +41,13 @@ class CompSlider(psg.Slider):
def __init__(self, vm, index, param): def __init__(self, vm, index, param):
self.vm = vm self.vm = vm
self.index = index self.index = index
super().__init__(**self.default_params(param)) super().__init__(
disable_number_display=True,
expand_x=True,
enable_events=True,
orientation="horizontal",
**self.default_params(param),
)
def default_params(self, param): def default_params(self, param):
match param: match param:
@ -50,10 +56,6 @@ class CompSlider(psg.Slider):
"range": (-24, 24), "range": (-24, 24),
"default_value": self.vm.strip[self.index].comp.gainin, "default_value": self.vm.strip[self.index].comp.gainin,
"resolution": 0.1, "resolution": 0.1,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }
case "RATIO": case "RATIO":
@ -61,10 +63,6 @@ class CompSlider(psg.Slider):
"range": (1, 8), "range": (1, 8),
"default_value": self.vm.strip[self.index].comp.ratio, "default_value": self.vm.strip[self.index].comp.ratio,
"resolution": 0.1, "resolution": 0.1,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }
case "THRESHOLD": case "THRESHOLD":
@ -72,10 +70,6 @@ class CompSlider(psg.Slider):
"range": (-40, -3), "range": (-40, -3),
"default_value": self.vm.strip[self.index].comp.threshold, "default_value": self.vm.strip[self.index].comp.threshold,
"resolution": 0.1, "resolution": 0.1,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }
case "ATTACK": case "ATTACK":
@ -83,10 +77,6 @@ class CompSlider(psg.Slider):
"range": (0, 200), "range": (0, 200),
"default_value": self.vm.strip[self.index].comp.attack, "default_value": self.vm.strip[self.index].comp.attack,
"resolution": 0.1, "resolution": 0.1,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }
case "RELEASE": case "RELEASE":
@ -94,10 +84,6 @@ class CompSlider(psg.Slider):
"range": (0, 5000), "range": (0, 5000),
"default_value": self.vm.strip[self.index].comp.release, "default_value": self.vm.strip[self.index].comp.release,
"resolution": 0.1, "resolution": 0.1,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }
case "KNEE": case "KNEE":
@ -105,10 +91,6 @@ class CompSlider(psg.Slider):
"range": (0, 1), "range": (0, 1),
"default_value": self.vm.strip[self.index].comp.knee, "default_value": self.vm.strip[self.index].comp.knee,
"resolution": 0.01, "resolution": 0.01,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }
case "OUTPUT GAIN": case "OUTPUT GAIN":
@ -116,10 +98,6 @@ class CompSlider(psg.Slider):
"range": (-24, 24), "range": (-24, 24),
"default_value": self.vm.strip[self.index].comp.gainout, "default_value": self.vm.strip[self.index].comp.gainout,
"resolution": 0.01, "resolution": 0.01,
"disable_number_display": True,
"expand_x": True,
"enable_events": True,
"orientation": "horizontal",
"key": f"COMPRESSOR||SLIDER {param}", "key": f"COMPRESSOR||SLIDER {param}",
} }

View File

@ -41,7 +41,7 @@ class Popup:
filepath = values["Browse"] filepath = values["Browse"]
break break
self.window.nvda.speak(button) self.window.nvda.speak(button)
case [[button], ["KEY", "ENTER"]]: case [_, ["KEY", "ENTER"]]:
popup.find_element_with_focus().click() popup.find_element_with_focus().click()
self.logger.debug(f"parsed::{parsed_cmd}") self.logger.debug(f"parsed::{parsed_cmd}")
popup.close() popup.close()
@ -84,7 +84,7 @@ class Popup:
match parsed_cmd := self.window.parser.match.parseString(event): match parsed_cmd := self.window.parser.match.parseString(event):
case [[button], ["FOCUS", "IN"]]: case [[button], ["FOCUS", "IN"]]:
self.window.nvda.speak(button) self.window.nvda.speak(button)
case [[button], ["KEY", "ENTER"]]: case [_, ["KEY", "ENTER"]]:
popup.find_element_with_focus().click() popup.find_element_with_focus().click()
case ["Ok"]: case ["Ok"]:
data = values data = values
@ -152,7 +152,7 @@ class Popup:
util.open_context_menu_for_buttonmenu(popup, f"BUFFER {driver}") util.open_context_menu_for_buttonmenu(popup, f"BUFFER {driver}")
case [[button], ["FOCUS", "IN"]]: case [[button], ["FOCUS", "IN"]]:
self.window.nvda.speak(button) self.window.nvda.speak(button)
case [[button], ["KEY", "ENTER"]]: case [_, ["KEY", "ENTER"]]:
popup.find_element_with_focus().click() popup.find_element_with_focus().click()
self.logger.debug(f"parsed::{parsed_cmd}") self.logger.debug(f"parsed::{parsed_cmd}")
popup.close() popup.close()
@ -169,20 +169,319 @@ class Popup:
steps = (_make_comp_frame,) steps = (_make_comp_frame,)
for step in steps: for step in steps:
layout.append([step()]) layout.append([step()])
layout.append([psg.Button("Auto Makeup", size=(12, 1)), psg.Button("Exit", size=(8, 1))]) layout.append([psg.Button("MAKEUP", size=(12, 1)), psg.Button("Exit", size=(8, 1))])
popup = psg.Window(title, layout, finalize=True) popup = psg.Window(title, layout, return_keyboard_events=False, finalize=True)
buttonmenu_opts = {"takefocus": 1, "highlightthickness": 1} buttonmenu_opts = {"takefocus": 1, "highlightthickness": 1}
for param in ("INPUT GAIN", "RATIO", "THRESHOLD", "ATTACK", "RELEASE", "KNEE", "OUTPUT GAIN"): for param in ("INPUT GAIN", "RATIO", "THRESHOLD", "ATTACK", "RELEASE", "KNEE", "OUTPUT GAIN"):
popup[f"COMPRESSOR||SLIDER {param}"].Widget.config(**buttonmenu_opts) popup[f"COMPRESSOR||SLIDER {param}"].Widget.config(**buttonmenu_opts)
popup[f"COMPRESSOR||SLIDER {param}"].bind("<FocusIn>", "||FOCUS IN")
popup[f"COMPRESSOR||SLIDER {param}"].bind("<FocusOut>", "||FOCUS OUT")
for event in ("KeyPress", "KeyRelease"):
event_id = event.removeprefix("Key").upper()
for direction in ("Left", "Right", "Up", "Down"):
popup[f"COMPRESSOR||SLIDER {param}"].bind(
f"<{event}-{direction}>", f"||KEY {direction.upper()} {event_id}"
)
popup[f"COMPRESSOR||SLIDER {param}"].bind(
f"<Shift-{event}-{direction}>", f"||KEY SHIFT {direction.upper()} {event_id}"
)
popup[f"COMPRESSOR||SLIDER {param}"].bind(
f"<Control-{event}-{direction}>", f"||KEY CTRL {direction.upper()} {event_id}"
)
if param == "RELEASE":
popup[f"COMPRESSOR||SLIDER {param}"].bind(
f"<Alt-{event}-{direction}>", f"||KEY ALT {direction.upper()} {event_id}"
)
if param == "RELEASE":
popup[f"COMPRESSOR||SLIDER {param}"].bind(
f"<Control-Alt-{event}-{direction}>", f"||KEY CTRL ALT {direction.upper()} {event_id}"
)
popup["MAKEUP"].bind("<FocusIn>", "||FOCUS IN")
popup["MAKEUP"].bind("<Return>", "||KEY ENTER")
popup["Exit"].bind("<FocusIn>", "||FOCUS IN") popup["Exit"].bind("<FocusIn>", "||FOCUS IN")
popup["Exit"].bind("<Return>", "||KEY ENTER") popup["Exit"].bind("<Return>", "||KEY ENTER")
while True: while True:
event, values = popup.read() event, values = popup.read()
self.logger.debug(f"event::{event}")
self.logger.debug(f"values::{values}")
if event in (psg.WIN_CLOSED, "Exit"): if event in (psg.WIN_CLOSED, "Exit"):
break break
match parsed_cmd := self.window.parser.match.parseString(event): match parsed_cmd := self.window.parser.match.parseString(event):
case [[button], ["KEY", "ENTER"]]: case [["COMPRESSOR"], ["SLIDER", param]]:
setattr(self.window.vm.strip[index].comp, param.lower(), values[event])
case [["COMPRESSOR"], ["SLIDER", param], ["FOCUS", "IN"]]:
self.window.nvda.speak(f"{param} {values[f'COMPRESSOR||SLIDER {param}']}")
case [
["COMPRESSOR"],
["SLIDER", param],
["KEY", "LEFT" | "RIGHT" | "UP" | "DOWN" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
val = getattr(self.window.vm.strip[index].comp, param.lower())
match input_direction:
case "RIGHT" | "UP":
if param == "KNEE":
val += 0.1
else:
val += 1
case "LEFT" | "DOWN":
if param == "KNEE":
val -= 0.1
else:
val -= 1
match param:
case "RATIO":
val = util.check_bounds(val, (1, 8))
case "THRESHOLD":
val = util.check_bounds(val, (-40, -3))
case "ATTACK":
val = util.check_bounds(val, (0, 200))
case "RELEASE":
val = util.check_bounds(val, (0, 5000))
case "KNEE":
val = util.check_bounds(val, (0, 1))
setattr(self.window.vm.strip[index].comp, param.lower(), val)
popup[f"COMPRESSOR||SLIDER {param}"].update(value=val)
if param == "KNEE":
self.window.nvda.speak(str(round(val, 2)))
else:
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [
["COMPRESSOR"],
["SLIDER", param],
["KEY", "CTRL", "LEFT" | "RIGHT" | "UP" | "DOWN" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
val = getattr(self.window.vm.strip[index].comp, param.lower())
match input_direction:
case "RIGHT" | "UP":
if param == "KNEE":
val += 0.3
elif param == "RELEASE":
val += 5
else:
val += 3
case "LEFT" | "DOWN":
if param == "KNEE":
val -= 0.3
elif param == "RELEASE":
val -= 5
else:
val -= 3
match param:
case "RATIO":
val = util.check_bounds(val, (1, 8))
case "THRESHOLD":
val = util.check_bounds(val, (-40, -3))
case "ATTACK":
val = util.check_bounds(val, (0, 200))
case "RELEASE":
val = util.check_bounds(val, (0, 5000))
case "KNEE":
val = util.check_bounds(val, (0, 1))
setattr(self.window.vm.strip[index].comp, param.lower(), val)
popup[f"COMPRESSOR||SLIDER {param}"].update(value=val)
if param == "KNEE":
self.window.nvda.speak(str(round(val, 2)))
else:
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [
["COMPRESSOR"],
["SLIDER", param],
["KEY", "SHIFT", "LEFT" | "RIGHT" | "UP" | "DOWN" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
val = getattr(self.window.vm.strip[index].comp, param.lower())
match input_direction:
case "RIGHT" | "UP":
if param == "KNEE":
val += 0.01
else:
val += 0.1
case "LEFT" | "DOWN":
if param == "KNEE":
val -= 0.01
else:
val -= 0.1
match param:
case "RATIO":
val = util.check_bounds(val, (1, 8))
case "THRESHOLD":
val = util.check_bounds(val, (-40, -3))
case "ATTACK":
val = util.check_bounds(val, (0, 200))
case "RELEASE":
val = util.check_bounds(val, (0, 5000))
case "KNEE":
val = util.check_bounds(val, (0, 1))
setattr(self.window.vm.strip[index].comp, param.lower(), val)
popup[f"COMPRESSOR||SLIDER {param}"].update(value=val)
if param == "KNEE":
self.window.nvda.speak(str(round(val, 2)))
else:
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [
["COMPRESSOR"],
["SLIDER", "RELEASE"],
["KEY", "ALT", "LEFT" | "RIGHT" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
val = self.window.vm.strip[index].comp.release
match input_direction:
case "RIGHT" | "UP":
val += 10
case "LEFT" | "DOWN":
val -= 10
val = util.check_bounds(val, (0, 5000))
self.window.vm.strip[index].comp.release = val
popup[f"COMPRESSOR||SLIDER {param}"].update(value=val)
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [
["COMPRESSOR"],
["SLIDER", "RELEASE"],
["KEY", "CTRL", "ALT", "LEFT" | "RIGHT" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
val = self.window.vm.strip[index].comp.release
match input_direction:
case "RIGHT" | "UP":
val += 50
case "LEFT" | "DOWN":
val -= 50
val = util.check_bounds(val, (0, 5000))
self.window.vm.strip[index].comp.release = val
popup[f"COMPRESSOR||SLIDER {param}"].update(value=val)
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [["COMPRESSOR"], ["SLIDER", "INPUT" | "OUTPUT" as direction, "GAIN"]]:
if direction == "INPUT":
self.window.vm.strip[index].comp.gainin = values[event]
else:
self.window.vm.strip[index].comp.gainout = values[event]
case [["COMPRESSOR"], ["SLIDER", "INPUT" | "OUTPUT" as direction, "GAIN"], ["FOCUS", "IN"]]:
label = f"{direction} GAIN"
self.window.nvda.speak(f"{label} {values[f'COMPRESSOR||SLIDER {label}']}")
case [
["COMPRESSOR"],
["SLIDER", "INPUT" | "OUTPUT" as direction, "GAIN"],
["KEY", "LEFT" | "RIGHT" | "UP" | "DOWN" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
if direction == "INPUT":
val = self.window.vm.strip[index].comp.gainin
else:
val = self.window.vm.strip[index].comp.gainout
match input_direction:
case "RIGHT" | "UP":
val += 1
case "LEFT" | "DOWN":
val -= 1
val = util.check_bounds(val, (-24, 24))
if direction == "INPUT":
self.window.vm.strip[index].comp.gainin = val
else:
self.window.vm.strip[index].comp.gainout = val
popup[f"COMPRESSOR||SLIDER {direction} GAIN"].update(value=val)
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [
["COMPRESSOR"],
["SLIDER", "INPUT" | "OUTPUT" as direction, "GAIN"],
["KEY", "CTRL", "LEFT" | "RIGHT" | "UP" | "DOWN" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
if direction == "INPUT":
val = self.window.vm.strip[index].comp.gainin
else:
val = self.window.vm.strip[index].comp.gainout
match input_direction:
case "RIGHT" | "UP":
val += 3
case "LEFT" | "DOWN":
val -= 3
val = util.check_bounds(val, (-24, 24))
if direction == "INPUT":
self.window.vm.strip[index].comp.gainin = val
else:
self.window.vm.strip[index].comp.gainout = val
popup[f"COMPRESSOR||SLIDER {direction} GAIN"].update(value=val)
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case [
["COMPRESSOR"],
["SLIDER", "INPUT" | "OUTPUT" as direction, "GAIN"],
["KEY", "SHIFT", "LEFT" | "RIGHT" | "UP" | "DOWN" as input_direction, "PRESS" | "RELEASE" as e],
]:
if e == "PRESS":
self.window.vm.event.pdirty = False
if direction == "INPUT":
val = self.window.vm.strip[index].comp.gainin
else:
val = self.window.vm.strip[index].comp.gainout
match input_direction:
case "RIGHT" | "UP":
val += 0.1
case "LEFT" | "DOWN":
val -= 0.1
val = util.check_bounds(val, (-24, 24))
if direction == "INPUT":
self.window.vm.strip[index].comp.gainin = val
else:
self.window.vm.strip[index].comp.gainout = val
popup[f"COMPRESSOR||SLIDER {direction} GAIN"].update(value=val)
self.window.nvda.speak(str(round(val, 1)))
else:
self.window.vm.event.pdirty = True
case ["MAKEUP"]:
val = not self.window.vm.strip[index].comp.makeup
self.window.vm.strip[index].comp.makeup = val
self.window.nvda.speak("on" if val else "off")
case [[button], ["FOCUS", "IN"]]:
if button == "MAKEUP":
self.window.nvda.speak(f"{button} {'on' if self.window.vm.strip[index].comp.makeup else 'off'}")
else:
self.window.nvda.speak(button)
case [_, ["KEY", "ENTER"]]:
popup.find_element_with_focus().click() popup.find_element_with_focus().click()
self.logger.debug(f"parsed::{parsed_cmd}") self.logger.debug(f"parsed::{parsed_cmd}")
popup.close() popup.close()

View File

@ -311,7 +311,7 @@ class NVDAVMWindow(psg.Window):
continue continue
match parsed_cmd := self.parser.match.parseString(event): match parsed_cmd := self.parser.match.parseString(event):
# Slide mode # Slider mode
case [["ALT", "LEFT" | "RIGHT" | "UP" | "DOWN" as direction], ["PRESS" | "RELEASE" as e]]: case [["ALT", "LEFT" | "RIGHT" | "UP" | "DOWN" as direction], ["PRESS" | "RELEASE" as e]]:
if mode: if mode:
self.write_event_value(f"SLIDER MODE {direction}||{e}", mode.split()[0]) self.write_event_value(f"SLIDER MODE {direction}||{e}", mode.split()[0])
@ -446,6 +446,19 @@ class NVDAVMWindow(psg.Window):
self[f"BUS {index}||LABEL"].update(value=label) self[f"BUS {index}||LABEL"].update(value=label)
self.cache["labels"][f"BUS {index}||LABEL"] = label self.cache["labels"][f"BUS {index}||LABEL"] = label
# Advanced popups (settings, comp, gate)
case ["CTRL-A"]:
match values["tabgroup"]:
case "tab||Settings":
self.write_event_value("ADVANCED SETTINGS", None)
case "tab||Physical Strip":
if values["tabgroup||Physical Strip"] == "tab||Physical Strip||sliders":
if focus := self.find_element_with_focus():
identifier, partial = focus.key.split("||")
_, index = identifier.split()
if "SLIDER COMP" in partial:
self.popup.compressor(int(index), title="Advanced Compressor")
# Menus # Menus
case [["Restart", "Audio", "Engine"], ["MENU"]]: case [["Restart", "Audio", "Engine"], ["MENU"]]:
self.perform_long_operation(self.vm.command.restart, "ENGINE RESTART||END") self.perform_long_operation(self.vm.command.restart, "ENGINE RESTART||END")
@ -620,18 +633,6 @@ class NVDAVMWindow(psg.Window):
self.write_event_value(f"INSERT CHECKBOX||{in_num} {channel}", val) self.write_event_value(f"INSERT CHECKBOX||{in_num} {channel}", val)
# Advanced Settings # Advanced Settings
case ["CTRL-A"]:
match values["tabgroup"]:
case "tab||Settings":
self.write_event_value("ADVANCED SETTINGS", None)
case "tab||Physical Strip":
if values["tabgroup||Physical Strip"] == "tab||Physical Strip||sliders":
if focus := self.find_element_with_focus():
identifier, partial = focus.key.split("||")
_, index = identifier.split()
if "SLIDER COMP" in partial:
self.popup.compressor(int(index), title="Advanced Compressor")
case ["ADVANCED SETTINGS"]: case ["ADVANCED SETTINGS"]:
if values["tabgroup"] == "tab||Settings": if values["tabgroup"] == "tab||Settings":
self.popup.advanced_settings(title="Advanced Settings") self.popup.advanced_settings(title="Advanced Settings")
@ -810,7 +811,7 @@ class NVDAVMWindow(psg.Window):
val = util.check_bounds(val, (-40, 12)) val = util.check_bounds(val, (-40, 12))
self.vm.strip[int(index)].limit = val self.vm.strip[int(index)].limit = val
self[f"STRIP {index}||SLIDER {param}"].update(value=val) self[f"STRIP {index}||SLIDER {param}"].update(value=val)
self.nvda.speak(str(val)) self.nvda.speak(str(round(val, 1)))
else: else:
self.vm.event.pdirty = True self.vm.event.pdirty = True
case [ case [
@ -877,7 +878,10 @@ class NVDAVMWindow(psg.Window):
val = util.check_bounds(val, (-40, 12)) val = util.check_bounds(val, (-40, 12))
self.vm.strip[int(index)].limit = val self.vm.strip[int(index)].limit = val
self[f"STRIP {index}||SLIDER {param}"].update(value=val) self[f"STRIP {index}||SLIDER {param}"].update(value=val)
self.nvda.speak(f"{param} {val}") if param == "LIMIT":
self.nvda.speak(str(int(val)))
else:
self.nvda.speak(str(round(val, 1)))
else: else:
self.vm.event.pdirty = True self.vm.event.pdirty = True
case [ case [
@ -944,7 +948,10 @@ class NVDAVMWindow(psg.Window):
val = util.check_bounds(val, (-40, 12)) val = util.check_bounds(val, (-40, 12))
self.vm.strip[int(index)].limit = val self.vm.strip[int(index)].limit = val
self[f"STRIP {index}||SLIDER {param}"].update(value=val) self[f"STRIP {index}||SLIDER {param}"].update(value=val)
self.nvda.speak(f"{param} {val}") if param == "LIMIT":
self.nvda.speak(str(int(val)))
else:
self.nvda.speak(str(round(val, 1)))
else: else:
self.vm.event.pdirty = True self.vm.event.pdirty = True
case [["STRIP", index], ["SLIDER", param], ["KEY", "CTRL", "SHIFT", "R"]]: case [["STRIP", index], ["SLIDER", param], ["KEY", "CTRL", "SHIFT", "R"]]:
@ -1053,7 +1060,7 @@ class NVDAVMWindow(psg.Window):
val = util.check_bounds(val, (-60, 12)) val = util.check_bounds(val, (-60, 12))
self.vm.bus[int(index)].gain = val self.vm.bus[int(index)].gain = val
self[f"BUS {index}||SLIDER GAIN"].update(value=val) self[f"BUS {index}||SLIDER GAIN"].update(value=val)
self.nvda.speak(str(val)) self.nvda.speak(str(round(val, 1)))
else: else:
self.vm.event.pdirty = True self.vm.event.pdirty = True
case [ case [
@ -1072,7 +1079,7 @@ class NVDAVMWindow(psg.Window):
val = util.check_bounds(val, (-60, 12)) val = util.check_bounds(val, (-60, 12))
self.vm.bus[int(index)].gain = val self.vm.bus[int(index)].gain = val
self[f"BUS {index}||SLIDER GAIN"].update(value=val) self[f"BUS {index}||SLIDER GAIN"].update(value=val)
self.nvda.speak(str(val)) self.nvda.speak(str(round(val, 1)))
else: else:
self.vm.event.pdirty = True self.vm.event.pdirty = True
case [ case [
@ -1091,7 +1098,7 @@ class NVDAVMWindow(psg.Window):
val = util.check_bounds(val, (-60, 12)) val = util.check_bounds(val, (-60, 12))
self.vm.bus[int(index)].gain = val self.vm.bus[int(index)].gain = val
self[f"BUS {index}||SLIDER GAIN"].update(value=val) self[f"BUS {index}||SLIDER GAIN"].update(value=val)
self.nvda.speak(str(val)) self.nvda.speak(str(round(val, 1)))
else: else:
self.vm.event.pdirty = True self.vm.event.pdirty = True
case [["BUS", index], ["SLIDER", "GAIN"], ["KEY", "CTRL", "SHIFT", "R"]]: case [["BUS", index], ["SLIDER", "GAIN"], ["KEY", "CTRL", "SHIFT", "R"]]: