A webcomic of roma...
Hey, wait a second!

Intel HDA & Surround Sound

To be honest, much like the AC97, I find the Intel HDA Audio to be absolute crap. I would run my Audigy, but for some reason playing with this seemed like a good idea. The first trip up right after that would be it wasn't doing surround sound. The quick google fix was to add some options to the modprobe. Hey presto that made it work!

options snd-hda-intel model=3stack-6ch


And it continued to more or less work until I upgraded to kernel 2.6.34. This is where things got weird. Mplayer stopped recognizing the alsa device surround51 on which it depended for playing the surround sound. (There's some sort of autodetect switch.)

[AO_ALSA] Unable to get sw-parameters: Invalid argument

But "speaker-test -c 6 -D surround51 -t wav" still worked correctly! All 6 channels were playing out of the correct speakers. Some googling found this post on the Arch Linux forums. Cdh there suggests that using the dmix plugin of alsa can fix things, and to a certain extent it can. The problem I had with it was that if anything else 2 channel was playing, 5.1 wouldn't work and vice-versa.

I was also experiencing stuttering with Herrie when playing music and in some 5.1 audio files. Going back to the ALSA dmix page led me to the trick of setting the sample rate back down to 44100 Hz and adding in period/buffer arguments.

But this still didn't fix the 2/5.1 channel problem. I could play more than one on each, 2 x 2 channel or 2 x 5.1 channel. Enter an Ubuntu Forums post on "Stereo music and 5.1 surround on 5.1 speakers" combined with the ALSA asoundrc page let me alter my .asoundrc file so that everything now seems to work.


How the file works now is the default and surround51 sound devices are overridden by new devices that take the sound and pass it forward to the dmix 6 channel device. By overriding the devices (the !) instead of creating new ones I don't have to reconfigure everything. The upmixing isn't identical to what alsa does by itself (it's louder) but it seems to work.

pcm.!default {
    type route
    slave.pcm duplex
    slave.channels 6
    ttable.0.0 0.33
    ttable.1.1 0.33
    ttable.0.2 0.5
    ttable.1.3 0.5
    ttable.0.4 0.17
    ttable.1.4 0.17
    ttable.0.5 0.5
    ttable.1.5 0.5

pcm.snd_card {
     type hw
     card 0 # change to your cards number or name

pcm.!surround51 {
    type plug
    slave.pcm duplex

# 6 channel dmix:
pcm.dmix6 {
     type dmix
        ipc_key 1024
        ipc_key_add_uid false # let multiple users share
        ipc_perm 0660 # IPC permissions (octal, default 0600)
        slave {
                pcm snd_card # see below
                rate 44100
                channels 6
		period_time 0
		period_size 1024
		buffer_time 0
		buffer_size 4096


pcm.duplex {
     type asym
     playback.pcm "dmix6"  # just pass to 6 channel dmix
     capture.pcm "snd_card"