Skip to content

Audio devices

Device-backed hosting is an optional layer around the host-neutral SDK. Discover a backend’s actual capabilities and release status before presenting a route. Do not infer support from an operating-system label, a backend enum, or a source tree that happens to compile.

Create the driver manager and enumerate devices from a control/UI thread. Enumeration may briefly query hardware. For a selected stable device ID, inspect direction-specific endpoint capabilities: availability, input/output support, channel descriptors, supported sample rates, supported buffer sizes, and whether the endpoint is currently in use. Human-readable names are presentation fields; stable backend IDs are route-selection keys.

For a driver, getCapabilities() reports channel ranges, native rates and buffer sizes, input and multichannel support, hot-swap support, and whether hardware latency is reported. Use those facts instead of parsing a backend-name string. A route compatibility probe can report unavailable input/output, unsupported rate, invalid channel map, permission denial, backend failure, or profile conflict before activation.

Enumeration, detailed queries, and activation are control/UI operations. Current-device, current-rate, and current-buffer queries are safe to poll from any thread.

Source: audio_driver_manager.h, audio_driver_manager.h, and audio_driver.h.

An AudioDriverConfig has separate input and output IDs and channel counts. On CoreAudio, IDs are direction-specific physical endpoint UIDs; an empty ID selects that direction’s current system default. Do not copy an output UID into the input field or silently substitute a different endpoint when a requested direction is absent.

Output-only routes have their own request shape: an empty output ID follows the backend’s current default, while a nonempty ID is never defaulted. Requested output channels identify physical output indices and must be valid for the selected endpoint. A request that requires a different count should be reported as incompatible rather than silently mixed to a closest format.

Source: audio_driver.h, audio_driver.h, and audio_driver.h.

Use Dummy for host-neutral and test workflows

Section titled “Use Dummy for host-neutral and test workflows”

The Dummy driver is available on every platform for testing without hardware. It exercises host-neutral setup and callback lifecycle without claiming a production device route. Use it for deterministic package or transport checks; do not present it as a substitute for hardware acceptance or as evidence that a platform device backend is release-supported.

The support matrix currently distinguishes the shipped production backend from source or fake-test capabilities:

BackendRelease posture
CoreAudioSupported on Apple platforms; the shipped production device backend
DummySupported for testing on macOS, Windows, and Linux
WASAPIWindows source/fake-test capable only; not release-supported
ASIOWindows optional source-only integration; requires a separately supplied SDK and is excluded from install/export/manifest
ALSAUnavailable; not implemented as a Linux production backend
JACKUnavailable; not implemented
PipeWireUnavailable; not implemented

Linux therefore has host-neutral core/package support and Dummy only for device-facing tests; it has no released production device backend. A backend is not promoted by compilation alone.

Source: audio_driver_manager.h, audio_driver.h, and SUPPORT_MATRIX.md.

Treat activation and reinitialization as transactions

Section titled “Treat activation and reinitialization as transactions”

setActiveDevice() creates and initializes a candidate before stopping the current driver. If candidate creation or stop fails, the current driver and configuration are preserved. On success, ownership and configuration commit atomically, then the device-change callback runs after the manager lock is released. A successful switch may cause a brief dropout.

Runtime route state is separate from selection state. A terminal route outcome means rendering has stopped and the driver requires an explicit initialize() with a host-selected configuration. Poll getTelemetry() and getAudioIoRouteState() from control code; do not assume automatic endpoint fallback. Outcomes include rate or format changes, invalid channel maps, direction-specific unavailability, permission denial, conversion failure, profile conflict, and backend failure.

When a route fails, preserve the reported endpoint identity and backend error, stop using the inactive callback, and explicitly re-probe or reinitialize only after the host has selected a valid configuration. Never switch to an arbitrary fallback endpoint as an implicit recovery policy.

Source: audio_driver_manager.h, audio_driver.h, and audio_driver.h.