From bc32792eae5cdcc72e392786a27c780ca829df2f Mon Sep 17 00:00:00 2001 From: Erwan Legrand Date: Sun, 20 Sep 2026 18:10:57 +0200 Subject: [PATCH 1/4] fix(host): gate frames_to_duration on the backends that call it WASAPI does not use the helper, so gating it on `target_os = "windows"` alone left it compiled but unused on Windows without ASIO or JACK, tripping `dead_code` under `-D warnings`. CI only ran `--all-features`, where ASIO consumes it, so this stayed hidden. Mirror the consuming backends' own module gates. --- src/host/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/host/mod.rs b/src/host/mod.rs index 801d94cff..36b72a87a 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -243,8 +243,8 @@ pub(crate) use error_emit::try_emit_error; target_os = "dragonfly", target_os = "freebsd", target_os = "netbsd", - target_os = "windows", target_vendor = "apple", + all(target_os = "windows", any(feature = "asio", feature = "jack")), all( target_arch = "wasm32", target_os = "unknown", From 4df91c06e6b8687bf9a8bb5686546fdb35014a92 Mon Sep 17 00:00:00 2001 From: Erwan Legrand Date: Sun, 20 Sep 2026 18:10:58 +0200 Subject: [PATCH 2/4] test(coreaudio): repair the iOS test module The module has not compiled since the 0.19 API changes: it was missing the `CallbackInfo` and trait imports, still constructed `SampleRate` as a tuple struct, and passed `&StreamConfig` where the config is now taken by value. CI never compiled it because clippy did not run `--all-targets`. Unverified on a device: iOS has no CI runner, so this is a compile fix only. --- src/host/coreaudio/ios/mod.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/host/coreaudio/ios/mod.rs b/src/host/coreaudio/ios/mod.rs index b7d1ed405..4099c203b 100644 --- a/src/host/coreaudio/ios/mod.rs +++ b/src/host/coreaudio/ios/mod.rs @@ -767,7 +767,10 @@ where #[cfg(test)] mod tests { - use crate::{BufferSize, SampleRate, StreamConfig}; + use crate::{ + BufferSize, CallbackInfo, StreamConfig, + traits::{DeviceTrait, HostTrait}, + }; #[test] fn test_ios_fixed_buffer_size() { @@ -776,12 +779,12 @@ mod tests { let config = StreamConfig { channels: 2, - sample_rate: SampleRate(48000), + sample_rate: 48_000, buffer_size: BufferSize::Fixed(512), }; let result = device.build_output_stream( - &config, + config, |_data: &mut [f32], _info: &CallbackInfo| {}, |_err| {}, None, From 8ffff0c2e0384848f5f066896058e9e2cc65996d Mon Sep 17 00:00:00 2001 From: Erwan Legrand Date: Sun, 20 Sep 2026 21:31:37 +0200 Subject: [PATCH 3/4] fix(coreaudio): make the overload listener teardown explicit The sender was only ever reassigned: the value captured by the listener thread is never read, so `unused_assignments` fires on stable 1.94.1 and the macOS clippy rows fail under `-D warnings`. The leading underscore silences `unused_variables`, not `unused_assignments`. Take the sender out to shut the previous listener down, and swap the replacement in with `mem::replace`, dropping the displaced sender. --- src/host/coreaudio/macos/mod.rs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/host/coreaudio/macos/mod.rs b/src/host/coreaudio/macos/mod.rs index 057246086..89aa53090 100644 --- a/src/host/coreaudio/macos/mod.rs +++ b/src/host/coreaudio/macos/mod.rs @@ -410,9 +410,9 @@ impl DefaultOutputMonitor { // These listeners target a specific device, so they must be re-registered against // whatever device is current whenever the default output reroutes. - // Held only to shut down the previous listener thread on drop when reassigned below. + // Held only to shut down the previous listener thread when the sender is dropped below. let buffer_size_listener: BufferSizeListener = Arc::new(Mutex::new(None)); - let mut _overload_shutdown_tx = match default_output_device() { + let mut overload_shutdown_tx = match default_output_device() { Some(device) => { set_buffer_size_listener( &buffer_size_listener, @@ -448,7 +448,7 @@ impl DefaultOutputMonitor { } match default_output_device() { None => { - _overload_shutdown_tx = None; + drop(overload_shutdown_tx.take()); set_buffer_size_listener(&buffer_size_listener_thread, None); report_lost( stream, @@ -463,9 +463,10 @@ impl DefaultOutputMonitor { // DefaultOutput AudioUnit rerouted automatically: recompute and notify // the buffer depth for the new device. refresh_latency(stream, &latency_refresh); - _overload_shutdown_tx = + let replacement = spawn_overload_listener(device.audio_device_id, pending_xrun.clone()) .ok(); + drop(std::mem::replace(&mut overload_shutdown_tx, replacement)); // Skipped once the monitor is dropped: there is nothing left to notify. set_buffer_size_listener( &buffer_size_listener_thread, From 61a18fbe794f1ec692ad28866e19e27e67c0369c Mon Sep 17 00:00:00 2001 From: Erwan Legrand Date: Sun, 20 Sep 2026 21:31:38 +0200 Subject: [PATCH 4/4] ci: lint all targets and the default feature set The clippy job denied warnings but ran only `--all-features` without `--all-targets`, so lints in test and example bodies went unchecked and regressions that appear only under the default feature set slipped through. Lint `--all-targets`, add default-feature rows for each host platform, and use `--workspace` instead of the deprecated `--all` alias. - Only rows that build ASIO need the SDK, so the setup step is gated on `--all-features` rather than on any non-empty feature list. Closes #1375 --- .github/workflows/quality.yml | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index e33a7f97d..5b302cc4d 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -41,12 +41,24 @@ jobs: features: --all-features os: ubuntu-latest + # Linux - ALSA backend, default features + - target: x86_64-unknown-linux-gnu + name: Linux-default + features: "" + os: ubuntu-latest + # Windows - WASAPI backend - target: x86_64-pc-windows-msvc name: Windows-x64 features: --all-features os: windows-latest + # Windows - WASAPI backend, default features + - target: x86_64-pc-windows-msvc + name: Windows-x64-default + features: "" + os: windows-latest + # Windows 32-bit - WASAPI backend - target: i686-pc-windows-msvc name: Windows-x86 @@ -59,6 +71,12 @@ jobs: features: --all-features os: ubuntu-latest + # macOS - CoreAudio backend, default features + - target: aarch64-apple-darwin + name: macOS-default + features: "" + os: ubuntu-latest + # Android - Oboe backend - target: armv7-linux-androideabi name: Android @@ -105,7 +123,8 @@ jobs: packages: libasound2-dev libjack-jackd2-dev libjack-jackd2-0 libdbus-1-dev libpipewire-0.3-dev - name: Setup ASIO SDK - if: runner.os == 'Windows' + # Only rows that build ASIO need the SDK; `--all-features` enables it. + if: runner.os == 'Windows' && contains(matrix.features, 'all-features') run: | curl -L -o asio.zip https://www.steinberg.net/asiosdk 7z x -oasio asio.zip @@ -127,7 +146,7 @@ jobs: - name: Run clippy env: CPAL_ASIO_DIR: ${{ runner.os == 'Windows' && format('{0}/asio', github.workspace) || '' }} - run: cargo clippy --all --target ${{ matrix.target }} ${{ matrix.features }} -- -D warnings + run: cargo clippy --workspace --all-targets --target ${{ matrix.target }} ${{ matrix.features }} -- -D warnings docs: strategy: @@ -209,4 +228,4 @@ jobs: - name: Run clippy env: RUSTFLAGS: ${{ matrix.rustflags }} - run: cargo +nightly clippy --all --target ${{ matrix.target }} ${{ matrix.features }} -Z build-std=${{ matrix.build_std }} -- -D warnings + run: cargo +nightly clippy --workspace --all-targets --target ${{ matrix.target }} ${{ matrix.features }} -Z build-std=${{ matrix.build_std }} -- -D warnings