NetBSD audio – an application perspective ... or, "doing it natively, because we can" pkgsrcCon 2019 — Nia Alarie

who am I?

nia@NetBSD.org

nia on freenode, etc

Developer since 2018

First talk :-)

audio options for NetBSD in pkgsrc

Use NetBSD native audio (sun audio/audioio.h)

Or OSS emulation layer

Basically a wrapper around sun audio in the kernel

Incomplete and old version, but works for simple stuff

Many many abstraction layers available:

OpenAL-Soft

alsa-lib (config file required)

libao, GStreamer (plugins!)

PortAudio, SDL

PulseAudio, JACK

... lots more!? some obsolete stuff (esd, nas?)

advantages of using NetBSD audio directly

Low latency, low CPU usage

Abstraction layers differ in latency (SDL2 vs ALSA/OpenAL)

Abstraction layers differ in latency (SDL2 vs ALSA/OpenAL) Query device information

Is /dev/audio1 a USB microphone or another sound card?

Is /dev/audio1 a USB microphone or another sound card? Avoid bugs from excessive layering

Nice API, well documented

[nia note: I had no idea how to write audio code. I read a man page and now I do.]

[nia note: I had no idea how to write audio code. I read a man page and now I do.] Your code might work on illumos too

[nia note: SDL2 seems very sensitive to the blk_ms sysctl being high or low, with other implementations there seems to be a less noticable difference. I don't know why.]

first test case: RetroArch

Frontend for libraries implementing emulators or game logic.

I learned NetBSD had its own non-OSS audio API.

I wanted to increase support for it.

RetroArch was a straightforward target

They accepted my patch

RetroArch was a straightforward target They accepted my patch My code also works on illumos.

differences from the OSS implementation?

Kernel calculates block size for the user's global latency

Simpler and probably results in more desirable outcomes

Less ioctls

OSS - pass values using setters, e.g. SNDCTL_DSP_SETFMT

Sun - pass one struct to the kernel with AUDIO_SETINFO

[nia note: Both Sun and OSS involve opening a device in /dev and performing standard read(2) and write(2) operations on it. The difference is how you tell the kernel to interpret the data.]

second test case: aiomixer

Decided to use my experience after RetroArch to write a mixer

State of mixers is lacking

A lightweight user-friendly alternative to mixerctl was needed

A lightweight user-friendly alternative to mixerctl was needed Do more than change volume - DACs

Your laptop has a headphone port and speakers

Should be possible to select between them

And control them independently

Your laptop has a headphone port and speakers Should be possible to select between them And control them independently ... would be nice to have more readable DAC names



pkgsrc-wip - wip/aiomixer

github repository- https://github.com/niacat/aiomixer

third test case: SDL2

Popular in applications, but high latency on many platforms.

SDL already targeted NetBSD directly, but with many problems:

Tried to use non-blocking I/O

Workaround for the bad old days where opening /dev/audio

locked it system-wide.

Workaround for the bad old days where opening /dev/audio locked it system-wide. Calls to SDL_Delay(1) everywhere

Bad quality output - jittering, poor performance

Buggy initialization

etlegacy patched to use OpenAL.

reimplementation

I reimplemented it using current docs and advice on SDL's bugzilla.

Blocking I/O - all calls to SDL_Delay(1) removed

Much better performance, jittering gone

Actually usable now

Submitted to upstream for inclusion in the next release

fourth test case: cubeb (Firefox/SeaMonkey)

cubeb is a portable audio library written in C and C++

mainly notable because Mozilla uses it

mozilla recommends PulseAudio

... but upstream accepts patches for new backends, if tests pass

Poor native audio support - only an unofficial OSS backend

No microphone support

No device selection

Unmaintained

FreeBSD removed it, we found bugs after audio2 merge

writing a cubeb backend for NetBSD audio

Detect devices (e.g. USB microphones)

Make them available as outputs or inputs

Give them nice, user-friendly names

Uses NetBSD APIs, e.g. AUDIO_GETPROPS, AUDIO_GETFORMAT

But most of it still works on illumos

Give them nice, user-friendly names Uses NetBSD APIs, e.g. AUDIO_GETPROPS, AUDIO_GETFORMAT But most of it still works on illumos Support more channels

Support 96000 Hz and other fancy sample rates

Need to convert floats in cubeb - no support in kernel currently

cubeb uses threads - very different I/O to other code

I want the OSS backend gone

Done! Merged by upstream!

[nia note: It's now one of the best supported APIs you could use. SDL2 is now very good too, but it's not as good for recording and doesn't have multi-device support.]

questions?

I might be able to answer them

thanks for listening

I'm looking for a job btw