The One with the Thoughts of Frans

Dolby Digital 5.1 Over S/PDIF With PulseAudio

This post is from 2011 and relates to Debian Squeeze. I put up a newer post in 2013 when Debian Wheezy was released.


This post describes how I got Dolby Digital 5.1 output working over S/PDIF on my onboard Realtek chip with other audio sources mixed in. Previously I was only able to achieve either 5.1 output by sending the data stream straight to my receiver, or 2.0 output with everything mixed in. The experiences detailed in this post originate in Debian Squeeze, but if what I wrote is specific to anything, it should be my hardware — not Debian and its derivatives. Before you read on, you might want to check out this forum post instead, which describes a method that didn’t work out for me.

PulseAudio 0.9.22 is required; it won’t work on older versions of PulseAudio. Debian Squeeze comes with ALSA 1.0.23; presumably that’s much less significant. On Debian getting this most recent PulseAudio can be done through the experimental repository.

If you’re on Debian ALSA is already setup, including the required libasound2-plugins, but to get the most recent version of PulseAudio you’ll want to add deb http://ftp.debian.org/debian experimental main to /etc/apt/sources.list, and then type apt-get update && apt-get -t experimental install pulseaudio in a superuser terminal (see the Debian Wiki for more information on the experimental repository). On many other distributions PulseAudio is already setup by default, but just like on Debian Squeeze that’s typically still PulseAudio 0.9.21 at present.

On Ubuntu you’d have to recompile libasound2-plugins yourself because it doesn’t include the a52 ALSA plugin by default. The link in the opening paragraph should describe that process sufficiently.

In the System Log Viewer you can keep an eye on syslog for (error) messages from ALSA as well as PulseAudio.

What follows is my /etc/asound.conf, heavily condensed from Johannes Bauer’s Dolby Digital with Linux and ALSA guide. It works quite nicely (with some minor adjustments), but it will only allow one application to utilize audio at a time. One could utilize PulseAudio for stereo while suspending it (with pasuspender) when you want to play a movie or some such with 5.1 audio, but I’d rather mix everything together in PulseAudio so I don’t have to think about it after the initial setup, just like in Windows.

pcm.a52 {
        @args [CARD]
        @args.CARD {
                type string
        }
        type rate
        slave {
                pcm {   
                        type a52
                        card $CARD
                }
                rate 48000 #required somehow, otherwise nothing happens in PulseAudio
        }
}
pcm.pulse {
        type pulse
}
ctl.pulse {
        type pulse
}
pcm.!default {
        type pulse
}
ctl.!default {
        type pulse
}

Now that you’ve got the ALSA configuration in order it’s time to make some slight adjustments to /etc/pulse/default.pa or PA won’t detect the possibility for Digital Surround 5.1. According to various sources they had some kind of Digital Surround show up automatically, but I had to explicitly tell PulseAudio about its existence. Adjusted from a comment on Ubuntu bug 348353 (which incidentally is why you need PulseAudio 0.9.22).

load-module module-alsa-sink device=a52 rate=48000 channels=6 tsched=0 sink_properties=device.description=SPDIF sink_name=SPDIF channel_map=front-left,front-right,rear-left,rear-right,front-center,lfe

I initially added this line without the channel_map, but then PulseAudio thought I had something like front-left,front-left-of-center,front-center,front-right-of-center,front-right,lfe, which would be a strange setup indeed.

I’m not quite sure whether the channel map might be more appropriate in /etc/pulse/daemon.conf, where I uncommented default-sample-rate = 48000. I also added the appropriate settings for default-sample-channels = 6 and changed enable-lfe-remixing to yes.

pavucontrol is instrumental in quickly seeing what’s going on and for application-specific volume settings. Not utilizing it would be a disservice for yourself if you’ve chosen to use PulseAudio.

Now that we’ve got all the configuration set up you could reboot the computer, but one of the great things about Linux is that you rarely have to do that other than to load a different kernel.

As user: pulseaudio --kill
As superuser/sudo: /etc/init.d/alsa-utils restart
(As user: pulseaudio -D, but that shouldn’t be necessary)

I utilized the surround test ac3 file from Lynne Music (straight to directory). I played it with mplayer -channels 6 to make sure everything was working correctly and to adjust the channel map. At this point everything was finally working fine for me, but most applications still were not cooperating because they defaulted to ALSA. Again, in Ubuntu this shouldn’t be an issue.

Various adjustments are still required in most applications. For instance, in Totem you have to explicitly set audio output to 5.1 in Edit > Preferences > Audio.
For MPlayer put channels=6 in ~/.mplayer/config (note that if you can’t get PulseAudio to work you could add the equivalents of mplayer -ao alsa:device=spdif -srate 48000 -ac hwac3 file.avi if you so desire).
VLC works fine if Dolby Surround is set to Auto in Tools > Preferences > Audio.

To get the 6 channel output to work in applications that use SDL (Gnash, quite a few games) you’ll need libsdl1.2debian-pulseaudio. This will replace libsdl1.2debian-alsa. Of course this won’t be necessary if your distro is set up with PA by default.

On a separate note, I set PulseAudio up so it can play audio from all kinds of sources (most notably my laptop).

7 Comments

  1. By default PA (PulseAudio) keeps releasing the sound card every time an application quits playing. This results in two problems: due to the nature of the connection it takes a fraction of a second for audio to start playing, because my receiver has to realize what the specific incoming signal consists of, so it can switch to the appropriate decoding mechanism. For e.g. Pidgin notifications (if they are enabled) this has the peculiar effect that only the final ⅔ or so of the notification sound is actually played back on the speakers. More important, sometimes there’s a strange, loud noise when PA releases the sound card. I don’t know if this is related to my sound card or to PA, but suffice it to say it’s not pleasant. Sometimes this also occurs while VLC is switching between two files on a playlist, because it actually stops playing for a split second. This may result in the noise and sometimes some slight crackling during the first couple of seconds of playback of the next file. Luckily, it’s easy to fix.

    In /etc/pulse/default.pa, find the lines that say:

    ### Automatically suspend sinks/sources that become idle for too long
    load-module module-suspend-on-idle

    Comment them out, that is, change it to the following:

    ### Automatically suspend sinks/sources that become idle for too long
    #load-module module-suspend-on-idle

    Now PA won’t release its grip on the sound card as soon as an application stops playing and no strange noises occur.

    This has the added advantage of blocking any applications that aren’t configured for using PA from locking onto the sound card. If you have an application that can’t play audio you can thus be sure that you’ll have to fix its configuration, start it with padsp, or some such.

    May 21, 2011 @ 13:11Permalink
    Frans

  2. […] have gotten significantly easier than they were a couple of years ago thanks primarily to improvements in […]

    July 3, 2013 @ 13:12Permalink
    Dolby Digital 5.1 over SP/DIF with PulseAudio in Debian Wheezy | The One with the Thoughts of Frans

  3. How can I create an a52 output for only the iec958/spdif device?

    I’ve tried about a thousand different things, and I’ve been over and over this short and not quite comprehensible document, but I cannot for the life of me figure out what this “@args” actually does other than magically make a52 devices for every soundcard attached to my system.

    I’m trying to remove this code and have a52 for ONLY the iec958/spdif device because I have several other audio devices for which it is innapropriate (nvidia hdmi, ivtv, etc.), and possibly getting in the way of other custom configurations I want to try.

    I don’t understand how this can possibly work, because CARD is never actually specified to anything, but it does make a52 outputs for all soundcards (just like your code above; the only difference is that I’ve removed the “card $CARD” line):

    pcm.a52 {
      @args [CARD]
      @args.CARD {
        type string
      }
      type rate
      slave {
        pcm {
          type a52
        }
        rate 48000 #I think it has to do with half and full duplex
      }
    }

    At first I tried replacing $CARD with every conceivable means of identifying the proper soundcard (hw:0,1) and even a few nonsense things. I found out this line is completely ignored. However, removing the @args section causes a52 devices not to be created for anything, even specifying a default as in the documentation is ignored…. why?

    August 19, 2013 @ 19:15Permalink
    quequotion

  4. I don’t understand how this can possibly work,

    …after two reboots, it stopped working.

    The “card $CARD” line is necessary.

    Do you know what kind of values are in $CARD?

    I’ve tried every possible way that alsa refers to cards in it’s documentation, but nothing works. This line must be present, but the value of $CARD is a complete mystery to me. It works just as well as “card ALF-eats-CATS”

    August 20, 2013 @ 4:24Permalink
    quequotion

  5. And then, out of nowhere, Alsa reordered all my audio devices and now a52 can’t be detected by certain programs, notably Mixxx…..

    August 20, 2013 @ 6:16Permalink
    quequotion

  6. …after two reboots, it stopped working.

    And then, out of nowhere, Alsa reordered all my audio devices

    Aha… here’s a neat one, a change I made to /etc/bluetooth/audio.conf was responsible for all that strangeness:

    Disable = Media

    Apparently this bluetooth configuration option has far-reaching influence.

    August 20, 2013 @ 6:25Permalink
    quequotion

  7. I didn’t realize Bluetooth could have such results. I’m glad it’s working for you now. Unfortunately it’s been over two years, but I think I managed to get most of my personal process written down in the blog post above. Like you, I found the docs mystifying, which is why most of my limited understanding was actually based on the examples written down by Johannes Bauer. The bulk of my effort didn’t relate to getting ALSA to output 5.1 correctly, which was simple using Johannes Bauer’s examples, but to making PulseAudio recognize the option was there.

    Note that PulseAudio improved quite a lot since.

    Do you know what kind of values are in $CARD?

    I believe it’s simply an integer. In my case I should be able to use 0 instead.

    $ cat /proc/asound/cards
     0 [Intel          ]: HDA-Intel - HDA Intel
                          HDA Intel at 0xfdff8000 irq 48
     1 [Q9000          ]: USB-Audio - QuickCam Pro 9000
                          Logitech, Inc. QuickCam Pro 9000 at usb-0000:00:1d.7-3, high speed
    

    August 20, 2013 @ 10:10Permalink
    Frans

RSS feed for comments on this post· TrackBack URI

Leave a Comment

You must be logged in to post a comment.