Upcoming JACK changes, new OSS API backend

From: Florian Walpen <dev_at_submerge.ch>
Date: Thu, 08 Jun 2023 22:14:16 UTC
Hi there,

to those interested in JACK audio server (audio/jack), I'm currently testing 
an overhauled OSS API backend for FreeBSD. I intend to merge that into the 
next JACK release (not planned yet). Here is some information in advance, and 
a chance to beta-test the backend before it hits the ports.

Main motivation for the new backend was to improve the situation for low 
latency requirements (live mixing and effects). Also to separate the OSS sync 
logic into a reusable library, for JACK audio adapters or another audio server 
in the future.


User Facing Changes:
====================
 - More robust operation with stable latencies +/- 1ms.
 - Avoid problems that may occur when the OSS buffer sizes are changed.
 - Low latency operation (4-6ms round-trip) on specific hardware.
 - The nperiod parameter is deprecated, always 1 (former default value).
 - Supposedly works with little-endian samples on big-endian systems.

Please note that for low latency you need a well tuned system (reliable 
timers) and the right hardware. So far I only know of the snd_hdspe driver 
which clocks in a round-trip-time of ~3ms at extreme settings, including DA -> 
AD conversion. Other PCI drivers may be worth a try, but USB interfaces always 
incurred a minimum latency of ~20ms in my tests which is not suitable for live 
processing.

On a side note, snd_hdspe may need some love - it splits the interface into 
18(!) 2-channel devices, which is fine for media consumption but somewhat 
impractical for audio work. Next project for me ;-)

I neither possess big-endian machines nor audio interfaces that take big-
endian samples, so I cannot test the last point. Glad to hear about any 
experience with mixed endianness.


Technical Changes:
==================
 - Use a new C++ header-only library for the OSS low level and sync logic.
 - Time based polling mechanism instead of poll() system calls.
 - Memory-map the OSS buffer where available, FreeBSD 13.2 and newer.
 - Fallback to read() / write() IO, FreeBSD prior to 13.2, virtual_oss.
 - Separate assist thread takes over when main JACK thread is busy.
 - Leaves the OSS buffer sizes untouched, which may cause troubles.
 - Applies an internal double buffer scheme instead.

Although memory mapped operation is possible on FreeBSD prior to 13.2, it is 
broken for many sample formats (non-power-of-2). The advantage of memory 
mapping is more about robustness than performance. And the time based polling 
is a requirement there, it doesn't work with poll().

The double buffer scheme and the assist thread decouple the internal buffer 
size (period) from the OSS buffer size. JACK should now cope much better with 
large periods against small OSS buffer sizes, and vice versa.


Beta Test:
==========
If you're interested enough to read up to this point, you may as well try it.
 - The attached patch can be applied to the ports tree with "git am".
 - Fetches from my github fork, not yet merged to the official JACK repo.
 - Same JACK version as before, but PORTREVISION is obviously off the mark.

Sources are fetched from here:
https://github.com/0EVSG/jack2/commits/freebsd_sosso

In case of regressions or otherwise unexpected encounters please send me the 
logs of the particular session. The logs can be found in
/var/log/jackd.log
or
~/.log/jack/jackdbus.log

Don't expect any miracles, if there's no regressions I'm already happy. 
And there's plenty of limiting factors in the FreeBSD audio landscape which 
JACK cannot solve.

Good luck!

Florian