Ubuntu – How to get the right Pulseaudio profiles to show up without restarting Pulseaudio

microphonepulseaudiosoundusb

Some times my USB headset microphone disappears from my list of input devices. Reconnecting the headset doesn't work, but killing Pulseaudio does:

pulseaudio -k

When Pulseaudio starts back up, my USB headset shows up both under input and output devices and works fine.

The problem is that killing Pulseaudio also crashes all applications using it, or leaves them without sound. This means that I have to restart Skype, Steam, XChat, any running video player (SMPlayer crashes), any running games etc.

Is there a way to force reload all devices without killing the running instance of Pulseaudio?


Interestingly, when I get my USB headset to work by restarting Pulseaudio, reconnecting the headset will cause only the output device to show up. I have to restart Pulseaudio again with the headset connected to get the input device to show up.


Edit: Checked pavuvontrol under "Configuration":

Screenshot

After restarting Pulseaudio, an additional profile ending with "+ Digital Stereo Input" (or something like that) is available in the list and selected by default.

Best Answer

I've been suffering with the same issue for a while, and had finally a chance to look at it. It turns out that unloading and reloading the Pulseaudio module responsible for the audio device works for me.

Unloading and reloading the module, by hand

In terminal window, enter command

pacmd list-cards

and from the output, find the audio device that is missing profiles. You will probably get several cards, and need to locate the right one. Mine looks like this:

[...]
index: 8
    name: <alsa_card.usb-Logitech_Logitech_USB_Headset-00-Headset>
    driver: <module-alsa-card.c>
    owner module: 27
    properties:
            alsa.card = "1"
            alsa.card_name = "Logitech USB Headset"
            [... more output ...]
[...]

From your output, look up the line "owner module". That is the module you need to unload, but you will need to look at it's parameters first, so you can reload it. Enter command

pacmd list-modules

and locate the module driving your card. Again, the relevant part of the output in my case looks like this (index matches owner module from output of pacmd list-cards):

[...]
index: 27
    name: <module-alsa-card>
    argument: <device_id="1" name="usb-Logitech_Logitech_USB_Headset-00-Headset" card_name="alsa_card.usb-Logitech_Logitech_USB_Headset-00-Headset" namereg_fail=false tsched=yes fixed_latency_range=no ignore_dB=no deferred_volume=yes use_ucm=yes card_properties="module-udev-detect.discovered=1">
    used: 2
    load once: no
    properties:
    [... more output ...]
[...]

You will need the module name and arguments to reload it.

To unload the module, enter command (replace module-index with appropriate value from your output)

pacmd unload-module module-index

To reload the module after it's unloaded, enter command

pacmd load-module module-name module-arguments

Replace module-name and module-arguments with values from output of pacmd list-modules. Leave out the angle brackets.

Now the module should be reloaded, and with some luck your headset profiles are back.

Applying automation

The above steps are a lot of work if you need to reset your device often, as the module index keeps changing and you need to look it up every time. I wrote a shell script for myself to automate the worst of it:

#!/bin/bash

if [ -z "$1" ]; then
  echo "Pulseaudio has these cards:"
  pacmd list-cards | grep 'name: '
  exit 0
fi

MODULE_INDEX=`pacmd list-modules | tac | grep -A 10 -e "argument: .*$1" | grep 'index:' | head -n 1 | cut -d ':' -f 2 | tr -d ' '`
MODULE_NAME=`pacmd list-modules | tac | grep -A 10 -e "argument: .*$1" | grep 'name:' | head -n 1 | cut -d ':' -f 2 | tr -d '<>'`
MODULE_ARGUMENTS=`pacmd list-modules | tac | grep -e "argument: .*$1" | head -n 1 | cut -d ':' -f 2 | tr -d '<>'`
echo "Module index is $MODULE_INDEX"
echo "Module name: $MODULE_NAME"
echo "Module args: $MODULE_ARGUMENTS"

if [ -z "$MODULE_INDEX" ]; then echo "Could not find module index"; exit 0; fi
if [ -z "$MODULE_NAME" ]; then echo "Could not find module name"; exit 0; fi
if [ -z "$MODULE_ARGUMENTS" ]; then echo "Could not find module arguments"; exit 0; fi

echo "Unloading module"
pacmd unload-module $MODULE_INDEX
echo ""
echo "Reloading module"
pacmd load-module $MODULE_NAME $MODULE_ARGUMENTS
echo ""

When run without arguments, the script lists the cards Pulseaudio knows of. When a part of a card's name is given as argument, the script attempts to unload and reload the relevant Pulseaudio module.

Related Question