===== Sound & Audio ===== This page reflects the state of sound support in %%FreeBSD%% 10.0-RELEASE to 14.0-CURRENT. It documents things of interest to users and developers. ==== History ==== Sound support for %%FreeBSD%% began in 1993, when Jordan K. Hubbard imported version 1.0c of the generic Linux sound driver into %%FreeBSD%%, later known as the %%VoxWare%% sound drivers, written by Hannu Savolainen. This code was made available by Hannu under two different licenses: GPL for Linux and BSD for %%FreeBSD%%/Unix variants. Several new versions of the %%VoxWare%% drivers were imported (and modified) into the %%FreeBSD%% base system between 1993 and 1997. At this time Amancio Hasty and Jim Lowe did most of the work on sound support in %%FreeBSD%%. The %%VoxWare%% drivers eventually became what we know today as OSS, the [[http://www.opensound.com/|Open Sound System]], maintained by Hannu and his team at 4Front Technologies. OSS has been considered a standard in the Linux world for many years (even if the ALSA project has become the number one choice nowadays, or ALSA has been defacto-replaced with other solutions like %%PulseAudio%% and/or pipewire). The last version to be imported was %%VoxWare%% 3.5-alpha6. By following the history it is evident that the sound API in %%FreeBSD%% has gradually evolved from the %%VoxWare%% standard, which later become the OSS standard. However, things changed in 1997 as more of the foundation for the sound system we have today was laid out. Luigi Rizzo was maintaining his own set of patches for %%FreeBSD%% and in 1997 his sound code was [[http://docs.freebsd.org/cgi/getmsg.cgi?fetch=8330+0+archive/1997/cvs-sys/19970914.cvs-sys|imported]] by John-Mark Gurney as an alternate sound driver. This driver was a complete rewrite (with the exception of soundcard.h) of the existing code (%%VoxWare%% code + modifications from Amancio). One of the most important features was support for %%PnP%% and %%FreeBSD%% 2.2.6 was the first release where it was part of the %%FreeBSD%% kernel source tree. So, for a period of time we had two sound drivers available in the %%FreeBSD%% kernel source tree: * new code in ''%%sys/i386/isa/snd/%%'' by Luigi Rizzo called "pcm" driver * old code in ''%%sys/i386/isa/sound/%%'' obtained from %%VoxWare%% and modified for %%FreeBSD%%. From 1997 to 1998, Luigi's code was maintained outside of the %%FreeBSD%% repository and was imported into %%FreeBSD%% whenever he cut a new release of his code. In 1999, Cameron Grant rewrote the sound system for %%FreeBSD%% 4.0 (his new driver was referred to as "newpcm" at the time) and later on [[http://docs.freebsd.org/cgi/getmsg.cgi?fetch=1177021+0+archive/1999/cvs-all/19990905.cvs-all|imported]] his work to ''%%sys/dev/pcm%%'' and [[http://docs.freebsd.org/cgi/getmsg.cgi?fetch=593969+0+archive/1999/freebsd-current/19990905.freebsd-current|announced]] the change on the %%FreeBSD%% current mailing list. This superceded Luigi's pcm driver and it was [[http://docs.freebsd.org/cgi/getmsg.cgi?fetch=76641+0+archive/1999/cvs-all/19991003.cvs-all|removed]] from the tree a month later. Cameron's newpcm code used the newbus interface and supported a great deal of hardware. Not long after the import of newpcm, the sound [[http://docs.freebsd.org/cgi/getmsg.cgi?fetch=907682+0+archive/1999/cvs-all/19991121.cvs-all|code]] was [[http://docs.freebsd.org/cgi/getmsg.cgi?fetch=24322+0+archive/1999/cvs-all/19991128.cvs-all|moved]] again. This time it ended up in ''%%sys/dev/sound%%'', which also is the current location of all code belonging to the %%FreeBSD%% sound system. In the following years many things changed in the sound area. The amount of drivers for different hardware chips increased dramatically (especially for PCI and USB devices) and many improvements were made to the sound infrastructure, much thanks to Cameron Grant and Orion Hodson. Cameron [[http://lists.freebsd.org/pipermail/freebsd-announce/2005-March/000984.html|passed away]] in 2005, a major loss for the %%FreeBSD%% community. Ariff Abdullah took over the maintainership of the pcm code in %%FreeBSD%% in 2005 and other individuals are taking care of the sound device drivers. Since then we've seen some dramatic changes in sound support including the volume per-channel adjustments, low-latency audio, multi-channel, locking removal, virtual channels, a high-quality resampler, a sync of the API to be compatible with OSSv4, as well as several rounds of device driver restructuring. ==== Features ==== * Multi-channel audio * Mixing * Equalization * Volume per-channel * Bit-perfect modes * Low latency I/O, as well as latency profiles * Virtual channels, for recording from multiple sources with mixing * High-quality resampling, featuring either linear interpolation, a couple of different kinds of bandlimited SINC interpolation, or zero order hold * OSSv4 compatibility * Statistics * Runtime setting via sysctl ---- ===== Documentation ===== ==== FreeBSD Handbook ==== The //Multimedia// chatper includes [[https://docs.freebsd.org/en/books/handbook/multimedia/#sound-setup|Setting Up the Sound Card]]. This section includes advice on configuring audio devices, including Bluetooth. ==== Manual Pages ==== [[https://man.freebsd.org/cgi/man.cgi?query=sound&sektion=4&manpath=FreeBSD|sound(4)]] should be updated whenever a new feature is added – a first stop for information. The page describes all [[https://docs.freebsd.org/en/books/handbook/config/#configtuning-sysctl|sysctl]] audio parameters. pcm(4) and snd(4) redirect to sound(4). [[https://man.freebsd.org/cgi/man.cgi?query=sysctl&sektion=8&manpath=FreeBSD|sysctl(8)]] can help to learn about runtime configuration of sound: * the subtree of ''%%hw.snd%%'' represents the sound system * each subtree of ''%%dev.pcm%%'' represents a device. Individual drivers: * [[https://man.freebsd.org/cgi/man.cgi?query=snd_ad1816&sektion=4&manpath=FreeBSD|snd_ad1816(4)]] – Analog Devices AD1816 ISA bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_als4000&sektion=4&manpath=FreeBSD|snd_als4000(4)]] – Avance Logic ALS4000 PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_atiixp&sektion=4&manpath=FreeBSD|snd_atiixp(4)]] – ATI IXP bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_cmi&sektion=4&manpath=FreeBSD|snd_cmi(4)]] – CMedia CMI8338/CMI8738 PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_cs4281&sektion=4&manpath=FreeBSD|snd_cs4281(4)]] – Crystal Semiconductor CS4281 PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_csa&sektion=4&manpath=FreeBSD|snd_csa(4)]] – Crystal Semiconductor CS461x/462x/4280 PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_ds1&sektion=4&manpath=FreeBSD|snd_ds1(4)]] – Yamaha DS-1 PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_emu10k1&sektion=4&manpath=FreeBSD|snd_emu10k1(4)]] – %%SoundBlaster%% Live! and Audigy PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_emu10kx&sektion=4&manpath=FreeBSD|snd_emu10kx(4)]] – Creative %%SoundBlaster%% Live! and Audigy sound cards device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_envy24&sektion=4&manpath=FreeBSD|snd_envy24(4)]] – VIA Envy24 and compatible bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_envy24ht&sektion=4&manpath=FreeBSD|snd_envy24ht(4)]] – VIA Envy24HT and compatible bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_es137x&sektion=4&manpath=FreeBSD|snd_es137x(4)]] – Ensoniq %%AudioPCI%% ES137x bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_ess&sektion=4&manpath=FreeBSD|snd_ess(4)]] – Ensoniq ESS ISA %%PnP%%/non-%%PnP%% bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_fm801&sektion=4&manpath=FreeBSD|snd_fm801(4)]] – Forte Media FM801 bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_gusc&sektion=4&manpath=FreeBSD|snd_gusc(4)]] – Gravis %%UltraSound%% ISA bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_hda&sektion=4&manpath=FreeBSD|snd_hda(4)]] – Intel High Definition Audio bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_hdspe&sektion=4&manpath=FreeBSD|snd_hdspe(4)]] – RME HDSPe bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_ich&sektion=4&manpath=FreeBSD|snd_ich(4)]] – Intel ICH AC'97 and compatible bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_maestro&sektion=4&manpath=FreeBSD|snd_maestro(4)]] – ESS Maestro bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_maestro3&sektion=4&manpath=FreeBSD|snd_maestro3(4)]] – ESS Maestro3/Allegro-1 bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_mss&sektion=4&manpath=FreeBSD|snd_mss(4)]] – Microsoft Sound System ISA %%PnP%%/non-%%PnP%% bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_neomagic&sektion=4&manpath=FreeBSD|snd_neomagic(4)]] – %%NeoMagic%% 256AV/ZX bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_sbc&sektion=4&manpath=FreeBSD|snd_sbc(4)]] – Creative Sound Blaster ISA and compatible bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_solo&sektion=4&manpath=FreeBSD|snd_solo(4)]] – ESS Solo-1/1E PCI bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_spicds&sektion=4&manpath=FreeBSD|snd_spicds(4)]] – I2S SPI audio codec driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_t4dwave&sektion=4&manpath=FreeBSD|snd_t4dwave(4)]] – Trident 4DWave bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_uaudio&sektion=4&manpath=FreeBSD|snd_uaudio(4)]] – USB audio and MIDI device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_via8233&sektion=4&manpath=FreeBSD|snd_via8233(4)]] – VIA Technologies VT8233 bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_via82c686&sektion=4&manpath=FreeBSD|snd_via82c686(4)]] – VIA Technologies 82C686A bridge device driver * [[https://man.freebsd.org/cgi/man.cgi?query=snd_vibes&sektion=4&manpath=FreeBSD|snd_vibes(4)]] – S3 %%SonicVibes%% bridge device driver Not documented: ''%%snd_ai2s(4)%%'', ''%%snd_audiocs(4)%%'', ''%%snd_aureal(4)%%'', ''%%snd_csapcm(4)%%'' and ''%%snd_davbus(4)%%''. ---- ===== Use Cases ===== ==== Mixer ==== %%FreeBSD%% 14.0-CURRENT includes a [[https://man.freebsd.org/cgi/man.cgi?query=mixer&sektion=3&manpath=FreeBSD+14.0-current|mixer(3)]] library and a rewritten [[https://man.freebsd.org/cgi/man.cgi?query=mixer&sektion=8&manpath=FreeBSD+14.0-current|mixer(8)]] utility. See [[https://margiolis.net/w/mixer_improvements/|Improvements on FreeBSD's sound mixer]] (Christos Margiolis, 2022-02-25). Utilities to set/display sound card mixer values built on the %%FreeBSD%% Sound System: * CLI (built-in): [[https://man.freebsd.org/cgi/man.cgi?query=mixer&sektion=8&manpath=FreeBSD|mixer(8)]] * TUI (ncurses): [[https://www.freshports.org/audio/mixertui/|audio/mixertui]] * GUI (QT): [[https://www.freshports.org/audio/dsbmixer/|audio/dsbmixer]] The ports collection also includes utilities such as [[https://www.freshports.org/audio/gtk-mixer/|GTK-Mixer]], which can set the default device. The default device can be set at the command line. For example, prior to %%FreeBSD%% 14.0-CURRENT: % cat /dev/sndstat Installed devices: pcm0: (play/rec) pcm1: (play/rec) default No devices installed from userspace. % sysctl hw.snd.default_unit=0 hw.snd.default_unit: 1 -> 0 – and with %%FreeBSD%% 14.0-CURRENT: % mixer -a | grep ^pcm pcm0:mixer: on hdaa0 kld snd_hda (play/rec) pcm1:mixer: at ? kld snd_uaudio (play/rec) (default) % mixer -d0 default_unit: 1 -> 0 pcm1:mixer: at ? kld snd_uaudio (play/rec) vol = 0.70:0.70 pbk pcm = 0.75:0.75 pbk ==== Video conferencing (via browser) ==== === OSS (simple) === Firefox 81 and greater support OSS. Audio devices can be selected at runtime. === sndio (intermediate) === The sndio audio framework was originally developed for %%OpenBSD%%. [[https://www.freshports.org/www/chromium/|www/chromium]] uses sndio by default. [[https://www.freshports.org/www/firefox/|www/firefox]] does not require sndio. [[https://github.com/mozilla/cubeb|cubeb]], Mozilla's cross-platform audio library, is patched on %%FreeBSD%% to make native use of OSS. sndio integration for userspace programs. By default, the PCM sound system in %%FreeBSD%% will create OSS(v4) compatible clones of the basename (ie. /dev/dsp is accessible via /dev/dspN[.N]). This works well for OSS-compatible userspace programs. By default sndio doesn't require a daemon, and just maps OSS /dev/dspN* devices to sndio rsnd/N devices that can be chosen at start-time via the environment variable AUDIODEVICE. sndio 1.7.0 and greater allow different playback and recording devices through the environment variables AUDIOPLAYDEVICE and AUDIORECDEVICE. === sndio (using daemon) === In more complex cases you might use the sndio daemon: $ sndiod To make this permanent: # sysrc -f /etc/rc.conf sndiod_enable="YES" # service sndiod start If "Audio device got stuck" occurs, it may help to set a flag then restart sndiod. See [[https://man.freebsd.org/cgi/man.cgi?query=sndiod&sektion=8&manpath=FreeBSD-Ports|sndiod(8)]] to understand the ''%%-a%%'' flag before doing this: # sysrc -f /etc/rc.conf sndiod_flags="-a on" This assumes that you have your soundcard(s) or snd_uaudio in your kernel configuration, like it is included in the GENERIC kernel configuration file. === virtual_oss (advanced) === It is not uncommon to need one device for loudspeakers and a different device for a microphone. More complicated setups include mixing three–five sources into a single audio stream that features effects, microphone, game/video audio, and/or music. %%FreeBSDs%% in-kernel mixing allows [[https://www.freshports.org/audio/virtual_oss/|audio/virtual_oss]] to tell the kernel which devices to mix, to create a sndio-compatible composite device. The following example assumes output of /dev/sndstat that is similar to this: Installed devices: pcm0: (play/rec) pcm1: (play/rec) default pcm2: (rec) For reference, this lists the primary audio card as pcm1 and the secondary audio card as pcm2. These can optionally be configured via nids as is the case with the [[Laptops/Thinkpad_T420|ThinkPad T420]] dock. First, we install virtual_oss: # pkg install audio/virtual_oss Then edit the file which can start virtual_oss with the system: less /usr/local/etc/rc.d/virtual_oss This file can be a little complex, so to ease understanding, here is a key scheme: -T /dev/sndstat \ # Register this device in /dev/sndstat -C 2 -c 2 \ # Make sure we're only working with two channels -S \ # Automatically resample using Project Z -r 48000 \ # Use a supported sample rate -b 24 \ # Use a supported sample depth -s 1024 \ # Set the size of the buffer -O /dev/dsp1 \ # Set pcm1 as the master device and playback device (default device for output) -R /dev/dsp2 \ # Set pcm2 as the recording device (device for input) -d dsp \ # Ensure that access via sndiod and the sndio library works -t vdsp.ctl # Optional control device for this virtual OSS instance You may also need to adjust the sample rate and depth of the various devices, if your devices don't support the values used in the above example. This can be done by checking /var/run/dmesg.boot or /var/log/messages, or by looking through sysctl OIDs in the dev.pcm namespace. Resampling using [[https://people.freebsd.org/~ariff/z_comparison/|Project Z]] uses the high-quality resampler mentioned elsewhere on this page. After this, run the following commands to enable and start virtual_oss: # service virtual_oss enable # service virtual_oss start The audio device can also be changed run-time without having to restart virtual_oss, give that the virtual_oss instance installed a control device: # virtual_oss_cmd /dev/vdsp.ctl -f /dev/dsp0 # virtual_oss_cmd /dev/vdsp.ctl -f /dev/dsp3 Optionally we also need to enable sndiod and start it (this step is only necessary if sndiod is used): # service sndiod enable # service sndiod start With this, these settings will persist across reboots. Finally, to check that the device is installed correctly, check /dev/sndstat again: $ cat /dev/sndstat Installed devices: pcm0: (play/rec) pcm1: (play/rec) default pcm2: (rec) Installed devices from userspace: dsp: (play/rec) With the dsp device registered as installed from userspace, Firefox and Chromium should correctly identify the audio source(s) that are mixed in the kernel, both output and input, if available) and work with video conferencing. It should be noted that this is, at present, somewhat incompatible with the simple sndiod setup noted above, as this involves removing and adding various devices - so the two setups should not be used in conjunction. Your browser may need to have some setting(s) adjusted to pick up on sndio, rather than preferring pulse if that's installed. In Firefox this can be done by adding/changing the media.cubeb.backend OID in the Firefox about:config. Alternatively, %%PulseAudio%% can be removed if it's not needed. Note: To use virtual_oss you could also edit ''%%/etc/rc.conf.d/virtual_oss%%'', an example virtual_oss_enable="YES" virtual_oss_dsp="-T /dev/sndstat -S -i 8 -C 18 -c 18 -r 48000 -b 32 -s 512 -f /dev/dsp0 -c 2 -d dsp -c 18 -d vdsp -t vdsp.ctl" === Redirecting full duplex audio from a remote machine (advanced) === You need to install virtual_oss and HpsJam. Then use virtual_oss(8) to create a fake /dev/dsp audio device, like shown below. echo virtual_oss -i 8 -B -S -Q 0 \ -T /dev/sndstat \ -c 4 -r 48000 -b 32 -s 4ms -f /dev/null \ -b 32 -c 2 -m 0,0,1,1 -d dsp \ -b 32 -c 2 -m 2,2,3,3 -d dsp.jack \ -M x,0,2,0,0,0 \ -M x,1,3,0,0,0 \ -M x,2,0,0,0,0 \ -M x,3,1,0,0,0 \ -t vdsp.ctl | su Then start a %%HpsJAM%% server instance, like shown below. echo HpsJam --server --peers 44 --ncpu 4 --cli-port 222 --port 700 --daemon --rtprio 8 | su Then start jackd as a regular user, like shown below. rtprio 8 jackd -d oss -d /dev/dsp.jack -r 48000 -p 256 & Then start HpsJam as a regular user, either via the terminal or X.org: HpsJam --mute-peer-audio --connect On another machine use the HpsJam software to connect to the same HpsJam server instance. Multiple devices may connect to your server instance of HpsJam. This allows you to easily move from one device to another. Then you can basically use any audio application on the remote machine at very low latency. Also remember to add your regular user to the "realtime" group and load the mac_priority.ko . === Chrome linux-binary === [[https://forums.freebsd.org/threads/linuxulator-how-to-run-google-chrome-linux-binary-on-freebsd.77559/|[Linuxulator How to run Google Chrome (linux-binary) on FreeBSD]]: sound, webcam, microphone, hardware acceleration all properly work. ==== FreeBSD in Audio Studio ==== Fosdem 2019 talk and slides: [[https://archive.fosdem.org/2019/schedule/event/freebsd_in_audio_studio/|FreeBSD in Audio Studio]], "%%FreeBSD%% is usually not the first choice for music art, but it has quite a lot to offer". ==== Audio profile ==== Audio profiles can be handled in userspace by: * [[https://man.freebsd.org/mixer/8|mixer(8)]] via -s option * [[https://www.freshports.org/audio/mixertui|