Index RSS

Switching audio devices on OpenBSD

Most of the time, I do not have to think about audio devices on OpenBSD: They just work. But sometimes, I need more features, like when I want to listen to music or other kinds of sound with a USB headset. The good news is that my Sennheiser headset also just works, but just plugging it in does not mean that sound comes out of it instead of the laptop speakers.

In earlier versions of OpenBSD, I had to play with sndiod parameters or set the AUDIODEVICE environment variable before starting the programs that should output their sound to the headset. But on recent versions (since 6.7, I think?), I can just use sndioctl to toggle my output device.

This is not documented on the multimedia FAQ. I do not know if their is a reason to prefer the old ways I just mentioned, so I give no warranties of any kind if you do what I describe here. I just find that it is both more comfortable and more versatile to use sndioctl. For officially supported methods, please look at the FAQ.

https://www.openbsd.org/faq/faq13.html

Switching the output device via sndioctl(1)

You can simply call sndioctl (without needing root permissions) and it will output all properties, which could look like this:

input.level=0.486
input.mute=0
output.level=0.714
output.mute=0
server.device=0
app/firefox0.level=1.000
app/mpg0.level=1.000

There are properties like *.level, which control the volume - both per device and per individual application, if you want to do that. You can also use sndioctl to mute or unmute audio input or output. But today, we are here to talk about server.device, which points, in the example output above, to the first audio device (rsnd/0).

If I plug my headset into my notebook, it would be a good guess to assume that it might become the second audio device. Let's change our output device to that via

sndioctl server.device=1

All sound currently playing and all sound that will be played from now on should be output to my headset - it does not get any easier than this!

Mono sound?

To be honest, I had a small problem at first: Only the left speaker on my headset was working. What was that about?

Well, calling sndioctl again quickly pointed to the culprit:

input.level=0.188
input.mute=0
output[0].level=0.306
output[1].level=0.012
output.mute=0
server.device=1
app/firefox0.level=1.000
app/mpg0.level=1.000

I do not know why, but I had different volumes for both headset speakers. This was quickly fixed with another call to sndioctl:

sndioctl output[1].level=0.306

After that, my sndioctl output was what I expected it to be in the first place, and all audio could be heard with both ears.

input.level=0.188
input.mute=0
output.level=0.306
output.mute=0
server.device=1
app/firefox0.level=1.000
app/mpg0.level=1.000

Setting the server.device variable back to zero switches my audio back to the internal speakers - and again, without any interrupts.

Also, should I ever desire to change the volume of one side of my headset independently from the other side, I learned to just do so via

sndioctl output[1].level=0.1

I do not believe that I will ever need this, but you never know.