May 092012

Here’s my notes on getting simple sound output working under FreeBSD.

Kernel module
To get sound working you need to have the proper kernel module loaded for your sound card, which means first figuring out what kind of sound card you have, then finding the appropriate module to have loaded.

To see what kind of sound card the kernel saw at boot up, use the dmesg command:

$ dmesg | grep pcm
pcm0: <HDA ATI R6xx HDMI PCM #0 HDMI> at cad 0 nid 1 on hdac0
pcm1: <HDA Realtek ALC888 PCM #0 Analog> at cad 2 nid 1 on hdac1
pcm2: <HDA Realtek ALC888 PCM #1 Digital> at cad 2 nid 1 on hdac1

Or to see which one is already loaded look at the /dev/sndstat device:

$ cat /dev/sndstat 
FreeBSD Audio Driver (newpcm: 64bit 2009061500/amd64)
Installed devices:
pcm0: <HDA ATI R6xx HDMI PCM #0 HDMI> (play)
pcm1: <HDA Realtek ALC888 PCM #0 Analog> (play/rec) default
pcm2: <HDA Realtek ALC888 PCM #1 Digital> (play)

So I want the hda driver. (This output also shows that I have multiple sound devices, see below for dealing with those.)

An alternative, brute force, way of finding a sound driver would be to load all of them:

# cd /boot/kernel
# kldload snd_*

and the looking to see what stuck, using either of the following:

$ kldstat | grep snd_
$ cat /dev/sndstat

Once you know what kind of sound card you have, look in /boot/default/loader.conf and search for the line that loads the module specific to your sound card. Add that to your /boot/loader.conf

# emacs /boot/default/loader.conf /boot/loader.conf
# grep snd_ /boot/loader.conf
snd_hda_load="YES"              # Intel High Definition Audio (Controller)

Test the sound card

Loading the driver will (in FreeBSD 5.x or later) usually create the /dev/dsp sound device entry for you. If it exists, then try to send some noise to it:

# cat ~/.profile > /dev/dsp

If this works, then you’re done. All sound aware apps should pick this up and use it for sound.

Creating /dev/dsp sound device

In the case that the /dev/dsp device does not get created automatically after a reboot, as was my case because I have multiple sound cards, (one on the main board, one on the video card) try the following:

Figure out which of the existing /dev/dsp* devices to use. I ran the following loop:

# for d in /dev/dsp*; do echo $d; cat ~/.profile > $d; sleep 1; done

6 times, with the speakers plugged into each of the 6 different ports in the back of the machine. Eventually I figured out it was /dev/dsp1.0 and the lower middle yellow port.

To put that info into place, I ran:

# sysctl hw.snd.default_unit=1

Surprisingly, a /dev/dsp was not created, but Skype started making sounds at me, so it worked!

To make that permanent I added the following to /etc/sysctl.conf

# to make /dev/dsp point to /dev/dsp1.0

After the next reboot, the /dev/dsp device was there and sound still worked.