change audio output between headphones and speakers on fedora 25

EDIT: I’ve corrected the script and added a small explanation on how to find out your sound card id.

In the last few days I’ve been busy installing and configuring the new Fedora 25 on my computers. I’ve installed it on my desktop and on my MacBook as well, and so far everything as been running quite smoothly! Nevertheless, nothing is ever 100% perfect, and I’ve run into a few quirks here and there. One of those quirks is that I couldn’t find a way to change the audio output between my headphones and my speakers, having them connected at the same time!

The symptoms were:

  • If I plugged the headphones in, sound started to play and the speakers were muted, as intended.
  • If I unplugged the headphones, sound started to play on the speakers. So far so good.

There is one problem with this approach. I really don’t want to plug and unplug the headphones every time I want to use them. So, after trying a few things without success, I’ve decided to write a script that takes care of everything! Run once, it changes from the current playing output to the other. Run it again, and it goes back. No sound coming from both ends, no strange mutes, everything works as expected! Let’s see how.


First steps:

  • Run pacmd list-sinks | grep analog-output and check your sinks port names.

My computer output is:

analog-output-lineout: Line Out (priority 9900, latency offset 0 usec, available: no)
analog-output-headphones: Headphones (priority 9000, latency offset 0 usec, available: yes)
active port: <analog-output-lineout>

Now I know that I want to change between analog-output-lineout and analog-output-headphones. Check your output to find out which naming scheme you’re using.

  • Now run pacmd list-cards | grep alsa_output:
alsa_output.pci-0000_00_1b.0.analog-stereo/#1: Built-in Audio Analog Stereo
alsa_output.pci-0000_00_1b.0.analog-stereo.monitor/#1: Monitor of Built-in Audio Analog Stereo

My device will be alsa_output.pci-0000_00_1b.0.analog-stereo, since I’m not using HDMI sound. You have to look at yours and see if you find something similar. It should be easy to identify.


The script:

  • vim audio-switcher (or any other name you like).
  • Copy the following script and replace DEVICE, FIRSTDEVICE and SECONDDEVICE with the values from the previous steps.

EDIT: You must replace ID with your own sound card id. You can find it using cat /proc/asound/cards and looking at the leftmost number.

#!/bin/bash

DEVICE='alsa_output.pci-0000_00_1b.0.analog-stereo'
FIRSTDEVICE=analog-output-lineout
SECONDDEVICE=analog-output-headphones
ACTIVE_SINK=$(pacmd list-sinks | grep 'active port' | awk '{ print $3 }')
ID=1

if [ "$ACTIVE_SINK" = "<analog-output-headphones>" ]; then
  echo "[*] Enabling all analog output on $DEVICE."
  pacmd set-sink-port $DEVICE $FIRSTDEVICE > /dev/null
  amixer -c $ID sset "Auto-Mute Mode" Disabled > /dev/null
else
  echo "[*] Enabling headphones only on $DEVICE."
  pacmd set-sink-port $DEVICE $SECONDDEVICE > /dev/null
  amixer -c $ID sset "Auto-Mute Mode" Enabled > /dev/null
fi

exit 0
  • Mark the script as executable: chmod +x audio-switcher.
  • You’re done! Just run it with ./audio-switcher and watch as your sound jumps from the speakers to the headphones and the other way around each time you run it. You can move the script to /usr/local/bin/ (mv audio-switcher /usr/local/bin) or symlink it (sudo ln -s /path/to/audio-switcher /usr/local/bin/) so you can call it from anywhere with audio-switcher.
    You can also assign a keyboard shortcut by going to System Settings > Keyboard > + and setting a name of your choice, the audio-switcher command and a shortcut you like.