I often switch between phones and speakers, but I'm too lazy to do it through the sound preferences window. So I came up with this script*, and I'm sharing it here as others might find it useful.

You'll need to tweak it a bit to work in your machine, but once you do it you can run it from a launcher or a keyboard shortcut, it's really comfy.

Okay, here's the code:


#!/bin/bash

# You'll need to swap those four values with the ones that work in your machine.
# Check the rest of the post for further info.
mainCard="pci-0000_06_00.1"
mainProfile="hdmi-stereo-extra1"
altCard="pci-0000_00_09.2"
altProfile="analog-stereo"

# If the current default source is main, your new source is alt. Else, your new is main.
if [[ $(pactl get-default-source) == "alsa_output.$mainCard.$mainProfile.monitor" ]]
then declare -g newCard="$altCard" newProfile="$altProfile"
else declare -g newCard="$mainCard" newProfile="$mainProfile"
fi

# Tells PulseAudio to shift the card profile and default sink to the new.
pactl set-card-profile "alsa_card.${newCard}" "output:${newProfile}"
pacmd set-default-sink "alsa_output.${newCard}.${newProfile}" &> /dev/null\

# Tells PulseAudio to shift the currently running programs to use the new output.
for i in $(pacmd list-sink-inputs | grep index | awk '{print $2}')
do pacmd move-sink-input "$i" "alsa_output.${newCard}.${newProfile}" &> /dev/null
done

# Optional text notification.
if [[ $(pactl get-default-source) == "alsa_output.$mainCard.$mainProfile.monitor" ]]
then notify-send -t 500 "Main sound output on!"
elif [[ $(pactl get-default-source) == "alsa_output.$altCard.$altProfile.monitor" ]]
then notify-send -t 500 "Alt sound output on!"
else notify-send -t 2000 "Something weird happened."
fi

# Optional audio notification. It runs VLC but it's easy to adapt or remove if you want.
cvlc --play-and-exit /usr/share/sounds/freedesktop/stereo/message-new-instant.oga


Check the first four lines of code. You'll need to replace that "pci.blahblah" and "audio.stereo.whatever" junk with the ones from your machine. To know them, run pacmd list-sources | grep name: in a terminal. The output will look like this:

name: ⟨alsa_output.pci-0000_06_00.1.hdmi-stereo-extra1.monitor⟩
name: ⟨alsa_output.pci-0000_00_09.2.analog-stereo.monitor⟩

Ignore ⟨alsa_output and monitor⟩. The second-to-last chunk (e.g. hdmi-stereo-extra1) is the profile. The rest (e.g. pci-0000_06_00.1) is the card. Now replace those in the script.

*credits: this script is partially inspired on this AskUbuntu comment.

  • Lvxferre@lemmy.mlOP
    link
    fedilink
    arrow-up
    10
    ·
    edit-2
    1 year ago

    NOTE: Lemmy is hellbent on replacing the "&" in the code with "& amp;". You'll probably want to undo it before running this code.

    • Dr Jekell@lemmy.world
      link
      fedilink
      English
      arrow-up
      8
      ·
      1 year ago

      There is mark-up that turns text blocks to a code block that doesn't change anything.

      You can also try pasting it into a text editor as what you copied it from may be at fault (Microsoft word is known to do this).

      • Lvxferre@lemmy.mlOP
        link
        fedilink
        arrow-up
        1
        ·
        edit-2
        1 year ago

        I used Pluma to do this, so the issue is mostly Lemmy. (IIRC the devs did this to avoid some XSS).

        I'm aware of the ``` mark-up (I didn't use it to highlight the code in pink - useful to set it apart from the comments), is there another?

        (I also had to replace the angle brackets with ⟨⟩, glad that I had those due to Linguistics. Otherwise Lemmy just noms on them for breakfast.)

        • Dr Jekell@lemmy.world
          link
          fedilink
          English
          arrow-up
          2
          ·
          1 year ago

          You can use the greater-than sign to make code blocks but for some reason it then picks up your use of pound sign as the formatting for headers even though putting text into a code block should stop that.

    • Lvxferre@lemmy.mlOP
      link
      fedilink
      arrow-up
      1
      ·
      1 year ago

      I should try pipewire out someday. The reason I'm using pulseaudio is basically "it's Mint default and I didn't bother changing it".

        • Lvxferre@lemmy.mlOP
          link
          fedilink
          arrow-up
          1
          ·
          1 year ago

          Now I'm genuinely confused, given that I got both PipeWire and PulseAudio packages installed, by default (I didn't mess with it):

            • Lvxferre@lemmy.mlOP
              link
              fedilink
              arrow-up
              2
              ·
              1 year ago

              ps -e | pipewire says that pipewire failed to load, and pactl info outputs /run/user/1000/pulse/native for server string. As such, I think that PulseAudio is running without PipeWire.

              It's… weird, though. I wonder why Mint does this. It's a relatively new instal running Mint 21.2.

  • Hominine@lemmy.world
    link
    fedilink
    English
    arrow-up
    2
    ·
    1 year ago

    Thanks for this post, I'm looking forward to hammering something like this out myself and this is a great jumping off point. 👍

    • Lvxferre@lemmy.mlOP
      link
      fedilink
      arrow-up
      2
      ·
      1 year ago

      You're welcome! It ain't much but it's honest work. I also have other scripts that I don't mind sharing, but they're mostly dumb stuff, like a simple autoclick using xdotool.