From 2e93b1a285d1d27759fe377018b1175943b08d74 Mon Sep 17 00:00:00 2001 From: Sheldon Lee Date: Wed, 12 Apr 2023 08:19:03 +0100 Subject: [PATCH] Fuck bash scripting sometimes - Rewrote the script in python --- .config/scripts/pipewire/link-virtual-mic | 78 ++++++++++++++++++++ .config/scripts/pipewire/link-virtual-mic.sh | 71 ------------------ 2 files changed, 78 insertions(+), 71 deletions(-) create mode 100755 .config/scripts/pipewire/link-virtual-mic delete mode 100755 .config/scripts/pipewire/link-virtual-mic.sh diff --git a/.config/scripts/pipewire/link-virtual-mic b/.config/scripts/pipewire/link-virtual-mic new file mode 100755 index 0000000..00d27f7 --- /dev/null +++ b/.config/scripts/pipewire/link-virtual-mic @@ -0,0 +1,78 @@ +#!/usr/bin/python +import argparse +import subprocess +import time + +mappingMic = { + "output\\.rnnoise_source:capture_1": "mixed-mic:input_FL", + "output\\.rnnoise_source:capture_2": "mixed-mic:input_FR" +} + +mappingLoopback = { + "loopback:monitor_FL": "mixed-mic:input_FL", + "loopback:monitor_FR": "mixed-mic:input_FR" +} + + +parser = argparse.ArgumentParser( + prog="link-virtual-mic", + description="link pipewire virtual mics.") + +parser.add_argument("-a", "--all", action="store_true") +parser.add_argument("-d", "--disconnect", action="store_true") + + +def main(): + args = parser.parse_args() + + connectAll = args.all and not args.disconnect + disconnectAll = args.all and args.disconnect + + disconnectMic = args.all and args.disconnect + disconnectLoopback = args.disconnect + + tries = -1 + while tries < 20: + tries += 1 + + micSuccess = True + loopbackSuccess = True + if disconnectAll or not args.disconnect: + micSuccess = manageLinks(mappingMic, disconnectMic) + if connectAll or disconnectLoopback: + loopbackSuccess = manageLinks(mappingLoopback, disconnectLoopback) + + if not micSuccess or not loopbackSuccess: + time.sleep(1) + continue + break + + +def manageLinks(mapping, disconnect=False): + for key, value in mapping.items(): + cmdOpts = {"shell": True, "capture_output": True, "text": True} + + cmd = "pw-link -o | grep -e '{}'".format(key) + completedProcess = subprocess.run(cmd, **cmdOpts) + if completedProcess.returncode == 1: + return False + output = completedProcess.stdout.split('\n')[0] + + cmd = "pw-link -i | grep -e '{}'".format(value) + completedProcess = subprocess.run(cmd, **cmdOpts) + if completedProcess.returncode == 1: + return False + input = completedProcess.stdout.split('\n')[0] + + if disconnect: + cmd = ["pw-link", "-d", output, input] + else: + cmd = ["pw-link", output, input] + print(' '.join(cmd)) + subprocess.run(cmd, capture_output=True) + + return True + + +if __name__ == "__main__": + main() diff --git a/.config/scripts/pipewire/link-virtual-mic.sh b/.config/scripts/pipewire/link-virtual-mic.sh deleted file mode 100755 index 32d567c..0000000 --- a/.config/scripts/pipewire/link-virtual-mic.sh +++ /dev/null @@ -1,71 +0,0 @@ -#!/bin/sh - -# See https://superuser.com/questions/1675877/how-to-create-a-new-pipewire-virtual-device-that-to-combines-an-real-input-and-o - -declare -A mapping -declare -A mappingDetach - -# Map various audio outputs to be inputs to other sinks: -# -# Loopback Monitor -\ -# -> Combined Sink/Source -> Virtual Microphone -> Voice software -# rnnoise mic output -/ -mapping+=( - # Link loopback and mic to combined sink - ["loopback:monitor_FL"]="mixed-mic:input_FL" - ["loopback:monitor_FR"]="mixed-mic:input_FR" - - #["output\.filter-chain.*:capture_1"]="mixed-mic:input_FL" - #["output\.filter-chain.*:capture_2"]="mixed-mic:input_FR" - ["output\.rnnoise_source:capture_1"]="mixed-mic:input_FL" - ["output\.rnnoise_source:capture_2"]="mixed-mic:input_FR" - # Link combined sink to virtual mic - #["combined-sink:monitor_FL"]="mixed-mic:input_FL" - #["combined-sink:monitor_FR"]="mixed-mic:input_FR" -) - -mappingDetach+=( - ["output\.rnnoise_source:capture_1"]="mixed-mic:input_FL" - ["output\.rnnoise_source:capture_2"]="mixed-mic:input_FR" -) - -completed=false -tries=0 - -if [[ "$1" == "--disconnect" ]] || [[ "$1" == "-d" ]]; then - for key in ${!mapping[@]}; do - value=${mapping[${key}]} - - tmp=$(pw-link -o | grep -e ${key}) || break - output=$(echo $tmp | head -n1) - - tmp=$(pw-link -i | grep -e ${value}) || break - input=$(echo $tmp | head -n1) - - pw-link -d ${key} ${input} &> /dev/null - done - exit -fi - -while not $completed && [ "$tries" -lt "20" ]; do - for key in ${!mapping[@]}; do - completed=false - value=${mapping[${key}]} - - # Check if the outpts and inputs exist before trying to link them, otherwise causes issues. - tmp=$(pw-link -o | grep -e ${key}) || break - output=$(echo $tmp | head -n1) - - tmp=$(pw-link -i | grep -e ${value}) || break - input=$(echo $tmp | head -n1) - - if [[ "$1" == "--disconnect-all" ]] || [[ "$1" == "-da" ]]; then - pw-link -d ${output} ${input} &> /dev/null - else - pw-link ${output} ${input} &> /dev/null - fi - completed=true - done - sleep 1 - tries=$((tries+1)) -done