Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I have a set of nice wireless headphones which I use from time to time, in addition to my speakers and normal microphone.

I'd like to write a script to switch between one input and output source and another, essentially a switch between my headphones and my speakers+microphone.

I'd like to change between this:

...and this:

Is there a way for me script a transfer between the two inputs and outputs? Essentially I'm looking for something like this:

CURRENT_INPUT="$(get-current-input-name)"
CURRENT_OUTPUT="$(get-current-output-name)"

if [ "$CURRENT_INPUT" == "Vengeance 2000" ]; then
    set-current-input "HD Pro Webcam C920"
else 
    set-current-input "Vengeance 2000"
fi

if ["$CURRENT_OUTPUT" == "Vengeance 2000" ]; then
    set-current-output "Built-in Audio"
else
    set-current-output "Vengeance 2000"
fi

Is there a way to script this?

share|improve this question
3  
You may have a look at man pactl for PulseAudio command line options. –  Teresa e Junior Feb 19 '13 at 3:43
    
Off-topic: what GUI application is that on those screenshots? –  Hugo May 10 '13 at 18:08
    
It's elementary's System Settings. –  Naftuli Tzvi Kay May 10 '13 at 18:47
add comment

3 Answers

up vote 12 down vote accepted
+100

As @Teresa-e-Junior pointed out pactl is the tool to use:

First of all we might want to get the IDs of our PA sinks. On my system this is what I get:

$ pactl list short sinks
0       alsa_output.pci-0000_01_00.1.hdmi-surround      module-alsa-card.c      s16le 6ch 44100Hz  SUSPENDED
1       alsa_output.pci-0000_00_1b.0.analog-stereo      module-alsa-card.c      s16le 2ch 44100Hz  RUNNING

Sink 1 is currently my default sink.
But now I want all my current and future streams to be played via HDMI (i.e. sink 0).

There is a command to set the default sink for PulseAudio, but it doesn't seem to have any effect on my PC:

$ pacmd set-default-sink 0 #doesn't work on my PC :(

Instead, new streams seem to be connected to the sink that had a stream moved to it most recently.

So let's tell pactl to move all currently playing streams to sink 0. We'll first need to list them:

$ pactl list short sink-inputs
290     1       176     protocol-native.c       float32le 2ch 44100Hz
295     1       195     protocol-native.c       float32le 2ch 44100Hz

Ok, we've got two streams (IDs 290 and 295) that are both attached to sink 1.
Let's move them to sink 0:

$ pactl move-sink-input 290 0
$ pactl move-sink-input 295 0

So, that should be it. Now we just have to make a script that does the work for us:

#!/bin/bash

if [ -z "$1" ]; then
    echo "Usage: $0 <sinkId/sinkName>" >&2
    echo "Valid sinks:" >&2
    pactl list short sinks >&2
    exit 1
fi

newSink="$1"

pactl list short sink-inputs|while read stream; do
    streamId=$(echo $stream|cut '-d ' -f1)
    echo "moving stream $streamId"
    pactl move-sink-input "$streamId" "$newSink"
done

You can call it with either a sink ID or a sink name as parameter (i.e. either 0 or something like alsa_output.pci-0000_01_00.1.hdmi-surround).

Now you could attach this script to a udev event or key shortcut.

share|improve this answer
1  
Awesome, thanks! I've turned this into a Python script which makes it nice and easy to work with, it's available here. –  Naftuli Tzvi Kay Mar 11 '13 at 18:27
    
Related: askubuntu.com/a/14083/6645 –  Naftuli Tzvi Kay May 10 '13 at 19:47
add comment

The following commands are use to manipulate the PulseAudio sound server:

pacmd - Used to reconfigure a PulseAudio sound server during runtime.
pactl - Used to control a running PulseAudio sound server.

Here are some examples of how they function.

pacmd list-sinks :: list name or index number of possible sinks

pacmd set-default-sink [sinkname] :: set the default output sink

pacmd set-default-source [sourcename] :: set the default input

pacmd set-sink-volume [index] [volume] :: set the sink volume

pacmd set-source-volume index volume :: volume control range 0 - 65536 (the lower the number the lower the volume)

These are only a few that I've pulled out of the wiki & man page. Reference this for more detailed information. Or you can view either commands --help or man page.

There is also a command line tool already out there that serves this purpose. It's name is ponymix. It's a command line mixer for PulseAudio. The link provided is to the projects github. It's developed by a friend and fellow Arch Linux Trusted User / Developer. If you're not running Arch you could just compile it from source using make and sudo make install.

$ ponymix --help
    usage: ponymix [options] <command>... 
Options:
 -h, --help              display this help and exit    
 -c, --card CARD         target card (index or name)
 -d, --device DEVICE     target device (index or name)
 -t, --devtype TYPE      device type
 -N, --notify            use libnotify to announce volume changes
     --source            alias to -t source
     --input             alais to -t source
     --sink              alias to -t sink
     --output            alias to -t sink
     --sink-input        alias to -t sink-input
     --source-output     alias to -t source-output
Device Commands:
  help                   display this message
  defaults               list default devices (default command)
  set-default            set default device by ID
  list                   list available devices
  list-short             list available devices (short form)
  list-cards             list available cards
  list-cards-short       list available cards (short form)
  get-volume             get volume for device
  set-volume VALUE       set volume for device
  get-balance            get balance for device
  set-balance VALUE      set balance for device
  adj-balance VALUE      increase or decrease balance for device
  increase VALUE         increase volume
  decrease VALUE         decrease volume
  mute                   mute device
  unmute                 unmute device
  toggle                 toggle mute
  is-muted               check if muted
Application Commands:
  move DEVICE            move target device to DEVICE
  kill DEVICE            kill target DEVICE
Card Commands:
  list-profiles          list available profiles for a card
  list-profiles-short    list available profiles for a card(short form)
  get-profile            get active profile for card
  set-profile PROFILE    set profile for a card
share|improve this answer
add comment

On my laptop running Fedora 20, HDMI output is not listed as a sink in the default profile, but as a different profile itself.

I have only 1 sink like this, nice music playing on my laptop speakers:

$ pactl list short sinks
8   alsa_output.pci-0000_00_1b.0.analog-stereo  module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

If I run pactl set-card-profile 0 output:hdmi-stereo then nice music is playing through HDMI. I get:

$ pactl list short sinks
14  alsa_output.pci-0000_00_1b.0.hdmi-stereo    module-alsa-card.c  s16le 2ch 44100Hz   RUNNING

To get back to default I just run pactl set-card-profile 0 output:analog-stereo+input:analog-stereo. Either way the default is there again if I reboot.

The list of profiles for my card is somewhere on pactl list cards output.

share|improve this answer
    
This info was already provided by the accepted answer. Please don't copy other user's answers unless you have something more to add. This just rehashes the other answer and provided nothing new or useful! –  slm Dec 28 '13 at 1:14
    
set-card-profile wasn't mentioned previously, and that's the most important info on this answer. –  Spidey Mar 2 at 15:03
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.