fix(audio): default to shared System output and resolve Auto to a concrete backend (#470)
OOTB playback froze (seekbar advancing, no audio) on hosts where the configured backend was not usable — e.g. PipeWire as the Linux default but `pactl` absent (minimal Debian/Ubuntu). "Auto" (a null backend_type) fell through to a legacy CPAL path that forced the track rate onto the shared default device, producing a suspended/silent stream and leaving a process-wide stuck audio handle that survived Reset. - Add a cross-platform "System" backend (CpalDefaultBackend now on Linux too): opens the OS default output at its negotiated rate with rodio resampling and an explicit ~100ms CPAL buffer (MixerDeviceSink has zero internal buffering, so the bare default underran and stayed suspended). Shared, no exclusivity, no `pactl` — mixes with other apps like any normal player. - Make System the OOTB default and what Reset lands on; seed it on first run. Drop the per-startup #375 NULL->PipeWire backfill migration. - Resolve a null backend_type to System in the player so the legacy CPAL path is never reached (covers legacy installs and headless callers). - "Auto" in Settings is now a resolve-and-set action: it picks the best available backend (PipeWire if available, else System), stores that concrete value and updates the dropdown + device picker, so backend_type is never null. - Explicit PipeWire (DAC passthrough) and ALSA Direct (exclusive) configs are untouched and remain bit-perfect. cc
This commit is contained in:
10 files changed
+111
-75
No files matched your search
@@ -3358,11 +3358,26 @@
|
||||
}
|
||||
|
||||
async function handleBackendChange(backendName: string) {
|
||||
// "Auto" is a resolve-and-set action, not a persisted mode. Pick the best
|
||||
// available backend — PipeWire if available (best quality + device routing),
|
||||
// otherwise System (always works) — and continue exactly as if the user had
|
||||
// selected that concrete backend. This keeps backend_type always concrete: it
|
||||
// never stays null, which on Linux fell through to the legacy CPAL path that
|
||||
// froze the seekbar with no audio and left a process-wide stuck audio handle
|
||||
// surviving Reset (#470). The dropdown then shows what was chosen, and the
|
||||
// device picker lets the user correct the DAC if the auto pick isn't theirs.
|
||||
if (backendName === 'Auto') {
|
||||
const pipewire = availableBackends.find(
|
||||
b => b.backend_type === 'PipeWire' && b.is_available
|
||||
);
|
||||
const system = availableBackends.find(b => b.backend_type === 'SystemDefault');
|
||||
backendName = (pipewire ?? system)?.name ?? 'System';
|
||||
}
|
||||
selectedBackend = backendName;
|
||||
|
||||
// Map UI name to backend type
|
||||
// Map UI name to backend type (always concrete after the Auto resolution above)
|
||||
const backend = availableBackends.find(b => b.name === backendName);
|
||||
const backendType = backendName === 'Auto' ? null : backend?.backend_type ?? null;
|
||||
const backendType = backend?.backend_type ?? null;
|
||||
|
||||
// Auto-disable incompatible features
|
||||
// DAC Passthrough and PW force bit-perfect only work with PipeWire
|
||||
|
||||
@@ -2145,7 +2145,7 @@
|
||||
"syncAudioOnStartup": "Audio-Einstellungen beim Start synchronisieren",
|
||||
"syncAudioOnStartupDesc": "Audiokonfiguration beim App-Start aus der Datenbank neu laden. Aktiviere dies, wenn dein Audiogerät oder deine Einstellungen nach dem Starten falsch erscheinen.",
|
||||
"audioBackend": "Audio-Backend",
|
||||
"audioBackendDesc": "Wähle Audiosystem: Auto (empfohlen), PipeWire (modern), ALSA Direct (bitperfekt, exklusiv) oder PulseAudio (veraltet).",
|
||||
"audioBackendDesc": "Wähle Audiosystem: System (Standard — geteilte Ausgabe wie jede App, kein Bitperfect), Auto (empfohlen — wählt das beste verfügbare Backend; ggf. musst du noch deinen DAC auswählen), PipeWire (modern), ALSA Direct (bitperfekt, exklusiv) oder PulseAudio (veraltet).",
|
||||
"currentSampleRate": "Aktuelle Abtastrate",
|
||||
"noActivePlayback": "Keine aktive Wiedergabe",
|
||||
"loadingDevices": "Geräte werden geladen...",
|
||||
|
||||
@@ -2145,7 +2145,7 @@
|
||||
"syncAudioOnStartup": "Sync audio settings on startup",
|
||||
"syncAudioOnStartupDesc": "Reload audio configuration from database when the app starts. Enable if your audio device or settings appear incorrect after launching.",
|
||||
"audioBackend": "Audio Backend",
|
||||
"audioBackendDesc": "Choose audio system: Auto (recommended), PipeWire (modern), ALSA Direct (bit-perfect, exclusive), or PulseAudio (legacy).",
|
||||
"audioBackendDesc": "Choose audio system: System (default — shared output like any app, no bit-perfect), Auto (recommended — picks the best available backend; you may still need to select your DAC), PipeWire (modern), ALSA Direct (bit-perfect, exclusive), or PulseAudio (legacy).",
|
||||
"currentSampleRate": "Current Sample Rate",
|
||||
"noActivePlayback": "No active playback",
|
||||
"loadingDevices": "Loading devices...",
|
||||
|
||||
@@ -2145,7 +2145,7 @@
|
||||
"syncAudioOnStartup": "Sincronizar configuración de audio al iniciar",
|
||||
"syncAudioOnStartupDesc": "Recarga la configuración de audio desde la base de datos al iniciar la app. Actívalo si tu dispositivo o configuración de audio aparecen incorrectos al abrir.",
|
||||
"audioBackend": "Backend de Audio",
|
||||
"audioBackendDesc": "Elige el sistema de audio: Auto (recomendado), PipeWire (moderno), ALSA Direct (bit-perfect, exclusivo), o PulseAudio (legacy).",
|
||||
"audioBackendDesc": "Elige el sistema de audio: System (predeterminado — salida compartida como cualquier app, sin bit-perfect), Auto (recomendado — elige el mejor backend disponible; quizá aún debas seleccionar tu DAC), PipeWire (moderno), ALSA Direct (bit-perfect, exclusivo), o PulseAudio (legacy).",
|
||||
"currentSampleRate": "Tasa de Muestreo Actual",
|
||||
"noActivePlayback": "Sin reproducción activa",
|
||||
"loadingDevices": "Cargando dispositivos...",
|
||||
|
||||
@@ -2145,7 +2145,7 @@
|
||||
"syncAudioOnStartup": "Synchroniser la configuration audio au démarrage",
|
||||
"syncAudioOnStartupDesc": "Recharge la configuration audio depuis la base de données au démarrage de l'application. Activez si votre appareil ou vos paramètres audio semblent incorrects après le lancement.",
|
||||
"audioBackend": "Backend audio",
|
||||
"audioBackendDesc": "Choisissez le système audio : Auto (recommandé), PipeWire (moderne), ALSA Direct (bit-perfect, exclusif) ou PulseAudio (ancien).",
|
||||
"audioBackendDesc": "Choisissez le système audio : System (par défaut — sortie partagée comme toute app, pas de bit-perfect), Auto (recommandé — choisit le meilleur backend disponible ; vous devrez peut-être encore sélectionner votre DAC), PipeWire (moderne), ALSA Direct (bit-perfect, exclusif) ou PulseAudio (ancien).",
|
||||
"currentSampleRate": "Taux d'échantillonnage actuel",
|
||||
"noActivePlayback": "Pas de lecture en cours",
|
||||
"loadingDevices": "Chargement des appareils...",
|
||||
|
||||
@@ -2145,7 +2145,7 @@
|
||||
"syncAudioOnStartup": "Sincronizar configurações de áudio na inicialização",
|
||||
"syncAudioOnStartupDesc": "Recarregar configuração de áudio do banco de dados quando o app iniciar. Ative se o dispositivo ou configurações de áudio parecerem incorretos após o lançamento.",
|
||||
"audioBackend": "Backend de Áudio",
|
||||
"audioBackendDesc": "Escolha o sistema de áudio: Auto (recomendado), PipeWire (moderno), ALSA Direct (bit-perfect, exclusivo) ou PulseAudio (legado).",
|
||||
"audioBackendDesc": "Escolha o sistema de áudio: System (padrão — saída compartilhada como qualquer app, sem bit-perfect), Auto (recomendado — escolhe o melhor backend disponível; talvez ainda precise selecionar seu DAC), PipeWire (moderno), ALSA Direct (bit-perfect, exclusivo) ou PulseAudio (legado).",
|
||||
"currentSampleRate": "Taxa de Amostragem Atual",
|
||||
"noActivePlayback": "Nenhuma reprodução ativa",
|
||||
"loadingDevices": "Carregando dispositivos...",
|
||||
|
||||
Reference in new issue
Block a user