removed VTS hotkey feature and added a 60Hz poller for sliders and knobs to set volumes more real time

This commit is contained in:
Mel
2026-02-09 18:22:53 +01:00
parent 636ba5e8bc
commit 1d9a856359

View File

@@ -3,6 +3,7 @@
import json import json
import mido import mido
import subprocess import subprocess
import time
nanoKontrol2_mapping: dict[int, str] = { nanoKontrol2_mapping: dict[int, str] = {
0: "Slider_1", 0: "Slider_1",
@@ -66,7 +67,7 @@ audiomixer_mapping = {
"Slider_2": "mic2.input", "Slider_2": "mic2.input",
"Solo_2": "mic2.input", "Solo_2": "mic2.input",
"Mute_2": "mic2.input", "Mute_2": "mic2.input",
# "Record_2": "mic2.input", "Record_2": "mic2.input",
"Slider_3": "system.input", "Slider_3": "system.input",
"Solo_3": "system.input", "Solo_3": "system.input",
"Mute_3": "system.input", "Mute_3": "system.input",
@@ -79,14 +80,14 @@ audiomixer_mapping = {
"Solo_5": "music.input", "Solo_5": "music.input",
"Mute_5": "music.input", "Mute_5": "music.input",
"Record_5": "obs_music.input", "Record_5": "obs_music.input",
"Slider_6": "obs.input", "Slider_6": "obs_monitor.input",
"Solo_6": "obs.input", "Solo_6": "obs_monitor.input",
"Mute_6": "obs.input", "Mute_6": "",
# "Record_6": "obs.input", "Record_6": "obs_monitor.input",
"Slider_7": "music.input", "Slider_7": "",
"Solo_7": "music.input", "Solo_7": "",
"Mute_7": "music.input", "Mute_7": "",
# "Record_7": "music.input", "Record_7": "",
"Slider_8": "browser.input", "Slider_8": "browser.input",
"Solo_8": "browser.input", "Solo_8": "browser.input",
"Mute_8": "browser.input", "Mute_8": "browser.input",
@@ -104,12 +105,12 @@ audiomixer_mapping = {
"Play": "XF86AudioPlay", "Play": "XF86AudioPlay",
"Stop": "XF86AudioStop", "Stop": "XF86AudioStop",
"Record": "alsa_output.pci-0000_7d_00.6.analog-stereo", "Record": "alsa_output.pci-0000_7d_00.6.analog-stereo",
"Marker_set": "vts ctrl+v+2", "Marker_set": "",
"Marker_prev": "vts ctrl+v+3", "Marker_prev": "",
"Marker_next": "vts ctrl+v+4", "Marker_next": "",
"Track_prev": "vts ctrl+v+5", "Track_prev": "",
"Track_next": "vts ctrl+v+6", "Track_next": "",
"Cycle": "vts ctrl+v+0", "Cycle": "",
} }
@@ -178,13 +179,14 @@ def find_id(device: str) -> str:
return device_id return device_id
def set_mute(toggle: bool, device: str) -> None: def set_mute(mute: bool, device: str) -> None:
device_id = find_id(device) device_id = find_id(device)
if toggle: if device_id:
subprocess.Popen(["/usr/bin/wpctl", "set-mute", device_id, "1"]) if mute:
else: subprocess.Popen(["/usr/bin/wpctl", "set-mute", device_id, "1"])
subprocess.Popen(["/usr/bin/wpctl", "set-mute", device_id, "0"]) else:
subprocess.Popen(["/usr/bin/wpctl", "set-mute", device_id, "0"])
def set_volume(volume: int, device: str) -> None: def set_volume(volume: int, device: str) -> None:
@@ -203,26 +205,9 @@ def press_hotkey(hotkey: str) -> None:
def reset() -> None: def reset() -> None:
for channel in audiomixer_mapping: for channel in audiomixer_mapping:
if channel.startswith("Mute_") or channel == "Record": if channel.startswith("Mute_") or channel == "Record":
set_mute(False, audiomixer_mapping[channel]) set_mute(mute=False, device=audiomixer_mapping[channel])
elif channel.startswith("Record_"): elif channel.startswith("Record_"):
set_mute(True, audiomixer_mapping[channel]) set_mute(mute=True, device=audiomixer_mapping[channel])
def vts_hotkey(hotkey: str) -> None:
vts = subprocess.run(
["/usr/bin/xdotool", "search", "--name", "Vtube Studio"],
capture_output=True,
text=True,
).stdout.strip("\n")
subprocess.Popen(
[
"/usr/bin/xdotool",
"key",
"--window",
vts,
f"{hotkey}",
]
)
def main(): def main():
@@ -233,6 +218,9 @@ def main():
# Unmute all channels for me and mute all OBS channels when program starts (usually at boot) # Unmute all channels for me and mute all OBS channels when program starts (usually at boot)
reset() reset()
last_time = time.monotonic()
frequency = 1 / 60
with mido.open_input(midi_device[0]) as mixer: with mido.open_input(midi_device[0]) as mixer:
for update in mixer: for update in mixer:
midi_input = nanoKontrol2_mapping[update.control] midi_input = nanoKontrol2_mapping[update.control]
@@ -240,16 +228,19 @@ def main():
# Mute speakers # Mute speakers
if midi_input == "Record": if midi_input == "Record":
if update.value == 127: if update.value == 127:
set_mute(toggle=True, device=audiomixer_mapping["Knob_2"]) set_mute(mute=True, device=audiomixer_mapping["Knob_2"])
else: else:
set_mute(toggle=False, device=audiomixer_mapping["Knob_2"]) set_mute(mute=False, device=audiomixer_mapping["Knob_2"])
# Set volume per channel # Set volume per channel
if midi_input in sliders: if midi_input in sliders:
set_volume( now = time.monotonic()
volume=update.value, if now - last_time >= frequency:
device=audiomixer_mapping[nanoKontrol2_mapping[update.control]], last_time = now
) set_volume(
volume=update.value,
device=audiomixer_mapping[nanoKontrol2_mapping[update.control]],
)
# Muting channels for user # Muting channels for user
if ( if (
@@ -257,13 +248,13 @@ def main():
and midi_input.startswith("Mute_") and midi_input.startswith("Mute_")
and update.value == 127 and update.value == 127
): ):
set_mute(toggle=True, device=audiomixer_mapping[midi_input]) set_mute(mute=True, device=audiomixer_mapping[midi_input])
elif ( elif (
midi_input in buttons midi_input in buttons
and midi_input.startswith("Mute_") and midi_input.startswith("Mute_")
and update.value == 0 and update.value == 0
): ):
set_mute(toggle=False, device=audiomixer_mapping[midi_input]) set_mute(mute=False, device=audiomixer_mapping[midi_input])
# Enabling channels for OBS # Enabling channels for OBS
if ( if (
@@ -271,13 +262,13 @@ def main():
and midi_input.startswith("Record_") and midi_input.startswith("Record_")
and update.value == 0 and update.value == 0
): ):
set_mute(toggle=True, device=audiomixer_mapping[midi_input]) set_mute(mute=True, device=audiomixer_mapping[midi_input])
elif ( elif (
midi_input in buttons midi_input in buttons
and midi_input.startswith("Record_") and midi_input.startswith("Record_")
and update.value == 127 and update.value == 127
): ):
set_mute(toggle=False, device=audiomixer_mapping[midi_input]) set_mute(mute=False, device=audiomixer_mapping[midi_input])
# Media controls # Media controls
if midi_input in ["Prev", "Next"] and update.value == 127: if midi_input in ["Prev", "Next"] and update.value == 127:
@@ -287,16 +278,6 @@ def main():
): ):
press_hotkey(hotkey=audiomixer_mapping[midi_input]) press_hotkey(hotkey=audiomixer_mapping[midi_input])
try:
if (
midi_input
in ["Marker_prev", "Marker_next", "Track_prev", "Track_next"]
and update.value == 127
) or midi_input in ["Cycle", "Marker_set"]:
if audiomixer_mapping[midi_input].startswith("vts"):
vts_hotkey(hotkey=audiomixer_mapping[midi_input].split(" ")[1])
except KeyError:
pass
# TODO define mixers in config files # TODO define mixers in config files
# TODO user config for audio streams # TODO user config for audio streams