marioortizmanero / polybar-pulseaudio-control

A feature-full Polybar module to control PulseAudio
MIT License
465 stars 48 forks source link

Make `next-sink` also iterate the sink ports #60

Open shervinsahba opened 2 years ago

shervinsahba commented 2 years ago

For example, my speakers are on alsa_output.pci-0000_2f_00.4.iec958-stereo whereas my headphones are alsa_output.pci-0000_2f_00.4.analog-stereo. Running pulseuadio-control next-sink doesn't identify the alternate port and stays on whichever I'm on.

I'm currently using indicator-sound-switcher which seems to identify both ports, so there may be an idea there but I've yet to dig around.

Thanks!

marioortizmanero commented 2 years ago

The ports are indicated with a forward slash after the name, and then the port name. name/port. Are you using that syntax?

shervinsahba commented 2 years ago

I'm not sure if I understand, and it may be because of my unfamiliarity with pulseaudio.

When my headphones are active I have:

> pactl list sinks
Sink #8
    State: IDLE
    Name: alsa_output.pci-0000_2f_00.4.analog-stereo
    Description: Starship/Matisse HD Audio Controller Analog Stereo
    Driver: module-alsa-card.c
    Sample Specification: s16le 2ch 44100Hz
    Channel Map: front-left,front-right
    Owner Module: 9
    Mute: no
    Volume: front-left: 24236 /  37% / -25.92 dB,   front-right: 24236 /  37% / -25.92 dB
           balance 0.00
    Base Volume: 65536 / 100% / 0.00 dB
    Monitor Source: alsa_output.pci-0000_2f_00.4.analog-stereo.monitor
    Latency: 1999662 usec, configured 1999818 usec
    Flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY 
    Properties:
        alsa.resolution_bits = "16"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = "ALC1220 Analog"
        alsa.id = "ALC1220 Analog"
        alsa.subdevice = "0"
        alsa.subdevice_name = "subdevice #0"
        alsa.device = "0"
        alsa.card = "1"
        alsa.card_name = "HD-Audio Generic"
        alsa.long_card_name = "HD-Audio Generic at 0xf7a00000 irq 121"
        alsa.driver_name = "snd_hda_intel"
        device.bus_path = "pci-0000:2f:00.4"
        sysfs.path = "/devices/pci0000:00/0000:00:08.1/0000:2f:00.4/sound/card1"
        device.bus = "pci"
        device.vendor.id = "1022"
        device.vendor.name = "Advanced Micro Devices, Inc. [AMD]"
        device.product.id = "1487"
        device.product.name = "Starship/Matisse HD Audio Controller"
        device.string = "front:1"
        device.buffering.buffer_size = "352768"
        device.buffering.fragment_size = "176384"
        device.access_mode = "mmap+timer"
        device.profile.name = "analog-stereo"
        device.profile.description = "Analog Stereo"
        device.description = "Starship/Matisse HD Audio Controller Analog Stereo"
        module-udev-detect.discovered = "1"
        device.icon_name = "audio-card-pci"
    Ports:
        analog-output-lineout: Line Out (type: Line, priority: 9000, not available)
        analog-output-headphones: Headphones (type: Headphones, priority: 9900, available)
    Active Port: analog-output-headphones
    Formats:
        pcm

but when I switch to speakers, this becomes

> pactl list sinks
pactl list sinks
Sink #10
    State: IDLE
    Name: alsa_output.pci-0000_2f_00.4.iec958-stereo
    Description: Starship/Matisse HD Audio Controller Digital Stereo (IEC958)
    Driver: module-alsa-card.c
    Sample Specification: s16le 2ch 44100Hz
    Channel Map: front-left,front-right
    Owner Module: 9
    Mute: yes
    Volume: front-left: 39275 /  60% / -13.34 dB,   front-right: 39275 /  60% / -13.34 dB
           balance 0.00
    Base Volume: 65536 / 100% / 0.00 dB
    Monitor Source: alsa_output.pci-0000_2f_00.4.iec958-stereo.monitor
    Latency: 1083485 usec, configured 1999818 usec
    Flags: HARDWARE HW_MUTE_CTRL DECIBEL_VOLUME LATENCY SET_FORMATS 
    Properties:
        alsa.resolution_bits = "16"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = "ALC1220 Digital"
        alsa.id = "ALC1220 Digital"
        alsa.subdevice = "0"
        alsa.subdevice_name = "subdevice #0"
        alsa.device = "1"
        alsa.card = "1"
        alsa.card_name = "HD-Audio Generic"
        alsa.long_card_name = "HD-Audio Generic at 0xf7a00000 irq 121"
        alsa.driver_name = "snd_hda_intel"
        device.bus_path = "pci-0000:2f:00.4"
        sysfs.path = "/devices/pci0000:00/0000:00:08.1/0000:2f:00.4/sound/card1"
        device.bus = "pci"
        device.vendor.id = "1022"
        device.vendor.name = "Advanced Micro Devices, Inc. [AMD]"
        device.product.id = "1487"
        device.product.name = "Starship/Matisse HD Audio Controller"
        device.string = "iec958:1"
        device.buffering.buffer_size = "352768"
        device.buffering.fragment_size = "176384"
        device.access_mode = "mmap+timer"
        device.profile.name = "iec958-stereo"
        device.profile.description = "Digital Stereo (IEC958)"
        device.description = "Starship/Matisse HD Audio Controller Digital Stereo (IEC958)"
        module-udev-detect.discovered = "1"
        device.icon_name = "audio-card-pci"
    Ports:
        iec958-stereo-output: Digital Output (S/PDIF) (type: SPDIF, priority: 0, availability unknown)
    Active Port: iec958-stereo-output
    Formats:
        pcm

The sinks and ports seem to completely change. When running pulseuadio-control next-sink, I think the "next possible sink" in this scenario is unlisted.

marioortizmanero commented 2 years ago

Sorry for the late response. Unfortunately, this script doesn't iterate sink ports, only the sinks themselves. I'll modify this issue's title to make it a feature request, but I won't be able to work on it for now, as I don't have enough time.

gersilex commented 2 years ago

I noticed an issue, too, regarding the ports. If a sink as no available port (because no HDMI device is plugged in, for example), PulseAudio does not allow you to set this sink as new default, and therefore cycling through them with next-sink never advances.

Implementing this enhancement would also solve this bug, as those sinks with no ports would just be skipped in the nextSync loop.

Log: Three executions. The first one changes from the USB Headset to the next sink, which has no available ports. PulseAudio does fail silently when trying to set the default sink to it. The second iteration sees the default sink is still the USB Headset and tries again to set the default sink to the sink with the disabled port, which fails again, and so on.


sh-5.1$ bash -x /usr/bin/pulseaudio-control next-sink
+ AUTOSYNC=no
+ COLOR_MUTED='%{F#6b6b6b}'
+ ICON_MUTED=
+ ICON_SINK=
+ NOTIFICATIONS=no
+ OSD=no
+ SINK_NICKNAMES_PROP=
+ VOLUME_STEP=2
+ VOLUME_MAX=130
+ FORMAT='$VOL_ICON ${VOL_LEVEL}%  $ICON_SINK $SINK_NICKNAME'
+ declare -A SINK_NICKNAMES
+ declare -a ICONS_VOLUME
+ declare -a SINK_BLACKLIST
+ export LC_ALL=C
+ LC_ALL=C
+ END_COLOR='%{F-}'
+ [[ next-sink = --* ]]
+ case "$1" in
+ nextSink
+ getCurSink
+ pactl info
+ local curSinkName
++ pactl info
++ awk '/Default Sink: / {print $3}'
+ curSinkName=alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo
++ pactl list sinks
++ grep -B 4 -E 'Name: alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo$'
++ sed -nE 's/^Sink #([0-9]+)$/\1/p'
+ curSink=15
+ sinks=()
+ local i=0
+ read -r line
++ pactl list short sinks
++ sort -n
++ echo '15 alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo    module-alsa-card.c  s16le 2ch 48000Hz   RUNNING'
++ cut -f1
+ index=15
++ echo '15 alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo    module-alsa-card.c  s16le 2ch 48000Hz   RUNNING'
++ cut -f2
+ name=alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo
+ sinks[$i]=15
+ i=1
+ read -r line
++ echo '16 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=16
++ echo '16 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink
+ sinks[$i]=16
+ i=2
+ read -r line
++ echo '17 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=17
++ echo '17 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink
+ sinks[$i]=17
+ i=3
+ read -r line
++ echo '18 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=18
++ echo '18 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink
+ sinks[$i]=18
+ i=4
+ read -r line
++ echo '19 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink  module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=19
++ echo '19 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink  module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink
+ sinks[$i]=19
+ i=5
+ read -r line
+ '[' 5 -eq 0 ']'
+ local newSink
+ '[' 15 -ge 19 ']'
+ for sink in "${sinks[@]}"
+ '[' 15 -lt 15 ']'
+ for sink in "${sinks[@]}"
+ '[' 15 -lt 16 ']'
+ newSink=16
+ break
+ pactl set-default-sink 16
+ local inputs
++ pactl list short sink-inputs
++ cut -f 1
+ inputs=40
+ for i in $inputs
+ pactl move-sink-input 40 16
+ '[' no = yes ']'
sh-5.1$ bash -x /usr/bin/pulseaudio-control next-sink
+ AUTOSYNC=no
+ COLOR_MUTED='%{F#6b6b6b}'
+ ICON_MUTED=
+ ICON_SINK=
+ NOTIFICATIONS=no
+ OSD=no
+ SINK_NICKNAMES_PROP=
+ VOLUME_STEP=2
+ VOLUME_MAX=130
+ FORMAT='$VOL_ICON ${VOL_LEVEL}%  $ICON_SINK $SINK_NICKNAME'
+ declare -A SINK_NICKNAMES
+ declare -a ICONS_VOLUME
+ declare -a SINK_BLACKLIST
+ export LC_ALL=C
+ LC_ALL=C
+ END_COLOR='%{F-}'
+ [[ next-sink = --* ]]
+ case "$1" in
+ nextSink
+ getCurSink
+ pactl info
+ local curSinkName
++ pactl info
++ awk '/Default Sink: / {print $3}'
+ curSinkName=alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo
++ pactl list sinks
++ grep -B 4 -E 'Name: alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo$'
++ sed -nE 's/^Sink #([0-9]+)$/\1/p'
+ curSink=15
+ sinks=()
+ local i=0
+ read -r line
++ pactl list short sinks
++ sort -n
++ echo '15 alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=15
++ echo '15 alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo
+ sinks[$i]=15
+ i=1
+ read -r line
++ echo '16 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink    module-alsa-card.c  s16le 2ch 48000Hz   RUNNING'
++ cut -f1
+ index=16
++ echo '16 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink    module-alsa-card.c  s16le 2ch 48000Hz   RUNNING'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink
+ sinks[$i]=16
+ i=2
+ read -r line
++ echo '17 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=17
++ echo '17 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink
+ sinks[$i]=17
+ i=3
+ read -r line
++ echo '18 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=18
++ echo '18 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink
+ sinks[$i]=18
+ i=4
+ read -r line
++ echo '19 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink  module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=19
++ echo '19 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink  module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink
+ sinks[$i]=19
+ i=5
+ read -r line
+ '[' 5 -eq 0 ']'
+ local newSink
+ '[' 15 -ge 19 ']'
+ for sink in "${sinks[@]}"
+ '[' 15 -lt 15 ']'
+ for sink in "${sinks[@]}"
+ '[' 15 -lt 16 ']'
+ newSink=16
+ break
+ pactl set-default-sink 16
+ local inputs
++ pactl list short sink-inputs
++ cut -f 1
+ inputs=40
+ for i in $inputs
+ pactl move-sink-input 40 16
+ '[' no = yes ']'
sh-5.1$ bash -x /usr/bin/pulseaudio-control next-sink
+ AUTOSYNC=no
+ COLOR_MUTED='%{F#6b6b6b}'
+ ICON_MUTED=
+ ICON_SINK=
+ NOTIFICATIONS=no
+ OSD=no
+ SINK_NICKNAMES_PROP=
+ VOLUME_STEP=2
+ VOLUME_MAX=130
+ FORMAT='$VOL_ICON ${VOL_LEVEL}%  $ICON_SINK $SINK_NICKNAME'
+ declare -A SINK_NICKNAMES
+ declare -a ICONS_VOLUME
+ declare -a SINK_BLACKLIST
+ export LC_ALL=C
+ LC_ALL=C
+ END_COLOR='%{F-}'
+ [[ next-sink = --* ]]
+ case "$1" in
+ nextSink
+ getCurSink
+ pactl info
+ local curSinkName
++ pactl info
++ awk '/Default Sink: / {print $3}'
+ curSinkName=alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo
++ pactl list sinks
++ grep -B 4 -E 'Name: alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo$'
++ sed -nE 's/^Sink #([0-9]+)$/\1/p'
+ curSink=15
+ sinks=()
+ local i=0
+ read -r line
++ pactl list short sinks
++ sort -n
++ echo '15 alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=15
++ echo '15 alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.usb-Plantronics_Plantronics_C720-M_9e847df215ab234199193d978a830a8b-00.iec958-stereo
+ sinks[$i]=15
+ i=1
+ read -r line
++ echo '16 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink    module-alsa-card.c  s16le 2ch 48000Hz   RUNNING'
++ cut -f1
+ index=16
++ echo '16 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink    module-alsa-card.c  s16le 2ch 48000Hz   RUNNING'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_5__sink
+ sinks[$i]=16
+ i=2
+ read -r line
++ echo '17 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=17
++ echo '17 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_4__sink
+ sinks[$i]=17
+ i=3
+ read -r line
++ echo '18 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=18
++ echo '18 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink    module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp_3__sink
+ sinks[$i]=18
+ i=4
+ read -r line
++ echo '19 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink  module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f1
+ index=19
++ echo '19 alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink  module-alsa-card.c  s16le 2ch 48000Hz   IDLE'
++ cut -f2
+ name=alsa_output.pci-0000_00_1f.3-platform-skl_hda_dsp_generic.HiFi__hw_sofhdadsp__sink
+ sinks[$i]=19
+ i=5
+ read -r line
+ '[' 5 -eq 0 ']'
+ local newSink
+ '[' 15 -ge 19 ']'
+ for sink in "${sinks[@]}"
+ '[' 15 -lt 15 ']'
+ for sink in "${sinks[@]}"
+ '[' 15 -lt 16 ']'
+ newSink=16
+ break
+ pactl set-default-sink 16
+ local inputs
++ pactl list short sink-inputs
++ cut -f 1
+ inputs=40
+ for i in $inputs
+ pactl move-sink-input 40 16
+ '[' no = yes ']'