1

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
TMarks
  • 111

2 Answers2

1

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.

kanehekili
  • 7,426
0

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.

TMarks
  • 111