moq_audio/lib.rs
1//! Native audio capture, encoding, and decoding for Media over QUIC.
2//!
3//! Counterpart to [`moq-video`](https://crates.io/crates/moq-video) for audio
4//! tracks, and shaped the same way. Sits on top of [`moq_mux`] and [`hang`] and
5//! adds the missing piece for native callers: Rust-native Opus and uncompressed
6//! PCM codecs that turn raw samples into HANG audio tracks and back, plus AAC-LC,
7//! which is what the gateways (RTMP, SRT, HLS, gstreamer) publish. AAC decodes in
8//! software and encodes only through a platform encoder.
9//!
10//! - `capture` describes an audio source (`capture::Config`) and grabs buffers
11//! per platform: a microphone via cpal (CoreAudio / WASAPI / ALSA) everywhere,
12//! or macOS system audio via ScreenCaptureKit. `capture::Source` picks between
13//! them and `capture::devices` lists the inputs and hands back the ids it
14//! takes. Requires the `capture` feature, so these names are unlinked here:
15//! they don't exist in a default build.
16//! - [`encode`] encodes PCM and publishes it through `moq_mux::container`,
17//! registering the rendition in the `hang` catalog. Two entry points:
18//! - `encode::Publication` and `encode::Driver` capture a controllable
19//! microphone publication. The retained publication starts, stops, and
20//! replaces the input while preserving one track identity, and reports the
21//! active device, failures, and post-processing level.
22//! - `encode::publish_capture` is the turnkey shorthand. It encodes strictly
23//! on demand: the track and catalog are advertised up front, but the device
24//! opens only while a subscriber is listening and is released when the last
25//! one leaves.
26//! - [`encode::Producer`] publishes PCM you hand it.
27//! - [`decode`] subscribes to an encoded track and decodes it back to PCM.
28//! [`decode::Consumer`] is the mirror of [`encode::Producer`]. It reads AAC-LC
29//! too, behind the default-on `aac` feature, since a broadcast that came in
30//! through a gateway is AAC rather than one of the codecs we encode in software.
31//! - `playback` plays decoded PCM out a speaker. `playback::Engine` owns the
32//! output device and mixes the `playback::Sink`s registered with it, so one
33//! device serves every track in a call. Requires the `playback` feature, so
34//! these names are unlinked here too.
35//! - `aec` keeps the speaker out of the microphone, which is what a conference
36//! on a laptop needs to not send itself back. `playback::Engine::canceller`
37//! builds cloneable `aec::Control` handles from the mix it is playing and
38//! `capture::Config::aec` attaches their adaptive state to one microphone at
39//! a time. Requires the `aec` feature, which implies both of the above.
40//!
41//! [`Format`] mirrors WebCodecs `AudioData.format`; the helpers convert between
42//! any supported layout and the interleaved `f32` representation libopus
43//! expects. [`Frame`] is a thin owned buffer: a timestamp, a payload, and the
44//! [`Activity`] it was decoded from, which is how a caller tells coded audio
45//! from the frames an Opus sender withholds while its input is silent. PCM
46//! layout lives on the producer / consumer via [`encode::Input`] /
47//! [`decode::Output`], not on each frame, so callers can't drift between calls.
48
49#[cfg(feature = "aac")]
50mod aac;
51mod activity;
52mod error;
53mod format;
54mod frame;
55mod layout;
56mod opus;
57mod pcm;
58mod resample;
59
60#[cfg(feature = "aec")]
61pub mod aec;
62#[cfg(feature = "capture")]
63pub mod capture;
64pub mod decode;
65pub mod encode;
66
67#[cfg(feature = "playback")]
68pub mod playback;
69
70pub use activity::Activity;
71pub use error::Error;
72pub use format::Format;
73pub use frame::Frame;
74pub use layout::Layout;