Can You Hear Me Now? - Sound on FreeBSD

April 17, 2025

Introduction

FreeBSD uses the Open Source Sound (OSS) system in the base install. This techbits article will show you how to set up and use OSS on FreeBSD.

First, let’s clear up some terminology. The Advanced Linux Sound Architecture (ALSA) performs the same role in Linux systems as the OSS system does in FreeBSD. Other products like Pulse Audio, and the JACK subsystem, are essentially sound servers. They provide sound distribution, filtering, and other services to local and remote applications. However, they are not required to use sound on FreeBSD.

Note however, that some applciations expect Pulse to be installed and working. Pulse is actually a sound server, not a sound driver. It’s usually a layer on top of OSS. So you have to get OSS working first before futzing around with Pulse.

If you’ve previously loaded a bunch of packages, Pulse audio may already be installed as a dependency. In my case, I don’t need it and I deliberately disabled it.

[jpb@jpblt:~]$ service pulseaudio stop
[jpb@jpblt:~]$ pulseaudio -k
[jpb@jpblt:~]$ pkg delete pulseaudio   # optional

This article focuses solely on OSS on FreeBSD.

Overview

The FreeBSD kernel probes all hardware in the system when booting up, noting whatever it finds in bolded output. In modern PCs and laptops, sound is usually provided through a sound chip such as the Realtek ALC257 High Definition Audio Controller (hdac).

If you can’t read fast enough, login at the prompt and run dmesg(8) to examine the kernel boot output.

Look for the sound chip(s) identified by the kernel.

[jpb@jpblt:~/]$ dmesg | grep hda
hdac0: <NVIDIA (0x22bd) HDA Controller> mem 0x83000000-0x83003fff at device 0.1 on pci1
hdac1: <Intel (0x7a50) HDA Controller> mem 0x4204130000-0x4204133fff,0x4204000000-0x42040fffff at device 31.3 on pci0
hdacc0: <NVIDIA (0x00a6) HDA CODEC> at cad 0 on hdac0
hdaa0: <NVIDIA (0x00a6) Audio Function Group> at nid 1 on hdacc0
pcm0: <NVIDIA (0x00a6) (HDMI/DP 8ch)> at nid 4 on hdaa0
pcm1: <NVIDIA (0x00a6) (HDMI/DP 8ch)> at nid 6 on hdaa0
pcm2: <NVIDIA (0x00a6) (HDMI/DP 8ch)> at nid 7 on hdaa0
hdacc1: <Realtek ALC257 HDA CODEC> at cad 0 on hdac1
hdaa1: <Realtek ALC257 Audio Function Group> at nid 1 on hdacc1
pcm3: <Realtek ALC257 (Analog 2.0/4ch)> at nid 33 and 18,25 on hdaa1

This output shows that I have an internal NVIDIA gpu on my laptop, but there is no sound associated with that card. The Realtek ALC257 chip is actually the working sound chip on my laptop.

There won’t be any sound without a kernel module to drive that sound and in my case the driver I need is snd_hda(4).

[jpb@jpblt:~]$ sudo kldload snd_hda
kldload: can't load snd_hda: module already loaded or in kernel

In this case my sound driver is already loaded. That’s fine.

I can now view the current configuration by looking at the contents of /dev/sndstat. This shows how the sound system is currently set up. My system looks like this:

[jpb@jpblt:~]$ cat /dev/sndstat
FreeBSD Audio Driver
Installed devices:
pcm0: <NVIDIA (0x00a6) (HDMI/DP 8ch)> on hdaa0 (1p:1v/0r:0v)
pcm1: <NVIDIA (0x00a6) (HDMI/DP 8ch)> on hdaa0 (1p:1v/0r:0v)
pcm2: <NVIDIA (0x00a6) (HDMI/DP 8ch)> on hdaa0 (1p:1v/0r:0v)
pcm3: <Realtek ALC257 (Analog 2.0/4ch)> on hdaa1 (1p:2v/1r:1v) default
No devices installed from userspace.

You can see that pcm3 is set as the “default” unit. Your output will undoubtedly be different.

The default unit in the subsystem can be changed with:

sysctl hw.snd.default_unit=n 

where ’n’ is the number of a pcm entry above.

My laptop shows this at the moment:

[jpb@jpblt:~]$ sysctl hw.snd.default_unit
hw.snd.default_unit: 3

which is correct from the entry shown above.

IMPORTANT NOTE:

The sysctl hw.snd.default_unit is what an application will believe when it starts up. So if you start some audio player or recorder it will use the facility designated by that sysctl. You can change the sysctl while the application is running, but it has no effect on the running application. Any other application you start will use the new value. This is useful if you want to play a movie and also record with voice overlay at the same time.

To set the default unit on startup, just add

hw.snd.default_unit=3

to /etc/sysctl.conf.

Testing Output

A quick way to test for sound is:

cp /dev/urandom  /dev/dsp

You should hear a blast of white noise from your speakers. Just Control-C to stop the noise.

/dev/dsp is like the main output channel that is connected to the default pcm device. If no sound, list all dsp devices and check each one:

[jpb@jpblt:~]$ ls -al /dev/dsp*
crw-rw-rw-  1 root wheel 0x45 Apr 17 10:09 /dev/dsp0
crw-rw-rw-  1 root wheel 0x47 Apr 17 10:09 /dev/dsp1
crw-rw-rw-  1 root wheel 0x49 Apr 17 10:09 /dev/dsp2
crw-rw-rw-  1 root wheel 0x4d Apr 17 13:08 /dev/dsp3

If still no sound, check the mixer levels:

[jpb@jpblt:~]$ mixer
pcm3:mixer: <Realtek ALC257 (Analog 2.0/4ch)> on hdaa1 (play/rec) (default)
    vol       = 1.00:1.00     pbk
    pcm       = 1.00:1.00     pbk
    mic       = 0.67:0.67     rec src
    rec       = 0.37:0.37     pbk
    ogain     = 1.00:1.00     pbk
    monitor   = 0.67:0.67     rec src

And set everything to level 1.0 with the command:

mixer vol=1 pcm=1 mic=1 rec=1 ogain=1 monitor=1

and try again. If your speaker is an external device, check that it is powered on, connected and any volume control is set to maximum.

If still no sound, you may need to fiddle with sound chip associations. See the discussion below in “Headphones Testing”.

Testing Input

For testing input, you’ll need an input source, usually a microphone. Your system should already have an onboard microphone, but some do not. Check any external USB camera you use. Sometimes there is a camera and microphone combination within the device.

If you don’t have one, try to borrow an external USB microphone from a friend.

IMHO, the best application for testing input is audacity(1). You can install it from a FreeBSD package repository.

Audacity can record audio, and shows you a graphical waveform of the audio in real time.

Recording sound with audacity(1)

Recording sound with audacity(1)

Try to record something with audacity. You may need to set the audio device settings and volume levels.

If the waveform is flat, stop recording and adjust the audio device settings in the menu. Audacity will allow you to select a microphone and separately select a speaker. This is useful if there are two different devices to test such as an external microphone internal speaker, or vice-versa.

At this point, just cycle through all known devices using the techniques above until you find the combination that works.

Headphones Testing.

Most people like to have the system cut over to headphones when they are plugged in and cut back to normal audio when the headphones are removed.

If that is not already working for you, there is a complete discussion, with several good examples, in the snd_hda(4) manual page. It’s important to understand the concepts and examples on this page.

To get this working, you first have to reboot and select "Verbose" mode. This will cause the kernel to log a lot of technical information.

Once booted, use:

dmesg > verbose.txt

and examine the output for details about the HDA sound system.

Here is what mine looked like before I started:

hdacc1: <Realtek ALC257 HDA CODEC> at cad 0 on hdac1
hdaa1: <Realtek ALC257 Audio Function Group> at nid 1 on hdacc1
hdaa1: Subsystem ID: 0x17aa3c22
hdaa1: NumGPIO=3 NumGPO=0 NumGPI=0 GPIWake=0 GPIUnsol=1
hdaa1:  GPIO0: disabled
hdaa1:  GPIO1: disabled
hdaa1:  GPIO2: disabled
hdaa1: Original pins configuration:
hdaa1: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa1: 18 90a60140 4  0  Mic           Fixed Digital Internal   Unknown 1
hdaa1: 19 40000000 0  0  Line-out      None  Unknown 0x00       Unknown 0
hdaa1: 20 90170120 2  0  Speaker       Fixed Analog  Internal   Unknown 1
hdaa1: 24 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa1: 25 04a11040 4  0  Mic           Jack  1/8     Right      Black   0
hdaa1: 26 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa1: 27 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa1: 29 4066b905 0  5  Modem-line    None  Digital 0x00       Res.B   9
hdaa1: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1
hdaa1: 33 04211010 1  0  Headphones    Jack  1/8     Right      Black   0
hdaa1: Patching widget caps nid=29 0x00400400 -> 0x00700400
hdaa1: Patched pins configuration:
hdaa1: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa1: 18 90a60140 4  0  Mic           Fixed Digital Internal   Unknown 1
hdaa1: 19 40000000 0  0  Line-out      None  Unknown 0x00       Unknown 0 DISA
hdaa1: 20 90170120 2  0  Speaker       Fixed Analog  Internal   Unknown 1
hdaa1: 24 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 25 04a11040 4  0  Mic           Jack  1/8     Right      Black   0
hdaa1: 26 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 27 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 33 04211010 1  0  Headphones    Jack  1/8     Right      Black   0
hdaa1: hdaa_audio_as_parse: Duplicate pin 0 (25) in association 4! Disabling association.
hdaa1: 3 associations found:
hdaa1: Association 0 (1) out:
hdaa1:  Pin nid=33 seq=0
hdaa1: Association 1 (2) out:
hdaa1:  Pin nid=20 seq=0
hdaa1: Association 2 (4) in (disabled):
hdaa1:  Pin nid=25 seq=0
hdaa1: Tracing association 0 (1)
hdaa1:  Pin 33 traced to DAC 2
hdaa1: Association 0 (1) trace succeeded
hdaa1: Tracing association 1 (2)
hdaa1:  Unable to trace pin 20 seq 0 with min nid 0
hdaa1: Association 1 (2) trace failed
hdaa1: Looking for additional DAC for association 0 (1)
hdaa1: Tracing input monitor
hdaa1: Tracing other input monitors
hdaa1: Tracing beeper
hdaa1: FG config/quirks: forcestereo ivref50 ivref80 ivref100 ivref
pcm3: <Realtek ALC257 (Right Analog Headphones)> at nid 33 on hdaa1
pcm3: Playback:
pcm3:      Stream cap: 0x00000001 PCM
pcm3:         PCM cap: 0x000e0060 16 20 24 bits, 44 48 KHz
pcm3:             DAC: 2
pcm3: 
pcm3:     nid=33 [pin: Headphones (Black Jack)]
pcm3:       + <- nid=2 [audio output] [src: pcm]
pcm3: 
pcm3: Master Volume (OSS: vol): -65/0dB
pcm3:    +- ctl  1 (nid   2 out):    -65/0dB (88 steps)
pcm3:    +- ctl 14 (nid  33 in ):    mute
pcm3: 
pcm3: PCM Volume (OSS: pcm): -65/0dB
pcm3:    +- ctl  1 (nid   2 out):    -65/0dB (88 steps)
pcm3:    +- ctl 14 (nid  33 in ):    mute
pcm3: 
pcm3: Mixer "vol":
pcm3: Mixer "pcm":
pcm3: Mixer "ogain":
pcm3: Playback channel set is: Front Left, Front Right, 
pcm3: Playback channel matrix is: 2.0 (disconnected)

Notice the line:

hdaa1: hdaa_audio_as_parse: Duplicate pin 0 (25) in association 4! Disabling association.

This prevented me from getting my headphones working. I had to set up my own specific associations for a speaker, microphone, and headphones configuration.

Understanding Sound Chip Associations

The output above shows the following configuration set up by the FreeBSD kernel:

hdaa1: nid   0x    as seq device       conn  jack    loc        color   misc
hdaa1: 18 90a60140 4  0  Mic           Fixed Digital Internal   Unknown 1
hdaa1: 19 40000000 0  0  Line-out      None  Unknown 0x00       Unknown 0 DISA
hdaa1: 20 90170120 2  0  Speaker       Fixed Analog  Internal   Unknown 1
hdaa1: 24 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 25 04a11040 4  0  Mic           Jack  1/8     Right      Black   0
hdaa1: 26 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 27 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 30 411111f0 15 0  Speaker       None  1/8     Rear       Black   1 DISA
hdaa1: 33 04211010 1  0  Headphones    Jack  1/8     Right      Black   0
hdaa1: hdaa_audio_as_parse: Duplicate pin 0 (25) in association 4! Disabling association.

The key columns are:

  • nid - this is the id of an input or output line on the sound chip
  • as - this is the association id that indicates what devices are grouped together
  • device - this is a designated label for the device
  • loc - this is the location of the device identified by the manufacturer or integrator
  • misc - a value of 0 indicates there are no changes expected on the device if something is plugged in to its connector. A value of 1 indicates there are changes expected on the device A note of “DISA” indicates that FreeBSD considers that NID disabled.

Graphically, the default configuration looks like this:

Default configuration of sound chip

Default configuration of sound chip

NID values are large bolded numbers, and association values are the rounded circle numbers. Locations of Rear, Internal, and Right are identifed on the diagram. The table below the figure shows the associations set up by default.

I needed to change the association values to pair the internal and right side microphones (18 and 25), and to pair the Internal speaker and external right side headphones.

The resulting reconfiguration looks like this:

Sound chip reconfiguration

Sound chip reconfiguration

Once I got what I wanted, I put the details in /boot/device.hints:

#
# Adjust the sound chip and snd_hda(4).
# Note - the driver assumes input on association 4 and output on association 2
#INPUT
hint.hdac.1.cad0.nid18.config="as=4 seq=0"
hint.hdac.1.cad0.nid25.config="as=4 seq=5"
#OUTPUT
hint.hdac.1.cad0.nid19.config="as=2 seq=0"
hint.hdac.1.cad0.nid33.config="as=2 seq=5 device=Headphones"
#DISABLED
hint.hdac.1.cad0.nid20.config="as=15 seq=0"
hint.hdac.1.cad0.nid24.config="as=15 seq=0"
hint.hdac.1.cad0.nid26.config="as=15 seq=0"
hint.hdac.1.cad0.nid27.config="as=15 seq=0"
hint.hdac.1.cad0.nid30.config="as=15 seq=0"

I now have sound working with OSS, using an external speaker and microphone, that has the ability to switch to a headphone set (speakers+microphone) when I plug it in.

That’s what I set out to do, so I’m done for now.

I don’t yet need Pulse audio, but if I do, I’ll look at it later.