feat(audio): surface "JACK is not bit-perfect" in Audio settings
JACK routes through the JACK graph (resamples to the graph rate), so it can't be bit-perfect — but nothing told the user. Add a `backend-is-jack` flag (settings.rs computes it beside alsa/pipewire at both set-sites; state.slint property) and a WarningBanner in AudioSettings, gated on it, pointing at ALSA-direct / PipeWire-passthrough for bit-perfect. UI-only; backend behavior unchanged. Blind change (no build this session) — validates on the next qbz_ui build. cc
This commit is contained in:
3 files changed
+15
No files matched your search
@@ -10,6 +10,7 @@ import { SettingsState, DacWizardActions } from "../state.slint";
|
||||
import { QbzToggle } from "../primitives/QbzToggle.slint";
|
||||
import { QbzSelect } from "../primitives/QbzSelect.slint";
|
||||
import { QbzIcon } from "../primitives/QbzIcon.slint";
|
||||
import { WarningBanner } from "../primitives/WarningBanner.slint";
|
||||
import { SettingRow } from "SettingRow.slint";
|
||||
|
||||
component GroupHeader inherits Text {
|
||||
@@ -95,6 +96,13 @@ export component AudioSettings inherits VerticalLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
// JACK routes through the JACK graph (resamples to the graph rate), so it
|
||||
// can't be bit-perfect — surface that so the user isn't misled.
|
||||
if SettingsState.backend-is-jack: WarningBanner {
|
||||
variant: "warning";
|
||||
title: @tr("JACK is not bit-perfect");
|
||||
body: @tr("The JACK backend routes audio through the JACK graph, which resamples to the graph's sample rate. For bit-perfect playback use ALSA (direct) or PipeWire with passthrough.");
|
||||
}
|
||||
SettingRow {
|
||||
label: @tr("Output device");
|
||||
description: @tr("The DAC or sound device that receives audio.");
|
||||
|
||||
@@ -2804,6 +2804,7 @@ export global SettingsState {
|
||||
// Audio — Rust-computed conditional flags driving `if`-gated rows.
|
||||
in-out property <bool> backend-is-alsa: false;
|
||||
in-out property <bool> backend-is-pipewire: false;
|
||||
in-out property <bool> backend-is-jack: false;
|
||||
in-out property <bool> alsa-plugin-is-hw: false;
|
||||
|
||||
// --- PLAYBACK ----------------------------------------------------------
|
||||
|
||||
@@ -147,6 +147,7 @@ pub struct SettingsSnapshot {
|
||||
// Audio — conditional flags.
|
||||
backend_is_alsa: bool,
|
||||
backend_is_pipewire: bool,
|
||||
backend_is_jack: bool,
|
||||
alsa_plugin_is_hw: bool,
|
||||
// Playback.
|
||||
continue_playback: bool,
|
||||
@@ -481,6 +482,7 @@ fn build_snapshot(
|
||||
|
||||
let backend_is_alsa = active_backend == AudioBackendType::Alsa;
|
||||
let backend_is_pipewire = active_backend == AudioBackendType::PipeWire;
|
||||
let backend_is_jack = active_backend == AudioBackendType::Jack;
|
||||
let alsa_plugin_is_hw = alsa_plugin == AlsaPlugin::Hw;
|
||||
let (out_backend_label, out_mode_label, out_backend_active, out_mode_active) =
|
||||
output_labels(&audio);
|
||||
@@ -525,6 +527,7 @@ fn build_snapshot(
|
||||
skip_sink_switch: audio.skip_sink_switch,
|
||||
backend_is_alsa,
|
||||
backend_is_pipewire,
|
||||
backend_is_jack,
|
||||
alsa_plugin_is_hw,
|
||||
continue_playback,
|
||||
show_context_icon: prefs.show_context_icon,
|
||||
@@ -596,6 +599,7 @@ pub fn apply_snapshot(window: &AppWindow, snap: SettingsSnapshot) {
|
||||
// Audio — conditional flags.
|
||||
st.set_backend_is_alsa(snap.backend_is_alsa);
|
||||
st.set_backend_is_pipewire(snap.backend_is_pipewire);
|
||||
st.set_backend_is_jack(snap.backend_is_jack);
|
||||
st.set_alsa_plugin_is_hw(snap.alsa_plugin_is_hw);
|
||||
// Playback.
|
||||
st.set_continue_playback(snap.continue_playback);
|
||||
@@ -721,6 +725,7 @@ fn push_conditional_flags(ctx: &SettingsCtx, weak: &slint::Weak<AppWindow>) {
|
||||
let plugin = audio.alsa_plugin.unwrap_or(AlsaPlugin::Hw);
|
||||
let is_alsa = backend == AudioBackendType::Alsa;
|
||||
let is_pipewire = backend == AudioBackendType::PipeWire;
|
||||
let is_jack = backend == AudioBackendType::Jack;
|
||||
let plugin_is_hw = plugin == AlsaPlugin::Hw;
|
||||
let plugin_index = ALSA_PLUGINS
|
||||
.iter()
|
||||
@@ -730,6 +735,7 @@ fn push_conditional_flags(ctx: &SettingsCtx, weak: &slint::Weak<AppWindow>) {
|
||||
let st = w.global::<SettingsState>();
|
||||
st.set_backend_is_alsa(is_alsa);
|
||||
st.set_backend_is_pipewire(is_pipewire);
|
||||
st.set_backend_is_jack(is_jack);
|
||||
st.set_alsa_plugin_is_hw(plugin_is_hw);
|
||||
st.set_alsa_plugin_index(plugin_index);
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user