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.
Discover capabilities on the control side
Section titled “Discover capabilities on the control side”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.
Handle endpoint identity by direction
Section titled “Handle endpoint identity by direction”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:
| Backend | Release posture |
|---|---|
| CoreAudio | Supported on Apple platforms; the shipped production device backend |
| Dummy | Supported for testing on macOS, Windows, and Linux |
| WASAPI | Windows source/fake-test capable only; not release-supported |
| ASIO | Windows optional source-only integration; requires a separately supplied SDK and is excluded from install/export/manifest |
| ALSA | Unavailable; not implemented as a Linux production backend |
| JACK | Unavailable; not implemented |
| PipeWire | Unavailable; 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.