diff --git a/Cargo.lock b/Cargo.lock index a10a4220..58a145c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,20 +112,12 @@ checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" [[package]] name = "alsa" version = "0.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed7572b7ba83a31e20d1b48970ee402d2e3e0537dcfe0a3ff4d6eb7508617d43" -dependencies = [ - "alsa-sys", - "bitflags 2.11.1", - "cfg-if", - "libc", -] [[package]] name = "alsa" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c88dbbce13b232b26250e1e2e6ac18b6a891a646b8148285036ebce260ac5c3" +checksum = "812947049edcd670a82cd5c73c3661d2e58468577ba8489de58e1a73c04cbd5d" dependencies = [ "alsa-sys", "bitflags 2.11.1", @@ -135,9 +127,9 @@ dependencies = [ [[package]] name = "alsa-sys" -version = "0.3.1" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db8fee663d06c4e303404ef5f40488a53e062f89ba8bfed81f42325aafad1527" +checksum = "ad7569085a265dd3f607ebecce7458eaab2132a84393534c95b18dcbc3f31e04" dependencies = [ "libc", "pkg-config", @@ -521,7 +513,7 @@ dependencies = [ "bytemuck", "coreaudio-rs 0.13.0", "cosmic-text", - "cpal 0.17.1", + "cpal 0.17.3", "crossbeam-channel", "fontdb", "half", @@ -2624,6 +2616,20 @@ dependencies = [ "objc2-core-foundation", ] +[[package]] +name = "coreaudio-rs" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5d7dca3ebcf65a035582c9ad4385371a9d9ee6537474d2a278f4e1e475bb58" +dependencies = [ + "bitflags 2.11.1", + "libc", + "objc2-audio-toolbox", + "objc2-core-audio", + "objc2-core-audio-types", + "objc2-core-foundation", +] + [[package]] name = "coreaudio-sys" version = "0.2.17" @@ -2682,12 +2688,12 @@ dependencies = [ [[package]] name = "cpal" -version = "0.17.1" +version = "0.17.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b1f9c7312f19fc2fa12fd7acaf38de54e8320ba10d1a02dcbe21038def51ccb" +checksum = "d8942da362c0f0d895d7cac616263f2f9424edc5687364dfd1d25ef7eba506d7" dependencies = [ - "alsa 0.10.0", - "coreaudio-rs 0.13.0", + "alsa 0.11.0", + "coreaudio-rs 0.14.2", "dasp_sample", "jni 0.21.1", "js-sys", @@ -2707,7 +2713,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows 0.62.2", + "windows 0.61.3", ] [[package]] @@ -3110,7 +3116,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -3368,8 +3374,8 @@ dependencies = [ "libc", "log", "rustversion", - "windows-link 0.2.1", - "windows-result 0.4.1", + "windows-link 0.1.3", + "windows-result 0.3.4", ] [[package]] @@ -3461,7 +3467,7 @@ dependencies = [ "vec_map", "wasm-bindgen", "web-sys", - "windows 0.62.2", + "windows 0.54.0", ] [[package]] @@ -3968,7 +3974,7 @@ checksum = "3640c1c38b8e4e43584d8df18be5fc6b0aa314ce6ebf51b53313d4306cca8e46" dependencies = [ "hermit-abi", "libc", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -4567,7 +4573,7 @@ version = "0.50.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.59.0", ] [[package]] @@ -5806,7 +5812,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7441,7 +7447,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7476,23 +7482,11 @@ version = "0.61.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9babd3a767a4c1aef6900409f85f5d53ce2544ccdfaa86dad48c91782c6d6893" dependencies = [ - "windows-collections 0.2.0", + "windows-collections", "windows-core 0.61.2", - "windows-future 0.2.1", + "windows-future", "windows-link 0.1.3", - "windows-numerics 0.2.0", -] - -[[package]] -name = "windows" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527fadee13e0c05939a6a05d5bd6eec6cd2e3dbd648b9f8e447c6518133d8580" -dependencies = [ - "windows-collections 0.3.2", - "windows-core 0.62.2", - "windows-future 0.3.2", - "windows-numerics 0.3.1", + "windows-numerics", ] [[package]] @@ -7504,15 +7498,6 @@ dependencies = [ "windows-core 0.61.2", ] -[[package]] -name = "windows-collections" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23b2d95af1a8a14a3c7367e1ed4fc9c20e0a26e79551b1454d72583c97cc6610" -dependencies = [ - "windows-core 0.62.2", -] - [[package]] name = "windows-core" version = "0.54.0" @@ -7549,19 +7534,6 @@ dependencies = [ "windows-strings 0.4.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement 0.60.2", - "windows-interface 0.59.3", - "windows-link 0.2.1", - "windows-result 0.4.1", - "windows-strings 0.5.1", -] - [[package]] name = "windows-future" version = "0.2.1" @@ -7570,18 +7542,7 @@ checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" dependencies = [ "windows-core 0.61.2", "windows-link 0.1.3", - "windows-threading 0.1.0", -] - -[[package]] -name = "windows-future" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d6f90251fe18a279739e78025bd6ddc52a7e22f921070ccdc67dde84c605cb" -dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", - "windows-threading 0.2.1", + "windows-threading", ] [[package]] @@ -7650,16 +7611,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-numerics" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e40844ac143cdb44aead537bbf727de9b044e107a0f1220392177d15b0f26" -dependencies = [ - "windows-core 0.62.2", - "windows-link 0.2.1", -] - [[package]] name = "windows-result" version = "0.1.2" @@ -7687,15 +7638,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-strings" version = "0.1.0" @@ -7715,15 +7657,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows-sys" version = "0.45.0" @@ -7800,15 +7733,6 @@ dependencies = [ "windows-link 0.1.3", ] -[[package]] -name = "windows-threading" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3949bd5b99cafdf1c7ca86b43ca564028dfe27d66958f2470940f73d86d75b37" -dependencies = [ - "windows-link 0.2.1", -] - [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" diff --git a/Cargo.toml b/Cargo.toml index ed50fae9..038a0b84 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,9 @@ kira = { path = "third_party/kira" } # cost ~7 ms a raise — invisibly, for the raises an addon wraps in `pcall`: five a frame measured # 44.7 ms of VM tick with an empty error log (`third_party/mlua-sys/BENILLA.md`). mlua-sys = { path = "third_party/mlua-sys" } +# A lock-only stand-in: bevy_audio's unbuilt cpal 0.15 would otherwise hold `alsa-sys` 0.3 against +# cpal 0.17's 0.4, and a lock holds one `links = "alsa"` (`third_party/alsa-0.9/BENILLA.md`). +alsa = { path = "third_party/alsa-0.9" } # Dependencies at opt-level 3 in dev: at opt-level 0, avian/parry collision drops a run to <1 fps. # Line tables only, and never packed into the binary, for the reason under `[profile.dev]` below. diff --git a/crates/benilla-app/src/sound/output/cpal.rs b/crates/benilla-app/src/sound/output/cpal.rs index 356edfe0..c5490a19 100644 --- a/crates/benilla-app/src/sound/output/cpal.rs +++ b/crates/benilla-app/src/sound/output/cpal.rs @@ -332,6 +332,13 @@ pub(super) struct Notices { /// The device watch: a thread that re-reads the host's default output every [`WATCH_EVERY`] and /// raises a notice when it changes. One-shot: the backend answers a notice by rebuilding the /// stream, which arms a fresh watch. +/// +/// Deviation: a change of the default output device is followed (here and in `coreaudio.rs`), where +/// 1.12.1 initialises its sound device once and never again (`Sound::Initialize` `0x7a4330` +/// refuses a second call; the driver-enumeration functions `0x7a6320`-`0x7a6380` have no caller), +/// because a headset plugged in mid-session should play at once. On ALSA the watch sees only the +/// "default" PCM, whose id never changes, so on Linux it is the sound server (PipeWire or Pulse) +/// that moves the stream. pub(super) struct Listeners { stop: Arc, thread: Option>, diff --git a/crates/benilla-app/src/sound/output/mod.rs b/crates/benilla-app/src/sound/output/mod.rs index 29513f33..ab9e5178 100644 --- a/crates/benilla-app/src/sound/output/mod.rs +++ b/crates/benilla-app/src/sound/output/mod.rs @@ -650,8 +650,8 @@ fn render_loop( period_ns: u64, ) { // Held for the thread's life: on Windows its drop hands the MMCSS registration back. - // `WOW_AUDIO_NO_RT=1` skips realtime for the user-interactive QoS fallback, an A/B lever for - // the render thread preempting the compute pools. + // `WOW_AUDIO_NO_RT=1` skips realtime for the fallback (user-interactive QoS on macOS), an A/B + // lever for the render thread preempting the compute pools. let no_rt = std::env::var_os("WOW_AUDIO_NO_RT").is_some(); let realtime = if no_rt { Err(anyhow::anyhow!("WOW_AUDIO_NO_RT=1")) @@ -667,7 +667,13 @@ fn render_loop( Some(realtime) } Err(e) => { - warn!("audio: render thread could not go realtime ({e}); using user-interactive QoS"); + // `promote_current_thread` is a no-op off macOS, so the thread keeps its normal priority. + let fallback = if cfg!(target_os = "macos") { + "user-interactive QoS" + } else { + "normal thread priority" + }; + warn!("audio: render thread could not go realtime ({e}); using {fallback}"); benilla_world::thread_qos::promote_current_thread( benilla_world::thread_qos::QosClass::UserInteractive, ); diff --git a/third_party/alsa-0.9/BENILLA.md b/third_party/alsa-0.9/BENILLA.md new file mode 100644 index 00000000..79571728 --- /dev/null +++ b/third_party/alsa-0.9/BENILLA.md @@ -0,0 +1,18 @@ +# A lock-only stand-in for `alsa` 0.9.1 + +Written by benilla, MIT OR Apache-2.0; it contains no upstream code. Wired in through +`[patch.crates-io]` in the workspace root. + +Why: `alsa-sys` declares `links = "alsa"`, and a lockfile may hold one version of it. `cpal` 0.17.3, +our audio device layer off macOS, takes `alsa` 0.11 and so `alsa-sys` 0.4. `bevy_internal` lists +`bevy_audio` as a weak optional dependency (`bevy_audio?/android_shared_stdcxx`), which puts +`bevy_audio`, its `cpal` 0.15.3 and so `alsa` 0.9.1 and `alsa-sys` 0.3 into the lock although the +workspace never enables bevy's audio (`Cargo.toml`, `bevy`). The two `links` collide and the +resolver refuses. This package satisfies `cpal` 0.15.3's `alsa = "0.9"` with no dependency on +`alsa-sys`. + +It is never compiled: `cargo tree --target all` holds no `cpal` 0.15. If bevy's audio were enabled, +the build would stop at the `compile_error!` in `src/lib.rs`, which says why. + +Drop it when the lock holds no `bevy_audio` (a bevy that no longer lists it) or when bevy's +`cpal` takes `alsa` 0.11. diff --git a/third_party/alsa-0.9/Cargo.toml b/third_party/alsa-0.9/Cargo.toml new file mode 100644 index 00000000..e4d74eb3 --- /dev/null +++ b/third_party/alsa-0.9/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "alsa" +version = "0.9.1" +edition = "2021" +license = "MIT OR Apache-2.0" +description = "Lock-only stand-in for alsa 0.9.1; see BENILLA.md" diff --git a/third_party/alsa-0.9/src/lib.rs b/third_party/alsa-0.9/src/lib.rs new file mode 100644 index 00000000..a0f2da3b --- /dev/null +++ b/third_party/alsa-0.9/src/lib.rs @@ -0,0 +1,4 @@ +compile_error!( + "third_party/alsa-0.9 is a lock-only stand-in: bevy_audio and its cpal 0.15 are not built. \ + See third_party/alsa-0.9/BENILLA.md." +);