mirror of
https://github.com/onyx-and-iris/nvda-voicemeeter.git
synced 2025-05-22 11:40:25 +01:00
Compare commits
3 Commits
a19aab3936
...
3ca9e14e96
Author | SHA1 | Date | |
---|---|---|---|
3ca9e14e96 | |||
4ca64f94bc | |||
22bf109499 |
@ -106,7 +106,7 @@ All sliders may be controlled in three different ways:
|
|||||||
- `Shift + Left|Right arrow` to move a slider by 0.1 steps.
|
- `Shift + Left|Right arrow` to move a slider by 0.1 steps.
|
||||||
- `Control + Left|Right arrow` to move a slider by 3 steps.
|
- `Control + Left|Right arrow` to move a slider by 3 steps.
|
||||||
|
|
||||||
To rename a strip/bus channel navigate to the relevant tab, then press `F2`. This will open a popup window where you can set the channel index (with a spinbox) and set the new label using a text input box.
|
To rename a strip/bus channel focus on the channel in question and press `F2`. Then enter the new channel name into the text input widget and press the `Ok` button.
|
||||||
|
|
||||||
Pressing the `OK` button with an empty text input will clear the label. In this case the label will be read as a default value for that channel. For example, if the leftmost Strip label were cleared, the screen reader will now read `Hardware Input 1`.
|
Pressing the `OK` button with an empty text input will clear the label. In this case the label will be read as a default value for that channel. For example, if the leftmost Strip label were cleared, the screen reader will now read `Hardware Input 1`.
|
||||||
|
|
||||||
@ -143,6 +143,9 @@ You may also enter slider modes which allow for control of the channels sliders
|
|||||||
- `Control + G` will enter Gain mode
|
- `Control + G` will enter Gain mode
|
||||||
- `Control + T` will enter Gate mode
|
- `Control + T` will enter Gate mode
|
||||||
- `Control + L` will enter Limit mode
|
- `Control + L` will enter Limit mode
|
||||||
|
- `Control + B` will enter Bass mode
|
||||||
|
- `Control + I` will enter Mid mode
|
||||||
|
- `Control + R` will enter Treble mode
|
||||||
|
|
||||||
To exit any of the slider modes press `Escape`.
|
To exit any of the slider modes press `Escape`.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
[project]
|
[project]
|
||||||
name = "nvda_voicemeeter"
|
name = "nvda_voicemeeter"
|
||||||
version = "0.3.0"
|
version = "0.3.1"
|
||||||
description = "A Voicemeeter app compatible with NVDA"
|
description = "A Voicemeeter app compatible with NVDA"
|
||||||
authors = [
|
authors = [
|
||||||
{ name = "onyx-and-iris", email = "code@onyxandiris.online" },
|
{ name = "onyx-and-iris", email = "code@onyxandiris.online" },
|
||||||
|
@ -323,7 +323,7 @@ class Builder:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def add_param_sliders(layout):
|
def add_param_sliders(layout):
|
||||||
layout.append([LabelSlider(self.window, i, param) for param in util.get_slider_params(i, self.vm)])
|
layout.append([LabelSlider(self.window, i, param) for param in util.get_slider_params(i, self.kind)])
|
||||||
|
|
||||||
def add_limit_slider(layout):
|
def add_limit_slider(layout):
|
||||||
layout.append(
|
layout.append(
|
||||||
@ -416,13 +416,13 @@ class Builder:
|
|||||||
|
|
||||||
def add_param_sliders(layout):
|
def add_param_sliders(layout):
|
||||||
if self.kind.name in ("basic", "banana"):
|
if self.kind.name in ("basic", "banana"):
|
||||||
for param in util.get_slider_params(i, self.vm):
|
for param in util.get_slider_params(i, self.kind):
|
||||||
layout.append([LabelSlider(self.window, i, param, range_=(-12, 12))])
|
layout.append([LabelSlider(self.window, i, param, range_=(-12, 12))])
|
||||||
else:
|
else:
|
||||||
layout.append(
|
layout.append(
|
||||||
[
|
[
|
||||||
LabelSlider(self.window, i, param, range_=(-12, 12))
|
LabelSlider(self.window, i, param, range_=(-12, 12))
|
||||||
for param in util.get_slider_params(i, self.vm)
|
for param in util.get_slider_params(i, self.kind)
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ logger = logging.getLogger(__name__)
|
|||||||
class Popup:
|
class Popup:
|
||||||
def __init__(self, window):
|
def __init__(self, window):
|
||||||
self.window = window
|
self.window = window
|
||||||
|
self.kind = self.window.kind
|
||||||
self.logger = logger.getChild(type(self).__name__)
|
self.logger = logger.getChild(type(self).__name__)
|
||||||
|
|
||||||
def save_as(self, message, title=None, initial_folder=None):
|
def save_as(self, message, title=None, initial_folder=None):
|
||||||
@ -46,28 +47,27 @@ class Popup:
|
|||||||
if filepath:
|
if filepath:
|
||||||
return Path(filepath)
|
return Path(filepath)
|
||||||
|
|
||||||
def rename(self, message, title=None, tab=None):
|
def rename(self, message, index, title=None, tab=None):
|
||||||
if tab == "Physical Strip":
|
if "Strip" in tab:
|
||||||
upper = self.window.kind.phys_in + 1
|
if index < self.kind.phys_in:
|
||||||
elif tab == "Virtual Strip":
|
title += f" Physical Strip {index + 1}"
|
||||||
upper = self.window.kind.virt_in + 1
|
else:
|
||||||
elif tab == "Buses":
|
title += f" Virtual Strip {index - self.kind.phys_in + 1}"
|
||||||
upper = self.window.kind.num_bus + 1
|
else:
|
||||||
|
if index < self.kind.phys_out:
|
||||||
|
title += f" Physical Bus {index + 1}"
|
||||||
|
else:
|
||||||
|
title += f" Virtual Bus {index - self.kind.phys_out + 1}"
|
||||||
layout = [
|
layout = [
|
||||||
[psg.Text(message)],
|
[psg.Text(message)],
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
psg.Spin(
|
|
||||||
list(range(1, upper)), initial_value=1, size=2, enable_events=True, key=f"Index", readonly=True
|
|
||||||
),
|
|
||||||
psg.Input(key="Edit"),
|
psg.Input(key="Edit"),
|
||||||
],
|
],
|
||||||
[psg.Button("Ok"), psg.Button("Cancel")],
|
[psg.Button("Ok"), psg.Button("Cancel")],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
popup = psg.Window(title, layout, finalize=True)
|
popup = psg.Window(title, layout, finalize=True)
|
||||||
popup["Index"].bind("<FocusIn>", "||FOCUS IN")
|
|
||||||
popup["Edit"].bind("<FocusIn>", "||FOCUS IN")
|
popup["Edit"].bind("<FocusIn>", "||FOCUS IN")
|
||||||
popup["Ok"].bind("<FocusIn>", "||FOCUS IN")
|
popup["Ok"].bind("<FocusIn>", "||FOCUS IN")
|
||||||
popup["Ok"].bind("<Return>", "||KEY ENTER")
|
popup["Ok"].bind("<Return>", "||KEY ENTER")
|
||||||
@ -81,15 +81,8 @@ class Popup:
|
|||||||
if event in (psg.WIN_CLOSED, "Cancel"):
|
if event in (psg.WIN_CLOSED, "Cancel"):
|
||||||
break
|
break
|
||||||
match parsed_cmd := self.window.parser.match.parseString(event):
|
match parsed_cmd := self.window.parser.match.parseString(event):
|
||||||
case ["Index"]:
|
|
||||||
val = values["Index"]
|
|
||||||
self.window.nvda.speak(f"Index {val}")
|
|
||||||
case [[button], ["FOCUS", "IN"]]:
|
case [[button], ["FOCUS", "IN"]]:
|
||||||
if button == "Index":
|
self.window.nvda.speak(button)
|
||||||
val = values["Index"]
|
|
||||||
self.window.nvda.speak(f"Index {val}")
|
|
||||||
else:
|
|
||||||
self.window.nvda.speak(button)
|
|
||||||
case [[button], ["KEY", "ENTER"]]:
|
case [[button], ["KEY", "ENTER"]]:
|
||||||
popup.find_element_with_focus().click()
|
popup.find_element_with_focus().click()
|
||||||
case ["Ok"]:
|
case ["Ok"]:
|
||||||
|
@ -141,12 +141,19 @@ def check_bounds(val, bounds: tuple) -> int | float:
|
|||||||
return val
|
return val
|
||||||
|
|
||||||
|
|
||||||
def get_slider_params(i, vm) -> Iterable:
|
def get_slider_params(i, kind) -> Iterable:
|
||||||
if i < vm.kind.phys_in:
|
if i < kind.phys_in:
|
||||||
if vm.kind.name == "basic":
|
if kind.name == "basic":
|
||||||
return ("AUDIBILITY",)
|
return ("AUDIBILITY",)
|
||||||
if vm.kind.name == "banana":
|
if kind.name == "banana":
|
||||||
return ("COMP", "GATE")
|
return ("COMP", "GATE")
|
||||||
if vm.kind.name == "potato":
|
if kind.name == "potato":
|
||||||
return ("COMP", "GATE", "DENOISER")
|
return ("COMP", "GATE", "DENOISER")
|
||||||
return ("BASS", "MID", "TREBLE")
|
return ("BASS", "MID", "TREBLE")
|
||||||
|
|
||||||
|
|
||||||
|
def get_full_slider_params(i, kind) -> Iterable:
|
||||||
|
params = list(get_slider_params(i, kind) + ("GAIN", "LIMIT"))
|
||||||
|
if kind.name == "basic":
|
||||||
|
params.remove("LIMIT")
|
||||||
|
return params
|
||||||
|
@ -50,7 +50,7 @@ class NVDAVMWindow(psg.Window):
|
|||||||
[self[f"PATCH COMPOSITE||PC{i + 1}"].Widget.config(**buttonmenu_opts) for i in range(self.kind.phys_out)]
|
[self[f"PATCH COMPOSITE||PC{i + 1}"].Widget.config(**buttonmenu_opts) for i in range(self.kind.phys_out)]
|
||||||
slider_opts = {"takefocus": 1, "highlightthickness": 1}
|
slider_opts = {"takefocus": 1, "highlightthickness": 1}
|
||||||
for i in range(self.kind.num_strip):
|
for i in range(self.kind.num_strip):
|
||||||
for param in util.get_slider_params(i, self.vm):
|
for param in util.get_slider_params(i, self.kind):
|
||||||
self[f"STRIP {i}||SLIDER {param}"].Widget.config(**slider_opts)
|
self[f"STRIP {i}||SLIDER {param}"].Widget.config(**slider_opts)
|
||||||
self[f"STRIP {i}||SLIDER GAIN"].Widget.config(**slider_opts)
|
self[f"STRIP {i}||SLIDER GAIN"].Widget.config(**slider_opts)
|
||||||
if self.kind.name != "basic":
|
if self.kind.name != "basic":
|
||||||
@ -109,7 +109,7 @@ class NVDAVMWindow(psg.Window):
|
|||||||
self[f"STRIP {i}||SLIDER GAIN"].update(value=self.vm.strip[i].gain)
|
self[f"STRIP {i}||SLIDER GAIN"].update(value=self.vm.strip[i].gain)
|
||||||
if self.kind.name != "basic":
|
if self.kind.name != "basic":
|
||||||
self[f"STRIP {i}||SLIDER LIMIT"].update(value=self.vm.strip[i].limit)
|
self[f"STRIP {i}||SLIDER LIMIT"].update(value=self.vm.strip[i].limit)
|
||||||
for param in util.get_slider_params(i, self.vm):
|
for param in util.get_slider_params(i, self.kind):
|
||||||
if param in ("AUDIBILITY", "BASS", "MID", "TREBLE"):
|
if param in ("AUDIBILITY", "BASS", "MID", "TREBLE"):
|
||||||
val = getattr(self.vm.strip[i], param.lower())
|
val = getattr(self.vm.strip[i], param.lower())
|
||||||
else:
|
else:
|
||||||
@ -148,16 +148,18 @@ class NVDAVMWindow(psg.Window):
|
|||||||
self.bind("<Control-o>", "CTRL-O")
|
self.bind("<Control-o>", "CTRL-O")
|
||||||
self.bind("<Control-s>", "CTRL-S")
|
self.bind("<Control-s>", "CTRL-S")
|
||||||
self.bind("<Control-m>", "CTRL-M")
|
self.bind("<Control-m>", "CTRL-M")
|
||||||
|
|
||||||
|
self.bind("<Control-g>", "GAIN MODE")
|
||||||
|
self.bind("<Control-b>", "BASS MODE")
|
||||||
|
self.bind("<Control-i>", "MID MODE")
|
||||||
|
self.bind("<Control-r>", "TREBLE MODE")
|
||||||
if self.kind.name == "basic":
|
if self.kind.name == "basic":
|
||||||
self.bind("<Control-u>", "AUDIBILITY MODE")
|
self.bind("<Control-u>", "AUDIBILITY MODE")
|
||||||
self.bind("<Control-g>", "GAIN MODE")
|
|
||||||
elif self.kind.name == "banana":
|
elif self.kind.name == "banana":
|
||||||
self.bind("<Control-g>", "GAIN MODE")
|
|
||||||
self.bind("<Control-c>", "COMP MODE")
|
self.bind("<Control-c>", "COMP MODE")
|
||||||
self.bind("<Control-t>", "GATE MODE")
|
self.bind("<Control-t>", "GATE MODE")
|
||||||
self.bind("<Control-l>", "LIMIT MODE")
|
self.bind("<Control-l>", "LIMIT MODE")
|
||||||
else:
|
else:
|
||||||
self.bind("<Control-g>", "GAIN MODE")
|
|
||||||
self.bind("<Control-c>", "COMP MODE")
|
self.bind("<Control-c>", "COMP MODE")
|
||||||
self.bind("<Control-t>", "GATE MODE")
|
self.bind("<Control-t>", "GATE MODE")
|
||||||
self.bind("<Control-d>", "DENOISER MODE")
|
self.bind("<Control-d>", "DENOISER MODE")
|
||||||
@ -231,9 +233,7 @@ class NVDAVMWindow(psg.Window):
|
|||||||
|
|
||||||
# Strip Sliders
|
# Strip Sliders
|
||||||
for i in range(self.kind.num_strip):
|
for i in range(self.kind.num_strip):
|
||||||
for param in util.get_slider_params(i, self.vm) + ("GAIN", "LIMIT"):
|
for param in util.get_full_slider_params(i, self.kind):
|
||||||
if self.kind.name == "basic" and param == "LIMIT":
|
|
||||||
continue
|
|
||||||
self[f"STRIP {i}||SLIDER {param}"].bind("<FocusIn>", "||FOCUS IN")
|
self[f"STRIP {i}||SLIDER {param}"].bind("<FocusIn>", "||FOCUS IN")
|
||||||
self[f"STRIP {i}||SLIDER {param}"].bind("<FocusOut>", "||FOCUS OUT")
|
self[f"STRIP {i}||SLIDER {param}"].bind("<FocusOut>", "||FOCUS OUT")
|
||||||
self[f"STRIP {i}||SLIDER {param}"].bind("<Left>", "||KEY LEFT")
|
self[f"STRIP {i}||SLIDER {param}"].bind("<Left>", "||KEY LEFT")
|
||||||
@ -291,12 +291,12 @@ class NVDAVMWindow(psg.Window):
|
|||||||
self.logger.debug(f"values::{values}")
|
self.logger.debug(f"values::{values}")
|
||||||
if event in (psg.WIN_CLOSED, "Exit"):
|
if event in (psg.WIN_CLOSED, "Exit"):
|
||||||
break
|
break
|
||||||
elif event in ("GAIN MODE", "COMP MODE", "GATE MODE", "DENOISER MODE", "LIMIT MODE"):
|
elif event.endswith("MODE"):
|
||||||
mode = event
|
mode = event
|
||||||
self.nvda.speak(f"{mode} enabled")
|
self.nvda.speak(f"{mode} enabled")
|
||||||
elif event == "Escape:27":
|
elif event == "Escape:27":
|
||||||
if mode:
|
if mode:
|
||||||
self.nvda.speak(f"{mode.split()[0]} mode disabled")
|
self.nvda.speak(f"{mode} disabled")
|
||||||
mode = None
|
mode = None
|
||||||
|
|
||||||
if mode:
|
if mode:
|
||||||
@ -380,43 +380,47 @@ class NVDAVMWindow(psg.Window):
|
|||||||
| "SLIDER-MODE-CTRL-LEFT"
|
| "SLIDER-MODE-CTRL-LEFT"
|
||||||
| "SLIDER-MODE-CTRL-RIGHT" as op
|
| "SLIDER-MODE-CTRL-RIGHT" as op
|
||||||
]:
|
]:
|
||||||
op = op.removeprefix("SLIDER-MODE-").split("-")
|
|
||||||
if values["tabgroup"] not in ("tab||Physical Strip", "tab||Virtual Strip", "tab||Buses"):
|
if values["tabgroup"] not in ("tab||Physical Strip", "tab||Virtual Strip", "tab||Buses"):
|
||||||
continue
|
continue
|
||||||
param = values[event]
|
param = values[event]
|
||||||
if focus := self.find_element_with_focus():
|
if focus := self.find_element_with_focus():
|
||||||
identifier, partial = focus.Key.split("||")
|
identifier, partial = focus.Key.split("||")
|
||||||
if "SLIDER" not in partial:
|
_, index = identifier.split()
|
||||||
self.write_event_value(f"{identifier}||SLIDER {param}||KEY {' '.join(op)}", None)
|
if param in util.get_full_slider_params(int(index), self.kind):
|
||||||
|
if "SLIDER" not in partial:
|
||||||
|
op = op.removeprefix("SLIDER-MODE-").split("-")
|
||||||
|
self.write_event_value(f"{identifier}||SLIDER {param}||KEY {' '.join(op)}", None)
|
||||||
|
|
||||||
# Rename popups
|
# Rename popups
|
||||||
case ["F2:113"]:
|
case ["F2:113"]:
|
||||||
tab = values["tabgroup"].split("||")[1]
|
tab = values["tabgroup"].split("||")[1]
|
||||||
if tab in ("Physical Strip", "Virtual Strip", "Buses"):
|
if tab in ("Physical Strip", "Virtual Strip", "Buses"):
|
||||||
data = self.popup.rename("Label", title=f"Rename {tab}", tab=tab)
|
if focus := self.find_element_with_focus():
|
||||||
if not data: # cancel was pressed
|
identifier, partial = focus.Key.split("||")
|
||||||
continue
|
_, index = identifier.split()
|
||||||
index = int(data["Index"]) - 1
|
index = int(index)
|
||||||
match tab:
|
data = self.popup.rename("Label", index, title=f"Rename", tab=tab)
|
||||||
case "Physical Strip":
|
if not data: # cancel was pressed
|
||||||
label = data.get("Edit", f"Hardware Input {index + 1}")
|
continue
|
||||||
self.vm.strip[index].label = label
|
match tab:
|
||||||
self[f"STRIP {index}||LABEL"].update(value=label)
|
case "Physical Strip":
|
||||||
self.cache["labels"][f"STRIP {index}||LABEL"] = label
|
label = data.get("Edit", f"Hardware Input {int(index) + 1}")
|
||||||
case "Virtual Strip":
|
self.vm.strip[int(index)].label = label
|
||||||
index += self.kind.phys_in
|
self[f"STRIP {index}||LABEL"].update(value=label)
|
||||||
label = data.get("Edit", f"Virtual Input {index - self.kind.phys_in + 1}")
|
self.cache["labels"][f"STRIP {index}||LABEL"] = label
|
||||||
self.vm.strip[index].label = label
|
case "Virtual Strip":
|
||||||
self[f"STRIP {index}||LABEL"].update(value=label)
|
label = data.get("Edit", f"Virtual Input {int(index) + 1}")
|
||||||
self.cache["labels"][f"STRIP {index}||LABEL"] = label
|
self.vm.strip[int(index)].label = label
|
||||||
case "Buses":
|
self[f"STRIP {index}||LABEL"].update(value=label)
|
||||||
if index < self.kind.phys_out:
|
self.cache["labels"][f"STRIP {index}||LABEL"] = label
|
||||||
label = data.get("Edit", f"Physical Bus {index + 1}")
|
case "Buses":
|
||||||
else:
|
if index < self.kind.phys_out:
|
||||||
label = data.get("Edit", f"Virtual Bus {index - self.kind.phys_out + 1}")
|
label = data.get("Edit", f"Physical Bus {int(index) + 1}")
|
||||||
self.vm.bus[index].label = label
|
else:
|
||||||
self[f"BUS {index}||LABEL"].update(value=label)
|
label = data.get("Edit", f"Virtual Bus {int(index) - self.kind.phys_out + 1}")
|
||||||
self.cache["labels"][f"BUS {index}||LABEL"] = label
|
self.vm.bus[int(index)].label = label
|
||||||
|
self[f"BUS {index}||LABEL"].update(value=label)
|
||||||
|
self.cache["labels"][f"BUS {index}||LABEL"] = label
|
||||||
|
|
||||||
# Menus
|
# Menus
|
||||||
case [["Restart", "Audio", "Engine"], ["MENU"]]:
|
case [["Restart", "Audio", "Engine"], ["MENU"]]:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user