Releases: RustAudio/cpal
cpal 0.18.1
A quick follow-up to 0.18.0 primarily to fix the docs.rs build failure.
docs.rs: Excludedpipewire, whose system dependency isn't available in that sandboxed build environment.- WASM: Fixed the
audioworkletfeature failing to compile onwasm32-wasip1and other non-browserwasm32targets.
No API or behavioral changes.
Links
cpal 0.18.0
Hey everyone! cpal 0.18.0 is out, bringing two long-requested native Linux backends, a unified error API, and accurate timestamps across every platform.
What's New
Native PipeWire and PulseAudio
Two new first-class backends join the Linux and BSD lineup:
- PipeWire
- PulseAudio
Enable them with the pipewire and pulseaudio Cargo features. When multiple backends are compiled in, cpal selects the best available one at runtime: PipeWire > PulseAudio > ALSA.
Unified Error API
All per-operation error enums (DevicesError, BuildStreamError, StreamError, etc.) are replaced by a single cpal::Error with a kind() getter:
match device.default_output_config() {
Err(e) => match e.kind() {
cpal::ErrorKind::DeviceNotAvailable => { /* ... */ }
cpal::ErrorKind::DeviceBusy => { /* retry */ }
_ => { /* ... */ }
}
}Two new error kinds make previously indistinguishable cases actionable: DeviceBusy (EBUSY/EAGAIN is retryable) and PermissionDenied for OS-level access denials. See the upgrading guide for the mapping table.
Accurate Timestamps and A/V Sync
Timestamps previously reflected when the callback fired rather than when audio would actually reach hardware. This release corrects that across every backend:
- AAudio: pipeline buffer depth accounted for; fallback to zero on error fixed
- ALSA:
LinkSynchronizedhardware cross-timestamps for reduced jitter on supported devices - ASIO: driver-reported hardware latency included; re-queried on
kAsioLatenciesChanged - CoreAudio: device latency and safety offset included
- JACK: precise hardware cycle deadline; input capture timestamps were previously using callback execution time
- WASAPI: hardware pipeline latency included
- WebAudio: base and output latency included
A new StreamTrait::now() method lets you query the stream's clock from outside the callback for A/V sync: read the audio clock at any point and correlate it with your video timeline.
48 kHz is the New Default
default_input_config() and default_output_config() now prefer 48 kHz, then 44.1 kHz, on all backends. Defaulting to 44.1 kHz meant cpal's chosen rate often didn't match the hardware's preferred rate. Pin it explicitly if you need 44.1 kHz.
New API
StreamTrait::buffer_size()queries the stream's current buffer sizeSupportedStreamConfigRange::try_with_standard_sample_rate()/with_standard_sample_rate()snaps to 48 kHz or 44.1 kHz from a supported range
Platform Improvements
-
ALSA:
device_by_id()now accepts PCM shorthand names likehw:0,0andplughw:foo; streams attempt to recover after system suspend; capture streams no longer hang on overruns; backward-stepping timestamps during startup and xrun recovery are fixed. -
ASIO:
collect()on the device iterator no longer stops after the first device; device enumeration and stream creation now work correctly when called from spawned threads; distortion from drivers that fire the buffer callback multiple times per cycle is fixed. -
CoreAudio: the physical stream format is now set directly on the hardware device rather than relying on the HAL mixer; user-specified timeouts are now respected when building a stream.
-
JACK: buffer size changes no longer fire an error callback but resizes internal buffers, avoiding unnecessary stream rebuilds; server shutdown now surfaces as
ErrorKind::DeviceNotAvailable. -
WASAPI: device names now prefer
FriendlyNameoverDeviceDesc, so you see the readable name from system settings; default streams automatically reroute when the system default device changes.
...and a lot more. The changelog has the full picture.
Breaking Changes
- Streams now require an explicit
play()call: ALSA, CoreAudio, and JACK previously auto-started streams on creation. If you never calledplay(), your callback will never fire after upgrading. Errortypes unified: match one.kind()instead of per-operation error enums.StreamConfigpassed by value:StreamConfignow implementsCopy; drop the&atbuild_*_streamcall sites.StreamInstantAPI overhauled: aligns withstd::time::Instant. Changeadd/subtochecked_add/checked_sub(or+/-);duration_sincereturnsDuration(saturating), secs/nanos are nowu64.- Default sample rate is now 48 kHz: pin explicitly if you need 44.1 kHz.
- Default sample format heuristics now fully ranked: floats before integers, higher bit-depth before lower; pin
F32explicitly if you were relying on it as the default. - Emscripten host removed: migrate to
wasm32-unknown-unknownwith thewasm-bindgenfeature.
Full details and migration examples in the upgrading guide.
Looking Ahead to v0.19
The design goals are tracked in #1220. Highlights:
- Extension traits: clean access to platform-specific functionality like RAW mode on WASAPI, control panel on ASIO, identifying stream properties on PipeWire, etc.
- Exclusive mode on CoreAudio and WASAPI
- Duplex stream API
- Input streams on WASM: microphone access from the browser
- Stream lifecycle normalization:
play/pausetostart/pause/stopwith a draining stop - Native DSD on WASAPI
BufferSizerefactor with range support
The feature set may change.
Thanks to Our Contributors
16 people contributed to this release, 13 of them for the first time: Access (@Decodetalkers), atlv (@atlv24), Chandler Newman (@csnewman), Colin Marc (@colinmarc), Edwin Löffler (@edwloef), Jerry.Wang (@wangjia184), Mat Silverstein (@silverstein), Mike Hilgendorf (@m-hilgendorf), osoftware (@osoftware), Raphael Poss (@knz), Seto Elkahfi (@setoelkahfi), Sintel (@Sin-tel), thewh1teagle (@thewh1teagle), Umer Haider (@umerhd), and Worik Stanton (@worikgh). Welcome aboard, and thank you all!
Support the Project
If you find value in cpal, sponsorships are a heartfelt token of appreciation and help cover the costs of building it: music service subscriptions, hardware for cross-platform compatibility, and tooling. Every contribution helps: sponsor me at GitHub.
Links
- Crate Home & README
- Documentation
- Changelog
- Upgrading Guide
- RustAudio Discord (#cpal channel)
Huge thanks to everyone who contributed to this release!
asio-sys 0.3.0
Added
- Added
Driver::latencies()to query input and output stream latencies - Added
BufferPreferenceenum with the driver's preferred buffer size and valid-size constraints
Changed
Driver::add_message_callbackandDriver::remove_message_callbackreplaced byDriver::add_event_callbackandDriver::remove_event_callbackMessageCallbackrenamed toDriverEventCallback, andMessageCallbackIdrenamed toDriverEventCallbackId.DriverEventCallbackwrapsFn(AsioDriverEvent) -> boolwhereAsioDriverEventis a new enum covering bothasioMessageselector events andsampleRateDidChangenotificationsCallbackIdrenamed toBufferCallbackId- Public-facing
c_longfields and return types replaced withi32 - Public-facing
c_doubleparameters and return types replaced withf64 CallbackInfo::system_timeis nowu64nanosecondsAsioError::ASE_NoMemoryrenamed toAsioError::NoMemory- Extended
BufferSizeRangewith apreferred: BufferPreferencefield AsioTime::reserved,AsioTimeInfo::reserved,AsioTimeCode::futurefields made private.asio_importmodule is nowpub(crate); raw bindgen types are no longer public APIasio_messagenow dispatcheskAsioResyncRequestandkAsioLatenciesChangedto callbacksasio_messagedelegateskAsioSelectorSupportedfor unknown selectors to registered callbacks, so each host decides which capabilities it opts intosample_rate_did_changenow dispatchesAsioDriverEvent::SampleRateChangedto registered callbacks when the reported rate differs from the last known rate
Fixed
- Fixed TOCTOU race condition when creating streams concurrently
- Fixed data race where
channels,latencies,sample_rate, and related query methods could call ASIO concurrently duringset_sample_rate's teardown/reload - Fixed
Asio::load_driverto returnLoadDriverError::LoadDriverFailedinstead of panicking when the driver name contains a null byte - Fixed
Driver::set_sample_rateto perform a dummy buffer cycle and driver reload when the driver does not apply the rate change immediately, as required by some drivers (e.g. Steinberg) - Fixed
asio_messagenot advertisingkAsioSelectorSupporteditself as a supported selector - Fixed rust-analyzer errors on non-Windows targets by using stub instead of ASIO bindings
Removed
- Removed unused
SampleRatestruct - Removed
DriverStatefrom the public API
cpal 0.17.3
Changed
- Reverted SemVer-breaking
DeviceBusyerror variant addition.
Fixed
- ASIO: Fix linker errors.
asio-sys 0.2.6
Fixed
- Link
advapi32to resolve Windows Registry API symbols.
cpal 0.17.2
This release was yanked.
Added
DeviceBusyerror variant for retriable device access errors (EBUSY,EAGAIN).- ALSA:
Debugimplementations forHost,Device,Stream, and internal types. - ALSA: Example demonstrating ALSA error suppression during enumeration.
- WASAPI: Enable as-necessary resampling in the WASAPI server process.
Changed
- Bump overall MSRV to 1.78.
- ALSA: Update
alsadependency to 0.11. - ALSA: Bump MSRV to 1.82.
- CoreAudio: Update
core-audio-rsdependency to 0.14.
Fixed
- ALSA: Enumerating input and output devices no longer interferes with each other.
- ALSA: Device handles are no longer exclusively held between operations.
- ALSA: Reduce Valgrind memory leak reports from ALSA global configuration cache.
- ALSA: Fix possible race condition on drop.
- ALSA: Fix audio callback stalling when start threshold is not met.
cpal 0.17.1
Added
- ALSA:
Defaultimplementation forDevice(returns the ALSA "default" device). - CI: Checks default/no-default/all feature sets with platform-dependent MSRV for JACK.
Fixed
- ALSA: Device enumeration now includes both hints and physical cards.
- JACK: No longer builds on iOS.
- WASM: WasmBindgen no longer crashes (regression from 0.17.0).
Changed
- ALSA: Devices now report direction from hint metadata and physical hardware probing.
asio-sys 0.2.5
Fixed
- Fixed ASIO SDK discovery on case sensitive filesystems.
cpal 0.17.0
Added
DeviceTrait::idmethod that returns a stable audio device ID.HostTrait::device_by_idto select a device by its stable ID.DisplayandFromStrimplementations forHostId.- Support for custom
Hosts,Devices, andStreams. Sample::bits_per_samplemethod.Copyimplementation toInputCallbackInfoandOutputCallbackInfo.StreamError::StreamInvalidatedvariant for when stream must be rebuilt.StreamError::BufferUnderrunvariant for buffer underrun/overrun notifications.Hashimplementation toDevicefor all backends.- AAudio:
SendandSyncimplementations toStream. - AAudio: Support for 12 and 24 kHz sample rates.
- ALSA:
I24andU24sample format support (24-bit samples stored in 4 bytes). - ALSA: Support for 12, 24, 352.8, 384, 705.6, and 768 kHz sample rates.
- ALSA:
EqandPartialEqimplementations toDevice. - CI: Native ARM64 Linux support in GitHub Actions.
- CoreAudio:
i8,i32andI24sample format support (24-bit samples stored in 4 bytes). - CoreAudio: Support for loopback recording (recording system audio output) on macOS > 14.6.
- CoreAudio:
Sendimplementation toStream. - Emscripten:
BufferSize::Fixedvalidation against supported range. - iOS: Complete AVAudioSession integration for device enumeration and buffer size control.
- JACK: Support for macOS and Windows platforms.
- JACK:
BufferSize::Fixedvalidation to reject requests that don't match server buffer size. - WASAPI: Expose
IMMDevicefrom WASAPI host Device. - WASAPI:
I24andU24sample format support (24-bit samples stored in 4 bytes). - WASAPI:
SendandSyncimplementations toStream. - WebAudio:
SendandSyncimplementations toStream. - WebAudio:
BufferSize::Fixedvalidation against supported range.
Changed
- MSRV depends on the platform and at minimum 1.77.
- Set examples to Rust 2021.
SampleRatefrom struct tou32type alias.- Update
audio_thread_priorityto 0.34. - Migrate CHANGELOG to Keep a Changelog format.
- AAudio: Configure buffer to ensure consistent callback buffer sizes.
- AAudio: Buffer size range detection to query the AudioService property correctly.
- ALSA: Improve
BufferSize::Fixedprecision and audio callback performance. - ALSA:
BufferSize::Defaultto use the device defaults. - ALSA: Card enumeration to work like
aplay -Ldoes. - ALSA: Update
alsato 0.10. - ALSA: Pass
silent=truetoPCM.try_recover, so it doesn't write to stderr. - ALSA: Report buffer underruns/overruns via
StreamError::BufferUnderrun. - ASIO: Share
sys::Asioinstance across allHostinstances. - CI: Fix cargo publish to trigger on GitHub releases instead of every master commit.
- CI: Replace cargo install commands with cached tool installation for faster builds.
- CI: Update actions to latest versions (checkout@v5, rust-cache@v2).
- CI: Verify compatibility with windows crates since v0.59.
- CI: Test platforms on appropriate MSRV per backend.
- CI: Fix
cargo updatesyntax for compatibility with Cargo 1.70 (use-pflag instead of positional argument). - CoreAudio:
Device::supported_configsto return a single element containing the available sample rate range when all elements have the samemMinimumandmMaximumvalues. - CoreAudio: Default audio device detection to be lazy when building a stream, instead of during device enumeration.
- CoreAudio: Configure device buffer to ensure predictable callback buffer sizes.
- CoreAudio: Remove
Cloneimplementation fromStream. - JACK: Use
StreamError::StreamInvalidatedfor JACK server sample rate changes. - JACK: Report buffer underruns/overruns via
StreamError::BufferUnderrun. - WASAPI: Update
windowsto >= 0.59, <= 0.62.
Fixed
- ALSA: Format selection to probe hardware endianness instead of assuming native byte order.
- ALSA: Data race in stream shutdown.
- ASIO: Handling for
kAsioResetRequestmessage to prevent driver UI becoming unresponsive. - ASIO: Buffer silencing logic to work with non-conformant drivers (e.g., FL Studio ASIO).
- CoreAudio: Timestamp accuracy.
- CoreAudio: Segfaults when enumerating devices.
- CoreAudio: Undefined behavior related to null pointers and aligned reads.
- CoreAudio: Unnecessary microphone permission requests when using output devices only.
- iOS: Example by properly activating audio session.
Removed
- WebAudio: Optional
wee-allocfeature for security reasons.
asio-sys 0.2.4
Fixed
- Fixed docs.rs documentation build by generating stub bindings when building for docs.rs
- Fixed buffer switch detection to work correctly with non-conformant ASIO drivers