Skip to main content

tympan_aspl/
lib.rs

1//! `tympan-aspl` — a Rust framework for writing macOS
2//! AudioServerPlugins.
3//!
4//! AudioServerPlugins are the user-space audio drivers that run
5//! inside `coreaudiod` and appear to the system as audio devices.
6//! `tympan-aspl` provides safe Rust abstractions over the Core Audio
7//! HAL AudioServerPlugin C interface so a Rust crate can implement a
8//! virtual audio device — a loopback, a virtual microphone, a
9//! routing or processing driver — without writing C++ or
10//! Objective-C.
11//!
12//! See `docs/overview.md` for the project's scope and
13//! `docs/architecture.md` for the design that drives this crate.
14//!
15//! ## Layering
16//!
17//! The crate is built bottom-up in conceptual layers, isolated by
18//! module boundary:
19//!
20//! - [`raw`] — the low-level FFI to the AudioServerPlugin C ABI.
21//!   Its ABI type definitions ([`raw::abi`]) and marshalling
22//!   ([`raw::marshal`]) are plain data, compiled and tested on every
23//!   host; only the live `extern "C"` entry points and
24//!   CoreFoundation calls (a later PR) are macOS-gated.
25//! - [`realtime`] — allocation-free, lock-free primitives for the
26//!   `IOProc` realtime callback. Cross-platform, so the realtime
27//!   invariants are unit-testable on any host.
28//! - The object model — [`error`], [`fourcc`], [`object`],
29//!   [`property`], [`mod@format`], [`io`] — cross-platform
30//!   plain-data mirrors of the Core Audio C types.
31//! - The property protocol — [`objects`] (the object tree) and
32//!   [`dispatch`] (the cross-platform answer to the HAL's property
33//!   reads).
34//! - The public API — [`driver`], [`device`], [`stream`] — the
35//!   traits and declarative types a consumer implements against.
36//! - [`bundle`] — `.driver` bundle `Info.plist` generation.
37//!
38//! ## Realtime safety
39//!
40//! Any code reachable from the `IOProc` realtime callback must be
41//! allocation-free, lock-free, and free of blocking syscalls. The
42//! [`realtime`] module exposes a [`RealtimeContext`] marker that
43//! acts as a compile-time witness for the realtime context;
44//! [`Driver::process_io`] takes one. Mechanical enforcement lives in
45//! `tests/realtime_safety.rs` via an `assert_no_alloc`
46//! global-allocator guard.
47//!
48//! ## Implementing a driver
49//!
50//! A consumer implements [`Driver`] for a type carrying its
51//! per-plug-in state, describes the device it exposes with a
52//! [`DeviceSpec`], and — on macOS — exposes the type as a CFPlugIn
53//! with the [`plugin_entry!`] macro.
54
55// Crate-wide policy for the realtime-safety lints declared in
56// `clippy.toml`. The `disallowed-types` and `disallowed-methods`
57// lists target items that have no business in a realtime path —
58// blocking syncs, kernel syscalls, sleeping primitives — and the
59// rest of the crate (initialisation paths, bundle generation,
60// tests, non-realtime support code) is free to use them. The
61// `realtime` module re-enables the lints at `deny` in its own
62// `mod.rs`, so the strict allow-list applies exactly where the
63// realtime invariants live.
64#![allow(clippy::disallowed_methods, clippy::disallowed_types)]
65
66pub mod bundle;
67pub mod device;
68pub mod dispatch;
69pub mod driver;
70pub mod error;
71pub mod format;
72pub mod fourcc;
73pub mod io;
74pub mod object;
75pub mod objects;
76pub mod property;
77pub mod realtime;
78pub mod stream;
79
80// The `raw` module's ABI type definitions and marshalling are
81// plain data — they compile and are tested on every host. Only its
82// live `extern "C"` entry points and CoreFoundation calls (a later
83// PR) are `cfg(target_os = "macos")`-gated, from within the module.
84pub mod raw;
85
86// `plugin_entry!` is defined on every platform so its documentation
87// and intra-doc links resolve in `cargo doc`, but it can only be
88// *expanded* on macOS: the factory it emits forwards to the
89// `cfg(target_os = "macos")`-gated `raw` module.
90mod macros;
91
92pub use bundle::BundleConfig;
93pub use device::{Device, DeviceId, DeviceSpec};
94pub use dispatch::DeviceState;
95pub use driver::{AnyDriver, Driver, DriverInfo};
96pub use error::OsStatus;
97pub use format::{FormatNegotiation, SampleFormat, StreamFormat};
98pub use fourcc::FourCharCode;
99pub use io::{IoBuffer, IoOperation, Sample, Timestamp};
100pub use object::{AudioObjectId, ObjectKind};
101pub use objects::{Object, ObjectMap};
102pub use property::{
103    PropertyAddress, PropertyElement, PropertyScope, PropertySelector, PropertyValue, ValueRange,
104};
105pub use realtime::RealtimeContext;
106pub use stream::{StreamDirection, StreamSpec};