Score:1

Switching Audio devices breaks optical audio output

kr flag

I am trying to quickly switch between audio output of my headphones and my speakers. Both are connected to my motherboard, which has a Line Out and a Optical Audio Out line. I would ideally like to do this via two commands so that I can add them as macros/ hotkeys.

  • Speakers -> Optical Audio
  • Headphones -> Line Out

I can accomplish the switch from speakers to headphones using the Settings > Sound > Output menu where it successfully lists the 4 audio options I have plugged in, the other two of which are DP/HDMI connections via the graphics card. If I attempt to now switch back to my speakers from my headphones, no audio is output. I have a 'workaround' where I pause all audio, switch to one of the graphics card outputs, waiting 5 seconds, switch to the speakers, wait 5 seconds, then play music and this has so far reliably fixed the issue.

I have been attempting to use pactl to change the outputs, which I thought would be sinks, but I only have two sinks available:

➜  ~ pactl list sinks short
55  alsa_output.pci-0000_2d_00.4.iec958-stereo  PipeWire    s32le 2ch 48000Hz   RUNNING
52  alsa_output.pci-0000_2b_00.1.hdmi-stereo-extra1 PipeWire    s16le 2ch 48000Hz   SUSPENDED

This is show while listening to audio on the speakers. Below is while lsitening to audio on the headphones.

➜  ~ pactl list sinks short
52  alsa_output.pci-0000_2b_00.1.hdmi-stereo-extra1 PipeWire    s16le 2ch 48000Hz   SUSPENDED
55  alsa_output.pci-0000_2d_00.4.analog-stereo  PipeWire    s32le 2ch 48000Hz   RUNNING

I assume these sinks correspond to the motherboard audio card and the GPU output. In this case I would expect that changing the device-port would be the command I am looking for.

➜  ~ pactl set-sink-port alsa_output.pci-0000_2d_00.4.iec958-stereo analog-stereo        
Failure: No such entity

I'm quite confused on how to get this to work. Any help is greatly appreciated.

Below is some info I believe will be important. OS: Ubuntu 21.10

Below is the output of pactl info with my username removed:

Server String: /run/user/1000/pulse/native
Library Protocol Version: 35
Server Protocol Version: 35
Is Local: yes
Client Index: 68
Tile Size: 65472
User Name: {USER}
Host Name: ubuntu
Server Name: PulseAudio (on PipeWire 0.3.38)
Server Version: 15.0.0
Default Sample Specification: float32le 2ch 48000Hz
Default Channel Map: front-left,front-right
Default Sink: alsa_output.pci-0000_2d_00.4.iec958-stereo
Default Source: alsa_input.usb-Sonix_Technology_Co.__Ltd._USB_2.0_Camera_SN0001-02.analog-stereo
Cookie: bf70:5e64

EDIT

Given @kanehekili 's answer and comments it appears I am looking to set the sink-port. The way to do this is to use pactl set-sink-port {SINK_NAME} {PORT_NAME} however my port does not exist according to pactl list sinks:

➜  ~ pactl list sinks
Sink #47
    State: RUNNING
    Name: alsa_output.pci-0000_2d_00.4.iec958-stereo
    Description: Starship/Matisse HD Audio Controller Digital Stereo (IEC958)
    Driver: PipeWire
    Sample Specification: s32le 2ch 48000Hz
    Channel Map: front-left,front-right
    Owner Module: 4294967295
    Mute: no
    Volume: front-left: 28524 /  44% / -21.68 dB,   front-right: 28524 /  44% / -21.68 dB
            balance 0.00
    Base Volume: 65536 / 100% / 0.00 dB
    Monitor Source: alsa_output.pci-0000_2d_00.4.iec958-stereo.monitor
    Latency: 0 usec, configured 0 usec
    Flags: HARDWARE HW_MUTE_CTRL DECIBEL_VOLUME LATENCY SET_FORMATS 
    Properties:
        object.path = "alsa:pcm:1:iec958:1:playback"
        api.alsa.path = "iec958:1"
        api.alsa.pcm.card = "1"
        api.alsa.pcm.stream = "playback"
        audio.channels = "2"
        audio.position = "FL,FR"
        device.routes = "1"
        alsa.resolution_bits = "16"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = "ALCS1200A Digital"
        alsa.id = "ALCS1200A 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 0xfc400000 irq 80"
        alsa.driver_name = "snd_hda_intel"
        device.profile.name = "iec958-stereo"
        device.profile.description = "Digital Stereo (IEC958)"
        card.profile.device = "11"
        device.id = "41"
        factory.name = "api.alsa.pcm.sink"
        priority.driver = "672"
        priority.session = "672"
        media.class = "Audio/Sink"
        node.nick = "HD-Audio Generic"
        node.name = "alsa_output.pci-0000_2d_00.4.iec958-stereo"
        device.description = "Starship/Matisse HD Audio Controller Digital Stereo (IEC958)"
        device.icon_name = "audio-card-iec958"
        device.bus = "pci"
        device.bus_path = "pci-0000:2d:00.4"
        node.pause-on-idle = "false"
        factory.id = "18"
        client.id = "32"
        node.driver = "true"
        factory.mode = "merge"
        audio.adapt.follower = ""
        library.name = "audioconvert/libspa-audioconvert"
        object.id = "47"
        node.max-latency = "8192/48000"
    Ports:
        iec958-stereo-output: Digital Output (S/PDIF) (type: SPDIF, priority: 0, availability unknown)
    Active Port: iec958-stereo-output
    Formats:
        pcm

When I attempt to switch sink ports I am met with an error

➜  ~ pactl set-sink-port alsa_output.pci-0000_2d_00.4.iec958-stereo analog-stereo        
Failure: No such entity

The above occurs even when using the numeric identifier for the sink. It appears that the port I am looking for does not exist, however I can change the port using the Settings menu I mentioned above, and running the same pactl list sinks changes the ports so that my iec958-stereo port no longer exists:

➜  ~ pactl list sinks
Sink #47
    State: RUNNING
    Name: alsa_output.pci-0000_2d_00.4.analog-stereo
    Description: Starship/Matisse HD Audio Controller Analog Stereo
    Driver: PipeWire
    Sample Specification: s32le 2ch 48000Hz
    Channel Map: front-left,front-right
    Owner Module: 4294967295
    Mute: no
    Volume: front-left: 31249 /  48% / -19.30 dB,   front-right: 31249 /  48% / -19.30 dB
            balance 0.00
    Base Volume: 65536 / 100% / 0.00 dB
    Monitor Source: alsa_output.pci-0000_2d_00.4.analog-stereo.monitor
    Latency: 0 usec, configured 0 usec
    Flags: HARDWARE HW_MUTE_CTRL HW_VOLUME_CTRL DECIBEL_VOLUME LATENCY 
    Properties:
        object.path = "alsa:pcm:1:front:1:playback"
        api.alsa.path = "front:1"
        api.alsa.pcm.card = "1"
        api.alsa.pcm.stream = "playback"
        audio.channels = "2"
        audio.position = "FL,FR"
        device.routes = "2"
        alsa.resolution_bits = "16"
        device.api = "alsa"
        device.class = "sound"
        alsa.class = "generic"
        alsa.subclass = "generic-mix"
        alsa.name = "ALCS1200A Analog"
        alsa.id = "ALCS1200A 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 0xfc400000 irq 80"
        alsa.driver_name = "snd_hda_intel"
        device.profile.name = "analog-stereo"
        device.profile.description = "Analog Stereo"
        card.profile.device = "5"
        device.id = "41"
        factory.name = "api.alsa.pcm.sink"
        priority.driver = "689"
        priority.session = "689"
        media.class = "Audio/Sink"
        node.nick = "HD-Audio Generic"
        node.name = "alsa_output.pci-0000_2d_00.4.analog-stereo"
        device.description = "Starship/Matisse HD Audio Controller Analog Stereo"
        device.icon_name = "audio-card-analog"
        device.bus = "pci"
        device.bus_path = "pci-0000:2d:00.4"
        node.pause-on-idle = "false"
        factory.id = "18"
        client.id = "32"
        node.driver = "true"
        factory.mode = "merge"
        audio.adapt.follower = ""
        library.name = "audioconvert/libspa-audioconvert"
        object.id = "47"
        node.max-latency = "8192/48000"
    Ports:
        analog-output-lineout: Line Out (type: Line, priority: 9000, availability group: Legacy 4, available)
        analog-output-headphones: Headphones (type: Headphones, priority: 9900, availability group: Legacy 5, not available)
    Active Port: analog-output-lineout
    Formats:
        pcm
Score:1
zw flag

The trick is, that you need to switch your sink-inputs - which are only available when they are active/running:

pactl list short sink-inputs
28  8   31  protocol-native.c   float32le 2ch 48000Hz

Your stream "28" is mapped to the output "8". That output can be checked with:

pactl list short sinks
1   alsa_output.pci-0000_1e_00.3.analog-stereo  module-alsa-card.c  s16le 2ch 48000Hz   SUSPENDED
8   alsa_output.pci-0000_1c_00.1.hdmi-stereo-extra3 module-alsa-card.c  s16le 2ch 48000Hz   SUSPENDED

So currently the inputstream 28 (whatever source stream that may be) is directed to the hdmi card. If you want to change the output to the internal analog card (e.g. headphones) just can move it by issuing:

pactl move-sink-input 28 1

So one of yours sinks represent the headphones, the other the speakers. So instead of using the (" you'll nedd to switch you input to either 52 or 55.

EDIT

Since I'm not familiar with an optical device aside an analog headphone I'd try tow switch ports:

pactl list sinks
Sink #16
    State: RUNNING
    Name: alsa_output.pci-0000_1e_00.3.analog-stereo
    ....
    Ports: 
        analog-output-lineout: Line Out (type: Line, priority: 9000, available)
        analog-output-headphones: Headphones (type: Headphones, priority: 9900, available)
    Active Port: analog-output-lineout

In this case you could switch the ports in sink #16 with:

pactl set-sink-port 16 analog-output-lineout

or

pactl set-sink-port 16 analog-output-headphones

You need to find the correct sink index and the port names - that only applies if the digital output is a port.

The example is not really working by default since pulseaudio and alsa usually automute the speakers if they are inserted (see here for more information) but with the the appropriate settings it does work.

TMarks avatar
kr flag
Thanks so much for answering, I was worried no one knew! Unforunatly I'm trying to move not from my internal card to my graphics card, but from my internal card's 3.5mm output to the optical audio output. I am able to do this manually via the settings menu, albeit with the fiddling I mentioned in my question. From what you've described it sounnds like I am attempted to change whatever is lower in the hierarchy than sinks. In this diagram (https://gavv.github.io/articles/pulseaudio-under-the-hood/diagrams/devices_and_streams.png) I am trying to change the box labeled "Headphones".
kanehekili avatar
zw flag
OK- since you showed us to sinks I thought you wanted to switch between them. Here you'll have to switch the ports - as you already have surmised. I'll check if I can find sth
TMarks avatar
kr flag
Thanks, I've editted my question to show what ports are available to me and the issue I am having there. I think this is closer to the answer but I'm unable to see why ports would show up in the settings menu but not in the `pactl list sinks` command.
kanehekili avatar
zw flag
Your command is missing the sink number. Try with `pactl set-sink-port 47 iec958-stereo-output`
TMarks avatar
kr flag
That doesn't seem to be it. I can't seem to set the `sink-port`, as only one shows up at a time.
kanehekili avatar
zw flag
what does `pactl list cards`say? You might have to switch cards. Look [here](https://unix.stackexchange.com/questions/65246/change-pulseaudio-input-output-from-shell) for some more infos
TMarks avatar
kr flag
Let us [continue this discussion in chat](https://chat.stackexchange.com/rooms/131021/discussion-between-tmarks-and-kanehekili).
TMarks avatar
kr flag
I've added an answer to the question. Thank you so much for your help @kanehekilli, I really appreciate it.
kanehekili avatar
zw flag
Glad you figured it out. Thanks for your time - I've learned a lot. Still don't understand why a reinstall fixed it though.
TMarks avatar
kr flag
I think the reason is that I was using PipeWire in combination with PulseAudio. I'm unsure how the combination interacts, but I believe PipeWire was handling my ports and just passing them to PulseAudio, meaning they would not show up in `pactl list sinks`. Reinstalling PulseAudio also uninstalled PipeWire, meaning that Pulse had full control of Audio sinks again. That is my running theory.
Score:0
kr flag

My issue was due to using PipeWire, apparently. I was unable to resolve this issues I had while still using PipeWire so I attempted to uninstall, was met by a GUI crash, had to sudo apt install --reinstall ubuntu-desktop then reboot. After this and running only the PulseAudio daemon, I was able to use:

pactl set-card-profile {card_number} {profile_name}

to successfully switch between the outputs with only a minor delay (with no sound outputting during the delay). This appears to be the best that can be done and I am going to leave it at that.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.