Compare commits

..

14 Commits

Author SHA1 Message Date
c385476cc4 adjust cache to match strip layout
event keys updated

_get_bus_assignments added to util.py

patch bump
2023-09-29 20:08:18 +01:00
1c09556c61 adds missing karaoke mode k v
patch bump
2023-09-29 18:30:53 +01:00
421688eff8 resizes the patch composite buttons
fixes possible (but unlikely) index out of range.

patch bump
2023-09-29 13:38:40 +01:00
bdd570738a fix version bump... 2023-09-29 01:18:57 +01:00
71b137a9c2 use self.kind 2023-09-29 01:16:48 +01:00
912eb8c14d number of patch composite buttons fixed
for banana and potato kinds

voicemeeter-api dependency bump

patch bump
2023-09-29 01:09:18 +01:00
9cd65737e5 bump to version 0.5.1
closes #16
2023-09-28 23:35:02 +01:00
4a6ca2a353 check against slider modes explicitly
add enter/exit slider mode debug logging
2023-09-28 22:43:06 +01:00
cc99b14e89 define space bind event for bus buttons 2023-09-28 21:35:05 +01:00
23458debaa initial busmode buttonmenu implementation
bump to 0.5.1a1
Issue #16
2023-09-28 19:44:42 +01:00
496cc35321 fixes comp output gain resolution 2023-09-28 18:18:26 +01:00
d758db9dee lint/format fixes 2023-09-28 16:32:52 +01:00
876de55ad2 Advanced Comp|Gate sliders implemented
bump to 0.5.0

closes #14
2023-09-27 23:34:07 +01:00
eab4b1c6a9 fixes unboundlocalerror 2023-09-27 13:36:48 +01:00
8 changed files with 148 additions and 109 deletions

6
pdm.lock generated
View File

@@ -251,13 +251,13 @@ files = [
[[package]] [[package]]
name = "voicemeeter-api" name = "voicemeeter-api"
version = "2.4.10" version = "2.4.11"
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.10-py3-none-any.whl", hash = "sha256:2f75acb7b472e56b6bd8d4f1141f32d948c55ef9b30d5a08e085a1c8e76e2464"}, {file = "voicemeeter_api-2.4.11-py3-none-any.whl", hash = "sha256:7a1b290d90c851204438c18e2d343e568c242fcd1e664c5b88d4019a553d44e1"},
{file = "voicemeeter_api-2.4.10.tar.gz", hash = "sha256:1d8dfc1e8922179f8b97c90b90b9ed051082018c6af5feb1d48250140a02d40c"}, {file = "voicemeeter_api-2.4.11.tar.gz", hash = "sha256:875591ad326a7a13ef141536cca83953edcda81da256191bab3844bac46a0e70"},
] ]

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "nvda_voicemeeter" name = "nvda_voicemeeter"
version = "0.5.0b1" version = "0.5.5"
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" },
@@ -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.10", "voicemeeter-api>=2.4.11",
] ]
requires-python = ">=3.10,<3.12" requires-python = ">=3.10,<3.12"
readme = "README.md" readme = "README.md"

View File

@@ -197,16 +197,16 @@ class Builder:
"""tab0 row3 represents patch composite""" """tab0 row3 represents patch composite"""
def add_physical_device_opts(layout): def add_physical_device_opts(layout):
outputs = util.get_patch_composite_list(self.vm.kind) outputs = util.get_patch_composite_list(self.kind)
layout.append( layout.append(
[ [
psg.ButtonMenu( psg.ButtonMenu(
f"PC{i + 1}", f"PC{i + 1}",
size=(6, 2), size=(5, 2),
menu_def=["", outputs], menu_def=["", outputs],
key=f"PATCH COMPOSITE||PC{i + 1}", key=f"PATCH COMPOSITE||PC{i + 1}",
) )
for i in range(self.kind.phys_out) for i in range(self.kind.composite)
] ]
) )
@@ -381,7 +381,7 @@ class Builder:
if i == self.kind.phys_in + 1: if i == self.kind.phys_in + 1:
layout.append( layout.append(
[ [
psg.Button("K", size=(6, 2), key=f"STRIP {i}||MONO"), psg.Button("K", size=(6, 2), key=f"STRIP {i}||KARAOKE"),
psg.Button("Solo", size=(6, 2), key=f"STRIP {i}||SOLO"), psg.Button("Solo", size=(6, 2), key=f"STRIP {i}||SOLO"),
psg.Button("Mute", size=(6, 2), key=f"STRIP {i}||MUTE"), psg.Button("Mute", size=(6, 2), key=f"STRIP {i}||MUTE"),
], ],
@@ -389,7 +389,7 @@ class Builder:
else: else:
layout.append( layout.append(
[ [
psg.Button("MC", size=(6, 2), key=f"STRIP {i}||MONO"), psg.Button("MC", size=(6, 2), key=f"STRIP {i}||MC"),
psg.Button("Solo", size=(6, 2), key=f"STRIP {i}||SOLO"), psg.Button("Solo", size=(6, 2), key=f"STRIP {i}||SOLO"),
psg.Button("Mute", size=(6, 2), key=f"STRIP {i}||MUTE"), psg.Button("Mute", size=(6, 2), key=f"STRIP {i}||MUTE"),
], ],
@@ -478,18 +478,26 @@ class Builder:
"""tab3 row represents bus composite toggle""" """tab3 row represents bus composite toggle"""
def add_strip_outputs(layout): def add_strip_outputs(layout):
params = ["MONO", "EQ", "MUTE", "MODE"] params = ["MONO", "EQ", "MUTE"]
if self.vm.kind.name == "basic": if self.kind.name == "basic":
params.remove("EQ") params.remove("EQ")
label = {"MODE": "BUSMODE"} busmodes = [util._bus_mode_map[mode] for mode in util.get_bus_modes(self.vm)]
layout.append( layout.append(
[ [
*[
psg.Button( psg.Button(
label.get(param, param.capitalize()), param.capitalize(),
size=(12 if param == "MODE" else 6, 2), size=(6, 2),
key=f"BUS {i}||{param}", key=f"BUS {i}||{param}",
) )
for param in params for param in params
],
psg.ButtonMenu(
"BUSMODE",
size=(12, 2),
menu_def=["", busmodes],
key=f"BUS {i}||MODE",
),
] ]
) )

View File

@@ -33,7 +33,7 @@ def get_nvdapath():
try: try:
NVDA_PATH = Path(get_nvdapath()) / "nvda.exe" NVDA_PATH = Path(get_nvdapath()) / "nvda.exe"
except FileNotFoundError as e: except FileNotFoundError:
NVDA_PATH = "" NVDA_PATH = ""

View File

@@ -97,7 +97,7 @@ class CompSlider(psg.Slider):
return { return {
"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.1,
"disabled": True, "disabled": True,
} }

View File

@@ -5,7 +5,7 @@ def _make_hardware_ins_cache(vm) -> dict:
def _make_hardware_outs_cache(vm) -> dict: def _make_hardware_outs_cache(vm) -> dict:
hw_outs = {**{f"HARDWARE OUT||A{i + 1}": vm.bus[i].device.name for i in range(vm.kind.phys_out)}} hw_outs = {**{f"HARDWARE OUT||A{i + 1}": vm.bus[i].device.name for i in range(vm.kind.phys_out)}}
if vm.kind.name == "basic": if vm.kind.name == "basic":
hw_outs |= {f"HARDWARE OUT||A2": vm.bus[1].device.name} hw_outs |= {"HARDWARE OUT||A2": vm.bus[1].device.name}
return hw_outs return hw_outs
@@ -38,10 +38,15 @@ def _make_param_cache(vm, channel_type) -> dict:
**{f"STRIP {i}||B3": vm.strip[i].B3 for i in range(vm.kind.num_strip)}, **{f"STRIP {i}||B3": vm.strip[i].B3 for i in range(vm.kind.num_strip)},
} }
params |= { params |= {
**{f"STRIP {i}||MONO": vm.strip[i].mono for i in range(vm.kind.num_strip)}, **{f"STRIP {i}||MONO": vm.strip[i].mono for i in range(vm.kind.phys_in)},
**{f"STRIP {i}||SOLO": vm.strip[i].solo for i in range(vm.kind.num_strip)}, **{f"STRIP {i}||SOLO": vm.strip[i].solo for i in range(vm.kind.num_strip)},
**{f"STRIP {i}||MUTE": vm.strip[i].mute for i in range(vm.kind.num_strip)}, **{f"STRIP {i}||MUTE": vm.strip[i].mute for i in range(vm.kind.num_strip)},
} }
for i in range(vm.kind.phys_in, vm.kind.phys_in + vm.kind.virt_in):
if i == vm.kind.phys_in + 1:
params[f"STRIP {i}||KARAOKE"] = vm.strip[i].k
else:
params[f"STRIP {i}||MC"] = vm.strip[i].mc
else: else:
params |= { params |= {
**{f"BUS {i}||MONO": vm.bus[i].mono for i in range(vm.kind.num_bus)}, **{f"BUS {i}||MONO": vm.bus[i].mono for i in range(vm.kind.num_bus)},

View File

@@ -48,8 +48,11 @@ def get_patch_composite_list(kind) -> list:
for i in range(kind.phys_out): for i in range(kind.phys_out):
[temp.append(f"IN#{i + 1} {channel}") for channel in ("Left", "Right")] [temp.append(f"IN#{i + 1} {channel}") for channel in ("Left", "Right")]
for i in range(kind.phys_out, kind.phys_out + kind.virt_out): for i in range(kind.phys_out, kind.phys_out + kind.virt_out):
[temp.append(f"IN#{i + 1} {channel}") for channel in ("Left", "Right", "Center", "LFE", "SL", "SR", "BL", "BR")] [
temp.append(f"BUS Channel") temp.append(f"IN#{i + 1} {channel}")
for channel in ("Left", "Right", "Center", "LFE", "SL", "SR", "BL", "BR")
]
temp.append("BUS Channel")
return temp return temp
@@ -108,6 +111,24 @@ def get_channel_identifier_list(vm) -> list:
return identifiers return identifiers
_bus_mode_map = {
"normal": "Normal",
"amix": "Mix Down A",
"bmix": "Mix Down B",
"repeat": "Stereo Repeat",
"composite": "Composite",
"tvmix": "Up Mix TV",
"upmix21": "Up Mix 2.1",
"upmix41": "Up Mix 4.1",
"upmix61": "Up Mix 6.1",
"centeronly": "Center Only",
"lfeonly": "Low Frequency Effect Only",
"rearonly": "Rear Only",
}
_bus_mode_map_reversed = dict((reversed(item) for item in _bus_mode_map.items()))
def get_bus_modes(vm) -> list: def get_bus_modes(vm) -> list:
if vm.kind.name == "basic": if vm.kind.name == "basic":
return [ return [
@@ -157,3 +178,21 @@ def get_full_slider_params(i, kind) -> Iterable:
if kind.name == "basic": if kind.name == "basic":
params.remove("LIMIT") params.remove("LIMIT")
return params return params
def get_slider_modes() -> Iterable:
return (
"GAIN MODE",
"BASS MODE",
"MID MODE",
"TREBLE MODE",
"AUDIBILITY MODE",
"COMP MODE",
"GATE MODE",
"DENOISER MODE",
"LIMIT MODE",
)
def _get_bus_assignments(kind) -> list:
return [f"A{i}" for i in range(1, kind.phys_out + 1)] + [f"B{i}" for i in range(1, kind.virt_out + 1)]

View File

@@ -45,9 +45,9 @@ class NVDAVMWindow(psg.Window):
for i in range(self.kind.phys_out): for i in range(self.kind.phys_out):
self[f"HARDWARE OUT||A{i + 1}"].Widget.config(**buttonmenu_opts) self[f"HARDWARE OUT||A{i + 1}"].Widget.config(**buttonmenu_opts)
if self.kind.name == "basic": if self.kind.name == "basic":
self[f"HARDWARE OUT||A2"].Widget.config(**buttonmenu_opts) self["HARDWARE OUT||A2"].Widget.config(**buttonmenu_opts)
if self.kind.name != "basic": if self.kind.name != "basic":
[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.composite)]
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.kind): for param in util.get_slider_params(i, self.kind):
@@ -57,6 +57,7 @@ class NVDAVMWindow(psg.Window):
self[f"STRIP {i}||SLIDER LIMIT"].Widget.config(**slider_opts) self[f"STRIP {i}||SLIDER LIMIT"].Widget.config(**slider_opts)
for i in range(self.kind.num_bus): for i in range(self.kind.num_bus):
self[f"BUS {i}||SLIDER GAIN"].Widget.config(**slider_opts) self[f"BUS {i}||SLIDER GAIN"].Widget.config(**slider_opts)
self[f"BUS {i}||MODE"].Widget.config(**buttonmenu_opts)
if self.kind.name != "basic": if self.kind.name != "basic":
for i in range(self.kind.phys_out): for i in range(self.kind.phys_out):
self[f"ASIO CHECKBOX||IN{i + 1} 0"].Widget.config(state="readonly") self[f"ASIO CHECKBOX||IN{i + 1} 0"].Widget.config(state="readonly")
@@ -179,20 +180,20 @@ class NVDAVMWindow(psg.Window):
self.bind(f"<Alt-Control-{event}-{direction}>", f"ALT CTRL {direction.upper()}||{event_id}") self.bind(f"<Alt-Control-{event}-{direction}>", f"ALT CTRL {direction.upper()}||{event_id}")
# Hardware In # Hardware In
for i in range(self.vm.kind.phys_in): for i in range(self.kind.phys_in):
self[f"HARDWARE IN||{i + 1}"].bind("<FocusIn>", "||FOCUS IN") self[f"HARDWARE IN||{i + 1}"].bind("<FocusIn>", "||FOCUS IN")
self[f"HARDWARE IN||{i + 1}"].bind("<space>", "||KEY SPACE", propagate=False) self[f"HARDWARE IN||{i + 1}"].bind("<space>", "||KEY SPACE", propagate=False)
self[f"HARDWARE IN||{i + 1}"].bind("<Return>", "||KEY ENTER", propagate=False) self[f"HARDWARE IN||{i + 1}"].bind("<Return>", "||KEY ENTER", propagate=False)
# Hardware Out # Hardware Out
for i in range(self.vm.kind.phys_out): for i in range(self.kind.phys_out):
self[f"HARDWARE OUT||A{i + 1}"].bind("<FocusIn>", "||FOCUS IN") self[f"HARDWARE OUT||A{i + 1}"].bind("<FocusIn>", "||FOCUS IN")
self[f"HARDWARE OUT||A{i + 1}"].bind("<space>", "||KEY SPACE", propagate=False) self[f"HARDWARE OUT||A{i + 1}"].bind("<space>", "||KEY SPACE", propagate=False)
self[f"HARDWARE OUT||A{i + 1}"].bind("<Return>", "||KEY ENTER", propagate=False) self[f"HARDWARE OUT||A{i + 1}"].bind("<Return>", "||KEY ENTER", propagate=False)
if self.vm.kind.name == "basic": if self.kind.name == "basic":
self[f"HARDWARE OUT||A2"].bind("<FocusIn>", "||FOCUS IN") self["HARDWARE OUT||A2"].bind("<FocusIn>", "||FOCUS IN")
self[f"HARDWARE OUT||A2"].bind("<space>", "||KEY SPACE", propagate=False) self["HARDWARE OUT||A2"].bind("<space>", "||KEY SPACE", propagate=False)
self[f"HARDWARE OUT||A2"].bind("<Return>", "||KEY ENTER", propagate=False) self["HARDWARE OUT||A2"].bind("<Return>", "||KEY ENTER", propagate=False)
# Patch ASIO # Patch ASIO
if self.kind.name != "basic": if self.kind.name != "basic":
@@ -202,7 +203,7 @@ class NVDAVMWindow(psg.Window):
# Patch Composite # Patch Composite
if self.kind.name != "basic": if self.kind.name != "basic":
for i in range(self.vm.kind.phys_out): for i in range(self.kind.composite):
self[f"PATCH COMPOSITE||PC{i + 1}"].bind("<FocusIn>", "||FOCUS IN") self[f"PATCH COMPOSITE||PC{i + 1}"].bind("<FocusIn>", "||FOCUS IN")
self[f"PATCH COMPOSITE||PC{i + 1}"].bind("<space>", "||KEY SPACE", propagate=False) self[f"PATCH COMPOSITE||PC{i + 1}"].bind("<space>", "||KEY SPACE", propagate=False)
self[f"PATCH COMPOSITE||PC{i + 1}"].bind("<Return>", "||KEY ENTER", propagate=False) self[f"PATCH COMPOSITE||PC{i + 1}"].bind("<Return>", "||KEY ENTER", propagate=False)
@@ -236,7 +237,12 @@ class NVDAVMWindow(psg.Window):
self[f"STRIP {i}||{param}"].bind("<FocusIn>", "||FOCUS IN") self[f"STRIP {i}||{param}"].bind("<FocusIn>", "||FOCUS IN")
self[f"STRIP {i}||{param}"].bind("<Return>", "||KEY ENTER") self[f"STRIP {i}||{param}"].bind("<Return>", "||KEY ENTER")
else: else:
for param in ("MONO", "SOLO", "MUTE"): if i == self.kind.phys_in + 1:
for param in ("KARAOKE", "SOLO", "MUTE"):
self[f"STRIP {i}||{param}"].bind("<FocusIn>", "||FOCUS IN")
self[f"STRIP {i}||{param}"].bind("<Return>", "||KEY ENTER")
else:
for param in ("MC", "SOLO", "MUTE"):
self[f"STRIP {i}||{param}"].bind("<FocusIn>", "||FOCUS IN") self[f"STRIP {i}||{param}"].bind("<FocusIn>", "||FOCUS IN")
self[f"STRIP {i}||{param}"].bind("<Return>", "||KEY ENTER") self[f"STRIP {i}||{param}"].bind("<Return>", "||KEY ENTER")
@@ -260,13 +266,16 @@ class NVDAVMWindow(psg.Window):
self[f"STRIP {i}||SLIDER {param}"].bind("<Control-Shift-KeyPress-R>", "||KEY CTRL SHIFT R") self[f"STRIP {i}||SLIDER {param}"].bind("<Control-Shift-KeyPress-R>", "||KEY CTRL SHIFT R")
# Bus Params # Bus Params
params = ["MONO", "EQ", "MUTE", "MODE"] params = ["MONO", "EQ", "MUTE"]
if self.vm.kind.name == "basic": if self.kind.name == "basic":
params.remove("EQ") params.remove("EQ")
for i in range(self.kind.num_bus): for i in range(self.kind.num_bus):
for param in params: for param in params:
self[f"BUS {i}||{param}"].bind("<FocusIn>", "||FOCUS IN") self[f"BUS {i}||{param}"].bind("<FocusIn>", "||FOCUS IN")
self[f"BUS {i}||{param}"].bind("<Return>", "||KEY ENTER") self[f"BUS {i}||{param}"].bind("<Return>", "||KEY ENTER")
self[f"BUS {i}||MODE"].bind("<FocusIn>", "||FOCUS IN")
self[f"BUS {i}||MODE"].bind("<space>", "||KEY SPACE", propagate=False)
self[f"BUS {i}||MODE"].bind("<Return>", "||KEY ENTER", propagate=False)
# Bus Sliders # Bus Sliders
for i in range(self.kind.num_bus): for i in range(self.kind.num_bus):
@@ -300,13 +309,15 @@ 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.endswith("MODE"): elif event in util.get_slider_modes():
mode = event mode = event
self.nvda.speak(f"{mode} enabled") self.nvda.speak(f"{mode} enabled")
self.logger.debug(f"entered slider mode {mode}")
continue continue
elif event == "ESCAPE": elif event == "ESCAPE":
if mode: if mode:
self.nvda.speak(f"{mode} disabled") self.nvda.speak(f"{mode} disabled")
self.logger.debug(f"exited from slider mode {mode}")
mode = None mode = None
continue continue
@@ -423,7 +434,7 @@ class NVDAVMWindow(psg.Window):
identifier, partial = focus.Key.split("||") identifier, partial = focus.Key.split("||")
_, index = identifier.split() _, index = identifier.split()
index = int(index) index = int(index)
data = self.popup.rename("Label", index, title=f"Rename", tab=tab) data = self.popup.rename("Label", index, title="Rename", tab=tab)
if not data: # cancel was pressed if not data: # cancel was pressed
continue continue
match tab: match tab:
@@ -452,12 +463,12 @@ class NVDAVMWindow(psg.Window):
case "tab||Settings": case "tab||Settings":
self.write_event_value("ADVANCED SETTINGS", None) self.write_event_value("ADVANCED SETTINGS", None)
case "tab||Physical Strip": case "tab||Physical Strip":
if self.kind.name != "potato":
continue
if values["tabgroup||Physical Strip"] == "tab||Physical Strip||sliders": if values["tabgroup||Physical Strip"] == "tab||Physical Strip||sliders":
if focus := self.find_element_with_focus(): if focus := self.find_element_with_focus():
identifier, partial = focus.key.split("||") identifier, partial = focus.key.split("||")
_, index = identifier.split() _, index = identifier.split()
match self.kind.name:
case "potato":
if "SLIDER COMP" in partial: if "SLIDER COMP" in partial:
self.popup.compressor(int(index), title="Advanced Compressor") self.popup.compressor(int(index), title="Advanced Compressor")
elif "SLIDER GATE" in partial: elif "SLIDER GATE" in partial:
@@ -599,14 +610,20 @@ class NVDAVMWindow(psg.Window):
val = values[f"PATCH COMPOSITE||{key}"] val = values[f"PATCH COMPOSITE||{key}"]
index = int(key[-1]) - 1 index = int(key[-1]) - 1
self.vm.patch.composite[index].set(util.get_patch_composite_list(self.kind).index(val) + 1) self.vm.patch.composite[index].set(util.get_patch_composite_list(self.kind).index(val) + 1)
self.TKroot.after(200, self.nvda.speak, f"PATCH COMPOSITE {key[-1]} set {val}") self.TKroot.after(200, self.nvda.speak, val)
case [["PATCH", "COMPOSITE"], [key], ["FOCUS", "IN"]]: case [["PATCH", "COMPOSITE"], [key], ["FOCUS", "IN"]]:
if self.find_element_with_focus() is not None: if self.find_element_with_focus() is not None:
if values[f"PATCH COMPOSITE||{key}"]: if values[f"PATCH COMPOSITE||{key}"]:
val = values[f"PATCH COMPOSITE||{key}"] val = values[f"PATCH COMPOSITE||{key}"]
else: else:
index = int(key[-1]) - 1 index = int(key[-1]) - 1
val = util.get_patch_composite_list(self.kind)[self.vm.patch.composite[index].get() - 1] comp_index = self.vm.patch.composite[index].get()
comp_list = util.get_patch_composite_list(self.kind)
try:
val = comp_list[comp_index - 1]
except IndexError as e:
val = comp_list[-1]
self.logger.error(f"{type(e).__name__}: {e}")
self.nvda.speak(f"Patch COMPOSITE {key[-1]} {val}") self.nvda.speak(f"Patch COMPOSITE {key[-1]} {val}")
case [["PATCH", "COMPOSITE"], [key], ["KEY", "SPACE" | "ENTER"]]: case [["PATCH", "COMPOSITE"], [key], ["KEY", "SPACE" | "ENTER"]]:
util.open_context_menu_for_buttonmenu(self, f"PATCH COMPOSITE||{key}") util.open_context_menu_for_buttonmenu(self, f"PATCH COMPOSITE||{key}")
@@ -647,54 +664,36 @@ class NVDAVMWindow(psg.Window):
# Strip Params # Strip Params
case [["STRIP", index], [param]]: case [["STRIP", index], [param]]:
label = self.cache["labels"][f"STRIP {index}||LABEL"]
match param: match param:
case "MONO": case "KARAOKE":
if int(index) < self.kind.phys_in: opts = ["off", "k m", "k 1", "k 2", "k v"]
actual = param.lower()
elif int(index) == self.kind.phys_in + 1:
actual = "k"
else:
actual = "mc"
phonetic = {"k": "karaoke"}
if actual == "k":
next_val = self.vm.strip[int(index)].k + 1 next_val = self.vm.strip[int(index)].k + 1
if next_val == 4: if next_val == len(opts):
next_val = 0 next_val = 0
setattr(self.vm.strip[int(index)], actual, next_val) self.vm.strip[int(index)].k = next_val
self.cache["strip"][f"STRIP {index}||{param}"] = next_val self.cache["strip"][f"STRIP {index}||{param}"] = next_val
self.nvda.speak(["off", "k m", "k 1", "k 2"][next_val]) self.nvda.speak(opts[next_val])
else: case output if param in util._get_bus_assignments(self.kind):
val = not self.cache["strip"][f"STRIP {index}||{param}"] val = not self.cache["strip"][f"STRIP {index}||{output}"]
setattr(self.vm.strip[int(index)], actual, val) setattr(self.vm.strip[int(index)], output, val)
self.cache["strip"][f"STRIP {index}||{param}"] = val self.cache["strip"][f"STRIP {index}||{output}"] = val
self.nvda.speak("on" if val else "off") self.nvda.speak("on" if val else "off")
case _: case _:
val = not self.cache["strip"][f"STRIP {index}||{param}"] val = not self.cache["strip"][f"STRIP {index}||{param}"]
setattr(self.vm.strip[int(index)], param if param[0] in ("A", "B") else param.lower(), val) setattr(self.vm.strip[int(index)], param.lower(), val)
self.cache["strip"][f"STRIP {index}||{param}"] = val self.cache["strip"][f"STRIP {index}||{param}"] = val
self.nvda.speak("on" if val else "off") self.nvda.speak("on" if val else "off")
case [["STRIP", index], [param], ["FOCUS", "IN"]]: case [["STRIP", index], [param], ["FOCUS", "IN"]]:
if self.find_element_with_focus() is not None: if self.find_element_with_focus() is not None:
val = self.cache["strip"][f"STRIP {index}||{param}"] val = self.cache["strip"][f"STRIP {index}||{param}"]
match param: phonetic = {"KARAOKE": "karaoke"}
case "MONO":
if int(index) < self.kind.phys_in:
actual = param.lower()
elif int(index) == self.kind.phys_in + 1:
actual = "k"
else:
actual = "mc"
case _:
actual = param
phonetic = {"k": "karaoke"}
label = self.cache["labels"][f"STRIP {index}||LABEL"] label = self.cache["labels"][f"STRIP {index}||LABEL"]
if actual == "k": if param == "KARAOKE":
self.nvda.speak( self.nvda.speak(
f"{label} {phonetic.get(actual, actual)} {['off', 'k m', 'k 1', 'k 2'][self.cache['strip'][f'STRIP {int(index)}||{param}']]}" f"{label} {phonetic.get(param, param)} {['off', 'k m', 'k 1', 'k 2', 'k v'][self.cache['strip'][f'STRIP {int(index)}||{param}']]}"
) )
else: else:
self.nvda.speak(f"{label} {phonetic.get(actual, actual)} {'on' if val else 'off'}") self.nvda.speak(f"{label} {phonetic.get(param, param)} {'on' if val else 'off'}")
case [["STRIP", index], [param], ["KEY", "ENTER"]]: case [["STRIP", index], [param], ["KEY", "ENTER"]]:
self.find_element_with_focus().click() self.find_element_with_focus().click()
@@ -964,6 +963,7 @@ class NVDAVMWindow(psg.Window):
self.vm.strip[int(index)].gain = 0 self.vm.strip[int(index)].gain = 0
self[f"STRIP {index}||SLIDER {param}"].update(value=0) self[f"STRIP {index}||SLIDER {param}"].update(value=0)
case "COMP" | "GATE" | "DENOISER": case "COMP" | "GATE" | "DENOISER":
target = getattr(self.vm.strip[int(index)], param.lower())
setattr(target, "knob", 0) setattr(target, "knob", 0)
self[f"STRIP {index}||SLIDER {param}"].update(value=0) self[f"STRIP {index}||SLIDER {param}"].update(value=0)
case "AUDIBILITY": case "AUDIBILITY":
@@ -1001,39 +1001,26 @@ class NVDAVMWindow(psg.Window):
"on" if val else "off", "on" if val else "off",
) )
case "MODE": case "MODE":
bus_modes = util.get_bus_modes(self.vm) chosen = util._bus_mode_map_reversed[values[event]]
next_index = bus_modes.index(val) + 1 setattr(self.vm.bus[int(index)].mode, chosen, True)
if next_index == len(bus_modes): self.cache["bus"][event] = chosen
next_index = 0
next_bus = bus_modes[next_index]
phonetic = {
"amix": "Mix Down A",
"bmix": "Mix Down B",
"repeat": "Stereo Repeat",
"tvmix": "Up Mix TV",
"upmix21": "Up Mix 2.1",
"upmix41": "Up Mix 4.1",
"upmix61": "Up Mix 6.1",
"centeronly": "Center Only",
"lfeonly": "Low Frequency Effect Only",
"rearonly": "Rear Only",
}
setattr(self.vm.bus[int(index)].mode, next_bus, True)
self.cache["bus"][event] = next_bus
self.TKroot.after( self.TKroot.after(
200, 200,
self.nvda.speak, self.nvda.speak,
phonetic.get(next_bus, next_bus), util._bus_mode_map[chosen],
) )
case [["BUS", index], [param], ["FOCUS", "IN"]]: case [["BUS", index], [param], ["FOCUS", "IN"]]:
if self.find_element_with_focus() is not None: if self.find_element_with_focus() is not None:
label = self.cache["labels"][f"BUS {index}||LABEL"] label = self.cache["labels"][f"BUS {index}||LABEL"]
val = self.cache["bus"][f"BUS {index}||{param}"] val = self.cache["bus"][f"BUS {index}||{param}"]
if param == "MODE": if param == "MODE":
self.nvda.speak(f"{label} bus {param} {val}") self.nvda.speak(f"{label} bus {param} {util._bus_mode_map[val]}")
else:
self.nvda.speak(f"{label} {param} {'on' if val else 'off'}")
case [["BUS", index], [param], ["KEY", "SPACE" | "ENTER"]]:
if param == "MODE":
util.open_context_menu_for_buttonmenu(self, f"BUS {index}||MODE")
else: else:
self.nvda.speak(f"{label} bus {param} {'on' if val else 'off'}")
case [["BUS", index], [param], ["KEY", "ENTER"]]:
self.find_element_with_focus().click() self.find_element_with_focus().click()
# Bus Sliders # Bus Sliders