#!/bin/bash
# Fast Site Engine. Copyright © 2004-2021, AC (acwed@ya.ru). All rights reserved. 2-clause BSD license.
# fsen.ru/linux/sound описание.
if [[ -z "$1" || -z "$2" ]]; then
  echo "Ошибка: не заданы параметры. Подробнее https://fsen.ru/linux/sound"
  exit 0
fi
A1="$1"
A2="$2"
A3=${3-""}
CF="" #pci-0000_20_00.0
CID=""
PLSC=`pactl list short cards`
getcard(){
  local L="" A=`pacmd s18tat` F="" Q=1 X="" R='^[0-9]+$'
  if [ -z "$1" ]; then
    F=$(echo A | awk -F': ' '/^Default sink name: /{print $2}')
    if [[ "$F" =~ "ladspa" ]]; then
      F=$(echo A | awk -F': ' '/^Default source name: /{print $2}')
    fi
    if [[ "$F" =~ ".monitor" ]]; then CF=${F%.*}; fi
    F=${F#*.} #отрезаем начало
    F=${F%.*} #конец
    A="$PLSC"
  elif [[ "$1" =~ $R ]]; then #по номеру
    Q=2
    A="$PLSC"
  else #по названию
    Q=3
    A=`pactl list cards`
    X="${1,,}" #в нижнеий регистр, ^^ в верхний
  fi
  while read L; do
    if [[ "$Q" = 1 ]]; then
      if [[ "$L" =~ "$F" ]]; then
        CID=$(echo "$L" | awk '{print $1}')
        CF=$(echo "$L" | awk '{print $2}')
        CF=${CF#*.}
        break
      fi
    elif [[ "$Q" = 2 ]]; then
      F=$(echo "$L" | awk '{print $1}')
      if [[ "$1" = "$F" ]]; then
        CID="$F"
        CF=$(echo "$L" | awk '{print $2}')
        CF=${CF#*.}
        break
      fi
    else
      if [[ "$L" =~ ": alsa_card." ]]; then F=$(echo "$L" | awk -F': ' '{print $2}'); fi
      if [[ "$L" =~ "№" ]]; then R=$(echo "$L" | awk -F'№' '{print $2}'); fi
      if [[ "$L" =~ "alsa.card_name" || "$L" =~ "alsa.long_card_name"  || "$L" =~ "device.vendor.name" || "$L" =~ "device.product.name" ]] && [[ "${L,,}" =~ "$X" ]]; then
        CID="$R"
        CF=${F#*.}
        break
      fi
    fi
  done <<< "$(echo -e "$A")"
}
setvs(){
  local V="$1" L="" F="" A=`pactl list short sinks`
  if [[ "$V" =~ '+' ]]; then V='+'${V/+/};
  elif [[ "$V" =~ '-' ]]; then V='-'${V/-/}; fi
  while read L; do
    if [[ "$L" =~ "alsa-card" ]]; then
      F=$(echo "$L" | awk '{print $2}')
      pactl set-sink-volume "$F" "$V"
    fi
  done <<< "$(echo -e "$A")"
}
setv(){
  local V="$1"
  if [[ "$V" =~ '+' ]]; then V=${V/+/}'+';
  elif [[ "$V" =~ '-' ]]; then V=${V/-/}'-'; fi
  amixer -c "$CID" -- sset Master "$V" unmute || setvs "$V"
}
setvol(){
  if [ "$1" = "all" ]; then
    local L="" A="$PLSC"
    while read L; do
      CID=$(echo "$L" | awk '{print $1}')
      CF=$(echo "$L" | awk '{print $2}')
      CF=${CF#*.}
      setv "$2"
    done <<< "$(echo -e "$A")"
  else
    getcard "$1"
    setv "$2"
  fi
}
if [ "$A1" = "up" ]; then
  setvol "$A3" "+$A2"
  exit 0
elif [ "$A1" = "down" ]; then
  setvol "$A3" "-$A2"
  exit 0
elif [ "$A1" = "vol" ]; then
  setvol "$A3" "$A2"
  exit 0
fi
A4=${4-""}
FF=""
PROF=""
PROF2=""
getpn(){
  declare -A a
  a["s"]="output:analog-stereo" #Аналоговый стерео выход
  a["sm"]="output:analog-stereo+input:analog-mono" #Аналоговый стерео выход + Аналоговый моно вход
  a["ss"]="output:analog-stereo+input:analog-stereo" #Аналоговый стерео дуплекс
  a["21"]="output:analog-surround-21" #Аналоговый объёмный 2.1 выход
  a["21m"]="output:analog-surround-21+input:analog-mono" #Аналоговый объёмный 2.1 выход + Аналоговый моно вход
  a["21s"]="output:analog-surround-21+input:analog-stereo" #Аналоговый объёмный 2.1 выход + Аналоговый стерео вход
  a["40"]="output:analog-surround-40" #Аналоговый объёмный 4.0 выход
  a["40m"]="output:analog-surround-40+input:analog-mono" #Аналоговый объёмный 4.0 выход + Аналоговый моно вход
  a["40s"]="output:analog-surround-40+input:analog-stereo" #Аналоговый объёмный 4.0 выход + Аналоговый стерео вход
  a["41"]="output:analog-surround-41" #Аналоговый объёмный 4.1 выход
  a["41m"]="output:analog-surround-41+input:analog-mono" #Аналоговый объёмный 4.1 выход + Аналоговый моно вход
  a["41s"]="output:analog-surround-41+input:analog-stereo" #Аналоговый объёмный 4.1 выход + Аналоговый стерео вход
  a["50"]="output:analog-surround-50" #Аналоговый объёмный 5.0 выход
  a["50m"]="output:analog-surround-50+input:analog-mono" #Аналоговый объёмный 5.0 выход + Аналоговый моно вход
  a["50s"]="output:analog-surround-50+input:analog-stereo" #Аналоговый объёмный 5.0 выход + Аналоговый стерео вход
  a["51"]="output:analog-surround-51" #Аналоговый объёмный 5.1 выход
  a["51m"]="output:analog-surround-51+input:analog-mono" #Аналоговый объёмный 5.1 выход + Аналоговый моно вход
  a["51s"]="output:analog-surround-51+input:analog-stereo" #Аналоговый объёмный 5.1 выход + Аналоговый стерео вход
  a["71"]="output:analog-surround-71" #Analog Surround 7.1 выход
  a["71m"]="output:analog-surround-71+input:analog-mono" #Analog Surround 7.1 выход + Аналоговый моно вход
  a["71s"]="output:analog-surround-71+input:analog-stereo" #Analog Surround 7.1 выход + Аналоговый стерео вход
  a["im"]="input:analog-mono" #Аналоговый моно вход
  a["is"]="input:analog-stereo" #Аналоговый стерео вход
  a["m"]="output:analog-mono" #Аналоговый моно выход
  a["mm"]="output:analog-mono+input:analog-mono" #Аналоговый моно дуплекс
  a["ms"]="output:analog-mono+input:analog-stereo" #Аналоговый моно выход + Аналоговый стерео вход
  a["958"]="output:iec958-stereo" #Цифровой стерео (IEC958) выход
  a["958m"]="output:iec958-stereo+input:analog-mono" #Цифровой стерео (IEC958) выход + Аналоговый моно вход
  a["958s"]="output:iec958-stereo+input:analog-stereo" #Цифровой стерео (IEC958) выход + Аналоговый стерео вход
  a["ds"]="output:hdmi-stereo" #Digital Stereo (HDMI) выход
  a["d51"]="output:hdmi-surround" #Digital Surround 5.1 (HDMI) выход
  a["d71"]="output:hdmi-surround71" #Digital Surround 7.1 (HDMI) выход
  a["ds2"]="output:hdmi-stereo-extra1" #Digital Stereo (HDMI 2) выход
  a["d512"]="output:hdmi-surround-extra1" #Digital Surround 5.1 (HDMI 2) выход
  a["d712"]="output:hdmi-surround71-extra1" #Digital Surround 7.1 (HDMI 2) выход
  a["ds3"]="output:hdmi-stereo-extra2" #Digital Stereo (HDMI 3) выход
  a["d513"]="output:hdmi-surround-extra2" #Digital Surround 5.1 (HDMI 3) выход
  a["d713"]="output:hdmi-surround71-extra2" #Digital Surround 7.1 (HDMI 3) выход
  a["ds4"]="output:hdmi-stereo-extra3" #Digital Stereo (HDMI 4) выход
  a["d514"]="output:hdmi-surround-extra3" #Digital Surround 5.1 (HDMI 4) выход
  a["d714"]="output:hdmi-surround71-extra3" #Digital Surround 7.1 (HDMI 4) выход
  a["off"]="off" #Выключено
  PROF2=${a["$1"]}
}
getp(){
  if [[ "$1" =~ " " ]]; then
    local P=$(echo "$1" | awk '{print $1}')
    getpn "$P"
    PROF="$PROF2"
    P=$(echo "$1" | awk '{print $2}')
    getpn "$P"
  else
    getpn "$1"
    PROF="$PROF2"
    PROF2=""
  fi
}
setpn(){
  if [ -n "$2" ]; then #не пустая
    pactl set-card-profile "$CID" "$1" || pactl set-card-profile "$CID" "$2"
  else
    pactl set-card-profile "$CID" "$1"
  fi
  amixer -c "$CID" set Front 1- unmute #kick lfe
  amixer -c "$CID" set Front 1+ unmute
}
setp(){
  getp "$1"
  if [ "$2" = "all" ]; then
    local L="" A="$PLSC"
    while read L; do
      CID=$(echo "$L" | awk '{print $1}')
      setpn "$PROF" "$PROF2"
    done <<< "$(echo -e "$A")"
  else
    getcard "$2"
    setpn "$PROF" "$PROF2"
  fi
}
getcp(){
  local L="" A="$PLSC"
  while read L; do
    if [[ "$L" =~ "alsa-card" &&  "$L" =~ "$1" ]]; then
      FF=$(echo "$L" | awk '{print $1}');
      break
    fi
  done <<< "$(echo -e "$A")"
}
togglep(){
  getp "$1"
  local L="" A="" F="" P1="$PROF" P2="$PROF2" P3="" P4="" F1="" F2=""
  getp "$2"
  P3="$PROF"
  P4="$PROF2"
  F1=$(echo "$P1" | awk -F':' '{print $2}')
  F2=$(echo "$P2" | awk -F':' '{print $2}')
  if [[ "$F1" =~ "+" ]]; then F1=$(echo "$F1" | awk -F'+' '{print $1}'); fi
  if [[ "$F2" =~ "+" ]]; then F2=$(echo "$F2" | awk -F'+' '{print $1}'); fi
  F1="\"$F1\""
  F2="\"$F2\""
  if ! [ "$3" = "all" ]; then getcard "$3"; fi
  A=`pactl list sinks`
  while read L; do
    if [[ "$L" =~ ": alsa_output." ]] && ! [[ "$L" =~ ".monitor" ]]; then
      F=${L#*.}
      F=${F%.*}
      getcp "$F"
      if [ "$3" = "all" ]; then CID="$FF"; fi
    fi
    if [[ "$L" =~ "device.profile.name" && "$FF" = "$CID" ]]; then
      if [[ "$L" =~ "$F1"  || "$L" =~ "$F2" ]]; then
        setpn "$P3" "$P4"
      else
        setpn "$P1" "$P2"
      fi
    fi
  done <<< "$(echo -e "$A")"
}
if [ "$A1" = "set" ]; then
  setp "$A2" "$A3"
elif [ "$A1" = "toggle" ]; then
  togglep "$A2" "$A3" "$A4"
elif [ "$A1" = "start" ]; then
  sleep 3s
  setvol "all" "1%"
  pulseaudio-equalizer enable
  sleep 2s
  setvol "all" "$A2%"
fi
