Switch between audio devices in real time

Hello.
The task is to switch between sound output devices in real-time (on the fly).
Only sndio and/or oss can be used.

To /boot/loader.conf already added:
Code:
snd_driver_load="YES"
sound_load="YES"
cuse_load="YES"

Switching with sysctl hw.snd.default_unit only works the next time you play a sound (it doesn’t work on the fly).
# cat /dev/sndstat
Code:
pcm0: <ATI R6xx (HDMI)> (play)
pcm1: <Analog Devices AD1882 (Analog)> (play/rec) default
pcm2: <Analog Devices AD1882 (Front Analog Headphones)> (play)
pcm3: <USB audio> (play/rec)
# uname -a
Code:
FreeBSD testInstall 12.0-RELEASE-p10 FreeBSD 12.0-RELEASE-p10 GENERIC  amd64
 
It's not supposed to work "on the fly". I'm not even sure if that's technically possible. While you can change the default output while the system is running, the application needs to re-open the device in order to pick up the change.

If you have an application writing to a file, you can remove/rename that file while this happens. The application would continue to write to the original file descriptor and needs to be restarted before it would pick up the file change.
 
It's not supposed to work "on the fly". I'm not even sure if that's technically possible. While you can change the default output while the system is running, the application needs to re-open the device in order to pick up the change.

If you have an application writing to a file, you can remove/rename that file while this happens. The application would continue to write to the original file descriptor and needs to be restarted before it would pick up the file change.


I have already done this with pulseaudio on Arch Linux and there it's easy, only switching between sinks with pactl.
But BSD has many utils to work with sound and MIDI devises ( sndiod, aucat, aucatctl, midicat, virtual-oss, virtual_oss_ctl). I am guessing that there, must be the way to archive this.
 
I have already done this with pulseaudio on Arch Linux and there it's easy
That's a software layer that sits in between the actual audio driver and a 'consumer' (i.e. audio application). It's this layer that does the actual switching, keeping the same connection to the consumer.
 
I have already done this with pulseaudio on Arch Linux and there it's easy, only switching between sinks with pactl.
But BSD has many utils to work with sound and MIDI devises ( sndiod, aucat, aucatctl, midicat, virtual-oss, virtual_oss_ctl).

OSS is a relatively dumb sound system, with notable exception of the software mixer (which isn't a part of initial OSS design, by the way) you pretty much talk directly to the kernel driver. That is why there is no native MIDI or routing capabilities. Good latency, though ;)

That said, multiplexing and loopback devices would be a very appropriate addition to FreeBSD OSS, but so far nobody bothered to do it. virtual_oss is the closest thing in existence and even that program is relatively new (< 10 years old).

I am guessing that there, must be the way to archive this.

Achieve what exactly?
 
Wouldn't audio/sndio provide the same type of intermediate software layer (sound server) that audio/pulseaudio provides? Perhaps OP is looking to use something like sndiod -f rsnd/0 or sndiod -f rsnd/0 -s snd/0 as a toggle in a script...

So I have already tried to create sub-device with sndio. But still don't understand how connect to them and in cat /dev/sndstat also can't see anything new. Maybe there must be some configuration in some file to to this.
 
The /dev/sndstat is part of the FreeBSD audio framework, sndio is a separate software layer that sits on top of that. It doesn't become part of the FreeBSD audio framework.
 
Developer sndio Alexandre Ratchov alex@caoua.org.

Replied that the ability to quickly switch sound devices is missing in sndio, only the fallback option.

Hi,

There's no utility to switch between devices, sorry.

However recent sndiod versions allow "alternate devices" to be
specified with a new -F options. If the alternate device is present,
it's used. If it's disconnected, sndiod switches to the other one. In
your example, if sndiod is started with:

sndiod -f rsnd/1 -F rsnd/3

then, when the the USB device is present, it will be used; if it's
disconnected sndiod switches to the on-board one. SIGHUP makes sndiod
switch back to the alternate device, if present.

I haven't tested this on FreeBSD yet.

The question is closed, hello pulseaudio.
 
I am not even sure if pulseaudio works the same way on Freebsd as in Linux. Pavucontrol on Linux can switch on the fly. So far I like OSS but I am very tempted to hit the ground with pulseaudio because of HDMI connection to the entertainment receiver.
 
I am not even sure if pulseaudio works the same way on Freebsd as in Linux. Pavucontrol on Linux can switch on the fly. So far I like OSS but I am very tempted to hit the ground with pulseaudio because of HDMI connection to the entertainment receiver.
With pulseaudio it's easy, there special command for this pactl move-sink-inputs, sink-input become when some app what to make sound. But unfortunately OSS doesn't give information to pulseaudio about sound cards and when I want connect new device (for example usb headset), I must relaunch pulseaudio , because it using udev to detect new devices.
 
So, there some way to archive switching with virtual_oss.
I started with creating link to physical device /dev/dsp2.0
virtual_oss -T /dev/sndstat -b 16 -c 2 -r 48000 -s 1024 -d dsp.first -O /dev/dsp2.0 -R /dev/null -t dsp.first.ctl &
Than creating second virtual device attached to first virtual one.
virtual_oss -T /dev/sndstat -b 16 -c 2 -r 48000 -s 1024 -d dsp.second -O /dev/dsp.first -R /dev/null -t dsp.second.ctl &
And than I trying to play for example music mpg123 -a /dev/dsp.second some.mp3.
Next step is to relaunch first virtual_oss with different -O /dev/dsp* option, but it cause pause in playing about 2 seconds.
And also I can't make virtual_oss device as default with sysctl hw.snd.default_unit.
 
Back
Top