lychee
lychee

Reputation: 1851

kernel vs user-space audio device driver on macOS

I'm in a need to develop an audio device driver for System Audio Capture(based on Soundflower).
But soon a problem appeared that it seems IOAudioFamily stack is being deprecated in OSX 10.10 and later.
Looking through the IOAudioDevice and IOAudioEngine header files it seems that apple recommends now using the <CoreAudio/AudioServerPlugIn.h> API which runs in user-space. But I can't find lots of information on this user-space device drivers topic. It seems that the only resource is the Apple provided sample devices from https://developer.apple.com/library/prerelease/content/samplecode/AudioDriverExamples/Introduction/Intro.html
Looking through the examples I find that its a lot harder and more work to develop a user-space driver instead of I/O Kit kernel based.
So the question arises what should motivate to develop a device driver in user-space instead of kernel space?

Upvotes: 8

Views: 2638

Answers (2)

pmdj
pmdj

Reputation: 23428

The "SimpleAudioDriver" example is somewhat misnamed. It demonstrates pretty much every feature of the API. This is handy as a reference if you actually need to use those features. It's also structured in a way that's maybe a little more complicated than necessary.

For a virtual device, the NullAudioDriver is probably a much better base, and much, much easier to understand (single source file, if I remember correctly). SimpleAudioDriver is more useful for dealing with issues such as hotplugging, multiple instances of identical devices, etc.

IOAudioEngine is deprecated as you say, and has been since OS X 10.10. Expect it to go away eventually, so if you build your driver with it, you'll probably need to rewrite it sooner than if you create a Core Audio Server Plugin based one.

Testing and debugging audio drivers is awkward either way (due to being so time sensitive), but I'd say userspace ones are slightly less frustrating to deal with. You'll still want to test on a different machine than your development Mac, because if coreaudiod crashes or hangs, apps usually start locking up too, so being able to just ssh in, delete your plugin and kill coreaudiod is handy. Certainly quicker turnaround than having to reboot.

(FWIW, I've shipped both kernel and userspace OS X audio drivers, and I spend a lot of time working on kexts.)

Update for macOS 12 and 13:

macOS 12 adds support for AudioDriverKit, which is essentially a sandboxed IPC wrapper around the IOAudio… kernel APIs. Apple says:

  1. This API should be used for any audio drivers for physical devices going forward.
  2. This API should not be used for virtual device drivers, continue using audio server plugins for that.

Regarding system audio capture, macOS 13 adds native support for this in the (possibly confusingly named) ScreenCaptureKit. As well as streaming the display contents (or individual windows), this can stream/record system audio, so no custom driver should be needed.

Upvotes: 8

shortwavedave
shortwavedave

Reputation: 190

There is a great book on this subject, available free online here:

http://free-electrons.com/doc/books/ldd3.pdf

See page 37 for a summary of why you might want a user-space driver, copied here for convenience:

The advantages of user-space drivers are:

  • The full C library can be linked in. The driver can perform many exotic tasks without resorting to external programs (the utility programs implementing usage policies that are usually distributed along with the driver itself).
  • The programmer can run a conventional debugger on the driver code without having to go through contortions to debug a running kernel.
  • If a user-space driver hangs, you can simply kill it. Problems with the driver are unlikely to hang the entire system, unless the hardware being controlled is really misbehaving.
  • User memory is swappable, unlike kernel memory. An infrequently used device with a huge driver won’t occupy RAM that other programs could be using, except when it is actually in use.
  • A well-designed driver program can still, like kernel-space drivers, allow concurrent access to a device.
  • If you must write a closed-source driver, the user-space option makes it easier for you to avoid ambiguous licensing situations and problems with changing kernel interfaces.

Upvotes: -2

Related Questions