Dec 272012
 

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>

 Leave a Reply

(to be displayed above your comment)

(for moderation; your e-mail address will not be made public)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>