On Sun, Sep 15, 2019 at 03:01:36PM -0300, Martin Pieuchot wrote:
> On 29/08/19(Thu) 10:52, Alexandre Ratchov wrote:
> > The diff below allows to specifiy "an alternate device" to use in case
> > the audio device is disconnected. If so, programs continue playing
> > using the other device.
> > 
> > For instance, if dmesg contains:
> > 
> >     audio0 at azalia0
> >     audio1 at uaudio0
> > 
> > and /etc/rc.conf.local contains:
> > 
> >     sndiod_flags=-f rsnd/0 -F rsnd/1
> > 
> > then sndiod will try to use the usb device by default. If it's
> > disconnected, programs continue using the internal one. Note that
> > there's no way to detect that the usb device is reconnected;
> 
> Instead of doing a open/reopen dance in userland, which is inherently
> racy, did you consider introducing a driver abstracting the various
> audio(4) drivers attached?  I'm thinking of something like wsmux(4) for
> audio.  This should allow us to transparently attach/detach usb audio
> devices.

I don't see any race conditions: once a device disappears, it is
closed and another one is opened in place. This only relies on calls
to open() and close() which are not racy. Unlike with hotplug(4),
there's no concurency between multiple code-paths; it's all
sequencial.

I've considered the wsmux-style device for audio. Multiple audio
devices can't be combined, so the audio mux device would be a switch
between the devices, which is roughly what the diff does.

Switching between devices, when possible, is not trivial, because the
state of one device must be restored on another device. It may require
channel mapping and/or format conversions, in case the devices don't
have the same capabilities. We don't want such complicated code to run
with full kernel privileges and to have access to all the physical
memory. FWIW, this was one of the reasons for moving the audio
sub-system completely to user-space, leaving in the kernel only the
code to access the hardware.

Furthermore, putting such code in the kernel would add an extra audio
software layer, while we've all the necessary bits in sndiod.

IMO, if in the future something ends up difficult to implement in
user-space I'm not against pulling parts of the code in the kernel,
but for now this doesn't seem necessary.


> > internal one will keep playing until all programs stop; then sndiod
> > will retry the usb one again. To force sndiod to retry the usb one,
> > send SIGHUP.
> 
> I'm not a fan of having such hotplug logic in userland because it is by
> default racy and opens a can of worm for being able to configure how / 
> when a driver becomes the default one.
> 

The configuration logic is simple and well-defined: there's an ordered
list of devices. Whenever a device disappears, it's closed and the
first working device of the list is opend. Configuring this is a
matter of providing the (oredered) device list; this would be
necessary in kernel implementation as well.

> > As we're at it, the same logic is applied to MIDI as well; it makes
> > possible to swap instuments without restarting programs.
> > 
> > For all this to work, both audio devices must support the same rate
> > (48kHz by default) and the same block size (now 10ms by default). This
> > requires the block size calculation to be fixed in the audio(9) layer,
> > so this diff is needed as well:
> 
> With the idea above you could attach all 'converted' audio drivers to
> the mux ;)

AFAIK, all drivers are now "fixed" (hacks remain, but they still
work). Now, whether switching between the devices is possible depends
only on the hardware and the device operating mode (which is not known
at attach time, btw).

Reply via email to