Switch between audio devices in real time

jsInspector

New Member

Reaction score: 1
Messages: 8

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
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,023
Messages: 38,477

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.
 
OP
jsInspector

jsInspector

New Member

Reaction score: 1
Messages: 8

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.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,023
Messages: 38,477

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.
 

shkhln

Daemon

Reaction score: 952
Messages: 2,203

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?
 

JBR

New Member

Reaction score: 1
Messages: 3

OP
jsInspector

jsInspector

New Member

Reaction score: 1
Messages: 8

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.
 

SirDice

Administrator
Staff member
Administrator
Moderator

Reaction score: 12,023
Messages: 38,477

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.
 
OP
jsInspector

jsInspector

New Member

Reaction score: 1
Messages: 8

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.
 

joplass

Active Member

Reaction score: 46
Messages: 249

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.
 
OP
jsInspector

jsInspector

New Member

Reaction score: 1
Messages: 8

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.
 
OP
jsInspector

jsInspector

New Member

Reaction score: 1
Messages: 8

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.
 
Top