summaryrefslogtreecommitdiff
path: root/minivac.sh
blob: 6fb7fa7b40f5097303e5a8524c7e64ed07dad68e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#!/bin/bash


#########################     VARIABLES     #########################


NAME="FLIGU-GIGU"


MICROPHONE="alsa_input.pci-0000_00_1b.0.analog-stereo"
SPEAKERS="alsa_output.pci-0000_00_1b.0.analog-stereo"
PROGRAM="WEBRTC VoiceEngine"

SHORTCUTS=(
    'FUNCTION              |     TERMINAL EQUIVALENT                  |     RECOMMENDED KEYBIND'
    '------------------------------------------------------------------------------------------'
    'Change Sink           |     minivac.sh                           |     Ctrl+Shift+F7'
    'Load Sinks            |     minivac.sh -l                        |     -'
    'Unload Sinks          |     minivac.sh -u                        |     -'
    'Notify-send Sinks     |     minivac.sh -n                        |     F7'
    'Reset Sinks           |     minivac.sh -r                        |     Shift+F7'
)

DMENU_APPEARANCE="mononoki;11;#191919;#AAAAAA;#890089;#FFFFFF;Select Input:"

for i in {1..7}
do
   declare "dm$i=$( cut -f$i -d';' <<< "$DMENU_APPEARANCE" )"     # CONVERT DMENU APPEARANCE STRIP INTO SEPARATE PARAMETERS
done

mapfile -t INPUTS < <( pactl list sink-inputs | grep -B 30 -A 10 "application.process.binary" | grep "Sink Input\|application\.name\|media\.name" | grep -B 2 "application\.name" | sed -r "/--/d; s|Sink\ Input\ ||g; s|[[:space:]]*application\.name\ \=|\~|g; s|[[:space:]]*media\.name\ \=\ |\~\ |g" | paste -sd '  \n' )

mapfile -t SINKS < <( pactl list sinks | grep -A 3 "Sink #" | grep "Sink #\|Name:\|Description:" | sed -r "s|[[:space:]]*Name:\ |\~ |g; s|[[:space:]]*Description:\ |\~\ |g" | paste -sd '  \n' )

#########################     HELPER FUNCTIONS     #########################

treat_inputs () {
    i=0
    for INPUT in "${INPUTS[@]}"
    do
        SINK=$( pactl list sink-inputs | grep -A 5 "$( sed -r "s| .*||g" <<< "$INPUT" )" | grep "Sink:")
        SINK_TRANSLATED=$( pactl list sinks | grep -A 3 "$( sed -r 's|: | #|g' <<< "$SINK" )" | grep "Description" | sed -r "s|.*Description: ||g" )
        INPUTS[i]="$INPUT -> $SINK_TRANSLATED"
        ((i++))
    done
}

load_sinks () {
    if [[ -z "$( pw-cli list-objects | grep -i "node.name = \"$NAME\"")" ]]; then
        pactl load-module module-null-sink media.class=Audio/Sink sink_name="$NAME" channel_map=stereo
        pactl load-module module-null-sink media.class=Audio/Source/Virtual sink_name="$NAME-MIC" channel_map=front-left,front-right
        connect_nodes
    else
        echo -e "\nSink $NAME already loaded."
    fi
}

connect_nodes () {
    if [[ ! -z "$( pw-cli list-objects | grep -i "node.name = \"$PROGRAM\"")" ]]; then
        pw-link "mpv:output_FL" "${NAME}:playback_FL"
        pw-link "mpv:output_FR" "${NAME}:playback_FR"
        pw-link "${MICROPHONE}:capture_FL" "${NAME}:playback_FL"
        pw-link "${MICROPHONE}:capture_FR" "${NAME}:playback_FL"
        pw-link "${NAME}:monitor_FL" "${NAME}-MIC:input_FL"
        pw-link "${NAME}:monitor_FR" "${NAME}-MIC:input_FR"
    else
        echo -e "\nNode $PROGRAM not found."
    fi
}

unload_sinks () {
    read -r -p "Are you sure? [y/N] " response
    response=${response,,}    # tolower
    if [[ "$response" =~ ^(yes|y)$ ]]; then
        pactl list short modules | grep "$NAME" | cut -f1 | xargs -L1 pactl unload-module
        echo -e "\nSinks unloaded."
    else
        echo -e "\nSink unloading aborted."
    fi
}


reset_sinks () {
    echo -e "Yes\nNo" \
    | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "#900D09" -sf "$dm6" -p "Reset all sinks?" \
    | grep "Yes" &> /dev/null && for INPUT in "${INPUTS[@]}"; do pactl move-sink-input "$(echo $INPUT | awk -F' ~ ' '{print $1}' | sed "s|#||")" "alsa_output.pci-0000_00_1b.0.analog-stereo"; done \
    && $HOME/stuf/scripts/notification_wrapper.sh "\nALL SINKS HAVE BEEN RESET" "MINIVAC"
}

notify_sinks () {
    treat_inputs
    $HOME/stuf/scripts/notification_wrapper.sh "\nLIST OF CURRENT MAPPINGS\n$(for INPUT in "${INPUTS[@]}"; do echo "\n$INPUT"; done)" "MINIVAC"
}

change_sink () {
    treat_inputs
    CHOICE_INPUT=$( echo "$(for INPUT in "${INPUTS[@]}"; do echo $INPUT; done)" | uniq | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "$dm7" )
    CHI_COMMAND=$(echo $CHOICE_INPUT | awk -F' ~ ' '{print $1}' | sed "s|#||")
    CHI_NOTIFY=$(echo $CHOICE_INPUT | awk -F' ~ ' '{print $2}' )

    [[ -n $CHI_COMMAND ]] && CHOICE_SINK=$( echo "$(for SINK in "${SINKS[@]}"; do echo $SINK; done)" | uniq | dmenu -fn "$([[ $(fc-match "$dm1" | grep "$dm1") ]] && fc-match -f %{family} "$dm1" || fc-match -f %{family} mono)-$dm2" -l 10 -i -nb "$dm3" -nf "$dm4" -sb "$dm5" -sf "$dm6" -p "Select Sink:" )
    CHS_COMMAND=$(echo $CHOICE_SINK | awk -F' ~ ' '{print $2}' )
    CHS_NOTIFY=$(echo $CHOICE_SINK | awk -F' ~ ' '{print $3}' )

    [[ -n $CHI_COMMAND && -n $CHS_COMMAND ]] && pactl move-sink-input "$CHI_COMMAND" "$CHS_COMMAND" && $HOME/stuf/scripts/notification_wrapper.sh "\nSOURCE\n$CHI_NOTIFY\nHAS BEEN MOVED TO SINK\n$CHS_NOTIFY" "MINIVAC"
}

#########################     EXECUTION     #########################

# [[ -z $( grep -E "^alsa_output.pci-0000_03_04.0.analog-stereo$" $HOME/.config/pulse/* ) || -z $( grep -E "^alsa_input.pci-0000_03_04.0.iec958-stereo$" $HOME/.config/pulse/* ) ]] \
# && $HOME/stuf/scripts/notification_wrapper.sh "\nSYSTEM CHANGE DETECTED, TERMINATING PROGRAM" "MINIVAC" && exit

while getopts "hlunrc" opt; do
    case $opt in
    h) echo -e "usage: $0 [-h help] [-n notify-send sinks] [-l load sinks] [-u unload sinks] [-r reset sinks]\n\nSuggested Keyboard Shortcuts:\n"; printf '%s\n' "${SHORTCUTS[@]}";  exit ;;        # PRINT HELP IN TERMINAL
    l) load_sinks; exit ;;                                                                                                                                                                          # LOAD ALL SINKS
    u) unload_sinks; exit ;;                                                                                                                                                                        # UNLOAD ALL SINKS
    n) notify_sinks; exit ;;                                                                                                                                                                        # LIST ALL SINKS VIA WRAPPER
    r) reset_sinks; exit ;;                                                                                                                                                                         # RESET ALL SINKS
    c) connect_nodes; exit ;;                                                                                                                                                                         # RESET ALL SINKS
    ?) echo "error: option -$OPTARG is not implemented"; exit ;;
    esac
done

change_sink