I’ve been using Pulseaudio to easily switch audio output between my digital amplifier and analog headphones (this prevents my headphones from blaring when I’m not actually wearing them). Recent updates to Pulseaudio required a number of changes in my configuration. At this point, I’m not even sure I could use the digital and analog outputs without going through this process. The process is not incredibly complex, but requires the use of new utilities and a bit of experimentation.
I previously used ALSA dmix to switch between multiple audio outputs (ALSA instructions), but most of the distributions now use Pulseaudio. There have clearly been a lot of bugs and incompatibilities during the transition. One of the most popular posts on the Gentoo user forums was instructions for disabling Pulseaudio. I think this trouble has settled down over the last year or so. It now works very well for me.
Instead of the old Creative Labs Soundblaster Live, I’ve now transitioned to the very excellent ASUS Xonar DG PCI 5.1 Channel Sound Card.
I won’t cover the full setup of Pulseaudio here – there are plenty of resources for that. Some may find my ~/.asoundrc
file useful:
pcm.pulse { type pulse } ctl.pulse { type pulse } pcm.!default { type pulse } ctl.!default { type pulse }
With this in place, you need to configure Pulseaudio to send output to the correct device. For this, use the pacmd
utility. It provides an interactive shell for querying and modifying audio settings. I’ve provided full outputs from my audio card at the end of the post. These pacmd
commands are likely to be the ones you’ll need:
list-cards list-sinks set-card-profile set-sink-port
It’s worth mentioning that I originally used sink indices instead of the names of the sinks. This worked fine for a while, until I needed to change Pulseaudio profiles. When the profile changes, the sink indices are auto-incremented. It’s much safer to use a name rather than an index (e.g. alsa_output.pci-0000_02_05.0.analog-stereo
).
The script to switch output to digital (to my amplifier):
#!/bin/sh /usr/bin/pacmd set-card-profile alsa_card.pci-0000_02_05.0 output:iec958-stereo+input:iec958-stereo echo
To re-configure Pulseaudio for audio out (to my headphones):
#!/bin/sh /usr/bin/pacmd set-card-profile alsa_card.pci-0000_02_05.0 output:analog-stereo /usr/bin/pacmd set-sink-port alsa_output.pci-0000_02_05.0.analog-stereo analog-output\;output-headphones-2 echo
Full Pulseaudio Configuration Output
lspci -vvv -s 02:05.0
02:05.0 Multimedia audio controller: C-Media Electronics Inc CMI8788 [Oxygen HD Audio] Subsystem: ASUSTeK Computer Inc. CMI8786 (Xonar DG) Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx- Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx- Latency: 64 (500ns min, 6000ns max) Interrupt: pin A routed to IRQ 20 Region 0: I/O ports at e800 [size=256] Capabilities: [c0] Power Management version 2 Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-) Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME- Kernel driver in use: snd_oxygen Kernel modules: snd-oxygen
pacmd help
>>> Available commands: help Show this help list-modules List loaded modules list-cards List cards list-sinks List loaded sinks list-sources List loaded sources list-clients List loaded clients list-sink-inputs List sink inputs list-source-outputs List source outputs stat Show memory block statistics info Show comprehensive status load-module Load a module (args: name, arguments) unload-module Unload a module (args: index) describe-module Describe a module (arg: name) set-sink-volume Set the volume of a sink (args: index|name, volume) set-source-volume Set the volume of a source (args: index|name, volume) set-sink-mute Set the mute switch of a sink (args: index|name, bool) set-source-mute Set the mute switch of a source (args: index|name, bool) set-sink-input-volume Set the volume of a sink input (args: index, volume) set-source-output-volume Set the volume of a source output (args: index, volume) set-sink-input-mute Set the mute switch of a sink input (args: index, bool) set-source-output-mute Set the mute switch of a source output (args: index, bool) set-default-sink Set the default sink (args: index|name) set-default-source Set the default source (args: index|name) set-card-profile Change the profile of a card (args: index|name, profile-name) set-sink-port Change the port of a sink (args: index|name, port-name) set-source-port Change the port of a source (args: index|name, port-name) suspend-sink Suspend sink (args: index|name, bool) suspend-source Suspend source (args: index|name, bool) suspend Suspend all sinks and all sources (args: bool) move-sink-input Move sink input to another sink (args: index, sink) move-source-output Move source output to another source (args: index, source) update-sink-proplist Update the properties of a sink (args: index|name, properties) update-source-proplist Update the properties of a source (args: index|name, properties) update-sink-input-proplist Update the properties of a sink input (args: index, properties) update-source-output-proplist Update the properties of a source output (args: index, properties) list-samples List all entries in the sample cache play-sample Play a sample from the sample cache (args: name, sink|index) remove-sample Remove a sample from the sample cache (args: name) load-sample Load a sound file into the sample cache (args: name, filename) load-sample-lazy Lazily load a sound file into the sample cache (args: name, filename) load-sample-dir-lazy Lazily load all files in a directory into the sample cache (args: pathname) kill-client Kill a client (args: index) kill-sink-input Kill a sink input (args: index) kill-source-output Kill a source output (args: index) set-log-level Change the log level (args: numeric level) set-log-meta Show source code location in log messages (args: bool) set-log-time Show timestamps in log messages (args: bool) set-log-backtrace Show backtrace in log messages (args: frames) play-file Play a sound file (args: filename, sink|index) dump Dump daemon configuration dump-volumes Debug: Show the state of all volumes shared Debug: Show shared properties exit Terminate the daemon
pacmd list-cards
>>> 1 card(s) available. index: 0 name: <alsa_card.pci-0000_02_05.0> driver: <module-alsa-card.c> owner module: 4 properties: alsa.card = "0" alsa.card_name = "Xonar DG" alsa.long_card_name = "C-Media Oxygen HD Audio at 0xe800, irq 20" alsa.driver_name = "snd_oxygen" device.bus_path = "pci-0000:02:05.0" sysfs.path = "/devices/pci0000:00/0000:00:14.4/0000:02:05.0/sound/card0" device.bus = "pci" device.vendor.id = "13f6" device.vendor.name = "C-Media Electronics Inc" device.product.id = "8788" device.product.name = "CMI8788 [Oxygen HD Audio]" device.string = "0" device.description = "CMI8788 [Oxygen HD Audio]" module-udev-detect.discovered = "1" device.icon_name = "audio-card-pci" profiles: output:analog-stereo: Analog Stereo Output (priority 6000) output:analog-stereo+input:analog-stereo: Analog Stereo Duplex (priority 6060) output:analog-stereo+input:iec958-stereo: Analog Stereo Output + Digital Stereo (IEC958) Input (priority 6055) output:analog-surround-40: Analog Surround 4.0 Output (priority 700) output:analog-surround-40+input:analog-stereo: Analog Surround 4.0 Output + Analog Stereo Input (priority 760) output:analog-surround-40+input:iec958-stereo: Analog Surround 4.0 Output + Digital Stereo (IEC958) Input (priority 755) output:analog-surround-41: Analog Surround 4.1 Output (priority 800) output:analog-surround-41+input:analog-stereo: Analog Surround 4.1 Output + Analog Stereo Input (priority 860) output:analog-surround-41+input:iec958-stereo: Analog Surround 4.1 Output + Digital Stereo (IEC958) Input (priority 855) output:analog-surround-50: Analog Surround 5.0 Output (priority 700) output:analog-surround-50+input:analog-stereo: Analog Surround 5.0 Output + Analog Stereo Input (priority 760) output:analog-surround-50+input:iec958-stereo: Analog Surround 5.0 Output + Digital Stereo (IEC958) Input (priority 755) output:analog-surround-51: Analog Surround 5.1 Output (priority 800) output:analog-surround-51+input:analog-stereo: Analog Surround 5.1 Output + Analog Stereo Input (priority 860) output:analog-surround-51+input:iec958-stereo: Analog Surround 5.1 Output + Digital Stereo (IEC958) Input (priority 855) output:iec958-stereo: Digital Stereo (IEC958) Output (priority 5500) output:iec958-stereo+input:analog-stereo: Digital Stereo (IEC958) Output + Analog Stereo Input (priority 5560) output:iec958-stereo+input:iec958-stereo: Digital Stereo Duplex (IEC958) (priority 5555) input:analog-stereo: Analog Stereo Input (priority 60) input:iec958-stereo: Digital Stereo (IEC958) Input (priority 55) off: Off (priority 0) active profile: <output:iec958-stereo+input:iec958-stereo> sinks: alsa_output.pci-0000_02_05.0.iec958-stereo/#18: CMI8788 [Oxygen HD Audio] Digital Stereo (IEC958) sources: alsa_output.pci-0000_02_05.0.iec958-stereo.monitor/#22: Monitor of CMI8788 [Oxygen HD Audio] Digital Stereo (IEC958) alsa_input.pci-0000_02_05.0.iec958-stereo/#23: CMI8788 [Oxygen HD Audio] Digital Stereo (IEC958) ports: analog-output;output-speaker: Analog Output / Speaker (priority 9910, available: unknown) properties: analog-output;output-headphones-1: Analog Output / Headphones 1 (priority 9909, available: unknown) properties: analog-output;output-headphones-2: Analog Output / Headphones 2 (priority 9908, available: unknown) properties: analog-input-microphone-front: Front Microphone (priority 8500, available: unknown) properties: analog-input-microphone: Microphone (priority 8700, available: unknown) properties: analog-input-linein: Line In (priority 8100, available: unknown) properties: analog-input: Analog Input (priority 8000, available: unknown) properties: iec958-stereo-input: iec958-stereo-input (priority 0, available: unknown) properties: iec958-stereo-output: Digital Output (S/PDIF) (priority 0, available: unknown) properties:
pacmd set-card-profile alsa_card.pci-0000_02_05.0 output:analog-stereo
pacmd list-sinks
>>> 1 sink(s) available. index: 20 name: <alsa_output.pci-0000_02_05.0.analog-stereo> driver: <module-alsa-card.c> flags: HARDWARE DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY state: SUSPENDED suspend cause: IDLE priority: 9059 volume: 0: 65% 1: 65% 0: -11.22 dB 1: -11.22 dB balance 0.00 base volume: 100% 0.00 dB volume steps: 65537 muted: no current latency: 0.00 ms max request: 0 KiB max rewind: 0 KiB monitor source: 25 sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo used by: 0 linked by: 2 configured latency: 0.00 ms; range is 0.50 .. 2000.00 ms card: 0 <alsa_card.pci-0000_02_05.0> module: 4 properties: alsa.resolution_bits = "16" device.api = "alsa" device.class = "sound" alsa.class = "generic" alsa.subclass = "generic-mix" alsa.name = "Multichannel" alsa.id = "Multichannel" alsa.subdevice = "0" alsa.subdevice_name = "subdevice #0" alsa.device = "0" alsa.card = "0" alsa.card_name = "Xonar DG" alsa.long_card_name = "C-Media Oxygen HD Audio at 0xe800, irq 20" alsa.driver_name = "snd_oxygen" device.bus_path = "pci-0000:02:05.0" sysfs.path = "/devices/pci0000:00/0000:00:14.4/0000:02:05.0/sound/card0" device.bus = "pci" device.vendor.id = "13f6" device.vendor.name = "C-Media Electronics Inc" device.product.id = "8788" device.product.name = "CMI8788 [Oxygen HD Audio]" device.string = "front:0" device.buffering.buffer_size = "352800" device.buffering.fragment_size = "352800" device.access_mode = "mmap+timer" device.profile.name = "analog-stereo" device.profile.description = "Analog Stereo" device.description = "CMI8788 [Oxygen HD Audio] Analog Stereo" alsa.mixer_name = "CMI8786" alsa.components = "CS4245 CMI8786" module-udev-detect.discovered = "1" device.icon_name = "audio-card-pci" ports: analog-output;output-speaker: Analog Output / Speaker (priority 9910, available: unknown) properties: analog-output;output-headphones-1: Analog Output / Headphones 1 (priority 9909, available: unknown) properties: analog-output;output-headphones-2: Analog Output / Headphones 2 (priority 9908, available: unknown) properties: active port: <analog-output;output-headphones-2>
pacmd set-card-profile alsa_card.pci-0000_02_05.0 output:iec958-stereo+input:iec958-stereo
pacmd list-sinks
>>> 1 sink(s) available. index: 22 name: <alsa_output.pci-0000_02_05.0.iec958-stereo> driver: <module-alsa-card.c> flags: HARDWARE HW_MUTE_CTRL DECIBEL_VOLUME LATENCY FLAT_VOLUME DYNAMIC_LATENCY state: SUSPENDED suspend cause: IDLE priority: 9058 volume: 0: 100% 1: 100% 0: 0.00 dB 1: 0.00 dB balance 0.00 base volume: 100% 0.00 dB volume steps: 65537 muted: yes current latency: 0.00 ms max request: 0 KiB max rewind: 0 KiB monitor source: 27 sample spec: s16le 2ch 44100Hz channel map: front-left,front-right Stereo used by: 0 linked by: 2 configured latency: 0.00 ms; range is 0.50 .. 743.04 ms card: 0 <alsa_card.pci-0000_02_05.0> module: 4 properties: alsa.resolution_bits = "16" device.api = "alsa" device.class = "sound" alsa.class = "generic" alsa.subclass = "generic-mix" alsa.name = "Digital" alsa.id = "Digital" alsa.subdevice = "0" alsa.subdevice_name = "subdevice #0" alsa.device = "1" alsa.card = "0" alsa.card_name = "Xonar DG" alsa.long_card_name = "C-Media Oxygen HD Audio at 0xe800, irq 20" alsa.driver_name = "snd_oxygen" device.bus_path = "pci-0000:02:05.0" sysfs.path = "/devices/pci0000:00/0000:00:14.4/0000:02:05.0/sound/card0" device.bus = "pci" device.vendor.id = "13f6" device.vendor.name = "C-Media Electronics Inc" device.product.id = "8788" device.product.name = "CMI8788 [Oxygen HD Audio]" device.string = "iec958:0" device.buffering.buffer_size = "131072" device.buffering.fragment_size = "131072" device.access_mode = "mmap+timer" device.profile.name = "iec958-stereo" device.profile.description = "Digital Stereo (IEC958)" device.description = "CMI8788 [Oxygen HD Audio] Digital Stereo (IEC958)" alsa.mixer_name = "CMI8786" alsa.components = "CS4245 CMI8786" module-udev-detect.discovered = "1" device.icon_name = "audio-card-pci" ports: iec958-stereo-output: Digital Output (S/PDIF) (priority 0, available: unknown) properties: active port: <iec958-stereo-output>