# OpenBSD sndio and mutiple devices ## Automatic audio device switch OpenBSD automatically detects the system audio device. But often this is not enough. I want to plug in a USB headset and audio should automatically switch to it. You can start sndiod with additional `-F` flags to define additional devices, which are switched to when they appear. ``` # sndiod -f rsnd/0 -F rsnd/1 -F rsnd/2 -F rsnd/3 ``` You can set these flags permanently with: ``` # rcctl set sndiod flags -f rsnd/0 -F rsnd/1 -F rsnd/2 -F rsnd/3 ``` This configuration allows up to 3 additional USB devices to be connected and sndiod will switch to the last one connected. If you have multiple devices connected and want to switch to a specific one, you can do so with: ``` $ sndioctl server.device=0 $ sndioctl server.device=1 $ sndioctl server.device=2 ... ``` ## Record from one device, but play back on another... Let's say I want to connect USB microphone, but I want to to play back sound on another device. This works by setting the environment variables `AUDIORECDEVICE` and `AUDIOPLAYDEVICE` accordingly. Example: ``` export AUDIOPLAYDEVICE=snd/0 export AUDIORECDEVICE=snd/1 ``` However, sndiod expects every device to play and record. So the above example would work to play on the system, but record on a headset. If the devices are more limited, the sndio flags need to be more specific, like this: ``` # rcctl set sndiod flags -f rsnd/0 -m play -s play -f rsnd/1 -m rec -s rec # rcctl restart sndiod $ export AUDIOPLAYDEVICE=snd/0.play $ export AUDIORECDEVICE=snd/1.rec ``` This creates a "play" sub device on the first audio device (system audio). And a sub device "rec" on the first USB device. The default is "play,rec", which would not work on my USB microphone. The -m switch describes what the device can do. The -s switch defines the sub device name. And now... everything works as expected. ``` $ aucat -o test.wav # record from microphone $ aucat -i test.wav # play on system speaker ```