Title: Networked audio on voidlinux using sndio Date: 2022-11-27 Tags: sndio voidlinux openbsd audio sndio is the audio system used on OpenBSD. However, unlike ALSA, it mostly exists in userland as the daemon sndiod, allowing it to be ported over to linux. sndio is heavier than alsa in terms of features, yet arguable lighter in terms of design. The main things it supports that alsa doesn't is: - Per-application controls - Network transparency The following commands are voidlinux specific, but the options that sndiod is run with can be applied on any distribtion. This installs and enables sndio with some options: xbps-install sndio echo 'OPTS="-f rsnd/ -L-"' > /etc/sv/sndiod/conf sv ln -s /etc/sv/sndiod /var/service -f tells sndiod which alsa device it should output from. If the 0th device is the output you want to use, it will be selected automatically, but otherwise rsnd/n must be used with the number of the device (check your asoundrc or `aplay -l`). -L- tells sndiod to listen for network connections. ## Networked audio Okay, you have a computer called speakers.local. You are running sndiod with -L- on it. You have another computer with sndio installed (but not necessarily running sndiod) and you set AUDIODEVICE=snd@speakers.local/0 in the environment. What happens now? Well, everything that uses sndio will play play as though it was running on speakers.local. That's it. That's all you have to do. ## Outputting to sndio Void is pretty good when it comes to supporting sndio. mpv and firefox are both built with sndio support. For cmus, cmus-sndio can be installed (cmus is pretty damn good when it comes to i/o plugins). That's really everything I use that needs to be output audio (I only use firefox occasionally, but when I do I want it to output audio). qutebrowser seems to need some fiddling, but I don't need any audio from that. Either way, here's a little a one liner that uses snd-aloop to play alsa output: ffmpeg -f alsa -i hw:Loopback,1,0 -f s16le - | aucat -e s16 -i - There's plenty of information on snd-aloop elsewhere. Aucat is sndio's aplay/arecord/mini-ffmpeg in one. Checkout the man page. ## Controlling / and visualizing with sndio The main way to control sndio is with sndioctl. Running it with no arguments produces something like: output.level=1.000 app/cava0.level=1.000 app/cmus0.level=1.000 app/mpv0.level=1.000 All of the levels can be adjusted and there are also .mutes for each that can be set to 1 or 0. An ncurses program for controlling these similar to ncpamixer (for pulse) and alsamixer is cmixer. Here's a script that allows you to use sndioctl as though it were amixer: command -v sndioctl >/dev/null && { echo "$1" | grep '%' >/dev/null && { case "$(echo "$1" | sed -E 's/.*(.)$/\1/')" in "+") t="+" ;; "-") t="-" ;; *) t="" ;; esac percent=$(echo "$1" | tr -d '%+-') units=$(echo "scale=3; $percent / 100" | bc) sndioctl output.level="${t}${units}" exit 0 } case "$1" in "mute") sndioctl output.mute=1 ;; "unmute") sndioctl output.mute=0 ;; "toggle") sndioctl output.mute=! ;; *) sndioctl output.level=$1 ;; esac } || amixer set Master "$1" Creating monitor/loopback devices with sndio is much simpler than with alsa, append '-s default -m mon -s monitor' to sndiod's options and now you can use: method = sndio source = snd@speakers.local/0.monitor To .config/cava/config and get a nice visualizer. Or something similar depending on your setup.