diff --git a/crates/qbz-audio/src/dac_probe.rs b/crates/qbz-audio/src/dac_probe.rs index 7d6f2fc1e..bb92fce8b 100644 --- a/crates/qbz-audio/src/dac_probe.rs +++ b/crates/qbz-audio/src/dac_probe.rs @@ -11,6 +11,8 @@ //! bit-perfect / sample-rate-passthrough path is untouched. use serde::{Deserialize, Serialize}; +// Every target but Windows still runs `pw-dump`. +#[cfg(not(windows))] use std::process::Command; /// The DAC's live, negotiated hardware state — what the card is REALLY clocked @@ -94,6 +96,18 @@ pub fn parse_alsa_card_for_node(json: &str, node_name: &str) -> Option { } /// Resolve the ALSA card number for a sink node by running `pw-dump`. +/// +/// W14, Windows only: `pw-dump` does not exist there, so the spawn already +/// failed into this same None. Scoped to Windows rather than `not(linux)` -- +/// a macOS or BSD box can have a real `pw-dump`, and this function is not the +/// place to decide it may not speak. +#[cfg(windows)] +fn alsa_card_for_node(_node_name: &str) -> Option { + None +} + +/// Resolve the ALSA card number for a sink node by running `pw-dump`. +#[cfg(not(windows))] fn alsa_card_for_node(node_name: &str) -> Option { let output = Command::new("pw-dump").output().ok()?; if !output.status.success() { diff --git a/crates/qbz-audio/src/health.rs b/crates/qbz-audio/src/health.rs index e1de1b85f..1db1fa5e7 100644 --- a/crates/qbz-audio/src/health.rs +++ b/crates/qbz-audio/src/health.rs @@ -5,6 +5,8 @@ //! the check step can show the right `apt`/`dnf`/`pacman` remediation. None of //! this opens a stream — purely diagnostic. +// Every target but Windows still probes; see `audio_stack_health`. +#[cfg(not(windows))] use std::process::Command; /// Result of the audio-stack probes. All best-effort; a failed probe reads as @@ -32,7 +34,8 @@ impl AudioStackHealth { } } -/// True if `sh -c ""` exits 0. +/// True if `sh -c ""` exits 0. Windows never probes; see below. +#[cfg(not(windows))] fn sh_ok(probe: &str) -> bool { Command::new("sh") .arg("-c") @@ -44,6 +47,31 @@ fn sh_ok(probe: &str) -> bool { /// Run the audio-stack probes. Linux-only meaningfully; elsewhere everything /// reads false except where trivially true. +/// +/// W14: on WINDOWS ONLY the answer is all-false, returned WITHOUT running the +/// probes. `systemctl`, `pactl` and `pw-dump` do not exist there (a spawn of a +/// missing image fails before a process is made, which is harmless), but `sh` +/// DOES exist wherever Git for Windows is installed, so the five `sh -c` +/// probes really run and flash five console windows past a GUI-subsystem +/// binary that owns no console. +/// +/// Scoped to Windows, not to `not(linux)`: macOS and the BSDs can have a real +/// `pactl`/`pw-dump` from Homebrew or ports, and answering false for them +/// would be a lie this diff has no business telling. +#[cfg(windows)] +pub fn audio_stack_health() -> AudioStackHealth { + AudioStackHealth { + wireplumber_active: false, + has_pw_dump: false, + cpal_sees_pipewire: false, + has_pactl: false, + any_devices: false, + } +} + +/// Run the audio-stack probes. Linux-only meaningfully; elsewhere everything +/// reads false except where trivially true. +#[cfg(not(windows))] pub fn audio_stack_health() -> AudioStackHealth { // systemd path first; fall back to a process check so non-systemd inits // (Gentoo/OpenRC, Void/runit) don't read as "WirePlumber down". diff --git a/crates/qbz-qt/src/diagnostics_qt.rs b/crates/qbz-qt/src/diagnostics_qt.rs index f65de1f6f..e973b6f56 100644 --- a/crates/qbz-qt/src/diagnostics_qt.rs +++ b/crates/qbz-qt/src/diagnostics_qt.rs @@ -1163,6 +1163,16 @@ fn collect_output_sinks() -> (Option, Vec, Option<(String, Strin /// right now (vs the saved "Preferred Sample Rate"). Linux/PipeWire/Pulse only; /// `None` when pactl is unavailable (a Flatpak/Snap sandbox without it simply /// degrades to "—", same as the reference). READ-ONLY. +/// W14, Windows only: `pactl` is a Pulse/PipeWire tool and does not exist on +/// Windows, so the row degrades to the same "-" the missing-pactl path already +/// produced -- without the spawn. macOS and the BSDs keep probing: a Homebrew +/// or ports `pactl` there is real and can answer. +#[cfg(windows)] +fn active_sink_format() -> Option<(String, String)> { + None +} + +#[cfg(not(windows))] fn active_sink_format() -> Option<(String, String)> { use std::process::Command; let default = Command::new("pactl")