All 4 canvas panels (Oscilloscope, Energy, Pulse, X/Y) now share:
- Bottom-left: 72px album art thumbnail with rounded corners
- Bottom-right: 4 rows (title, album, artist, compact badge), right-aligned,
max-width 400px for longer text
- Energy: removed 85% height constraint, rings use full canvas
Convert 6 visualizer tabs into a single dropdown menu in the header.
Remove album art and full quality badge from Oscilloscope, Energy,
Transient Pulse, and Lissajous panels. Replace with bottom-right
compact track info (title, artist/album, text-only quality badge).
Dramatically increase AlbumReactive sensitivity for heavy music
(faster attack/decay, 3x scale/glow multipliers).
Energy Bands + Oscilloscope:
- Constrain drawing area to 85% of screen height, vertically centered
Oscilloscope:
- Change from bottom-left info to centered artwork layout (like Bars)
Transient Pulse:
- Lower backend threshold 0.15 -> 0.04, cooldown 6 -> 3 frames
- Use raw (un-smoothed) bass-weighted RMS for sharper detection
- Add frontend-side supplementary beat detection from energy data
Album Reactive:
- Fix glow layer centering (was anchored to top-left, now inset: 0)
- Double scale effect (0.04 -> 0.08) and glow spread (40 -> 80)
- Fast attack / medium decay smoothing for visible reactivity
Backend:
- Emit viz:energy with 5-band RMS (sub-bass, bass, mids, presence, air)
- Emit viz:transient with attack detection (threshold + cooldown)
Frontend panels:
- EnergyBandsPanel: concentric glowing rings around centered artwork
- LissajousPanel: stereo X/Y phase plot with trail (watermark layout)
- TransientPulsePanel: expanding rings from center on beat detection
- AlbumReactivePanel: album art with breathing scale/glow from energy
All panels extract colors from album art, throttle at 30fps, and follow
the existing visualizer lifecycle (enable/disable backend on mount).
Focus tabs now: Coverflow, Static, Bars, Scope, Energy, X/Y, Pulse,
Reactive, Lyrics, Queue (keys 1-0).
New OscilloscopePanel renders dual L/R waveforms from viz:waveform
event data. ALBUM_SECONDARY layout with small artwork bottom-left.
Colors extracted from album art with green tint (L) and blue tint (R).
Registered as focus tab with AudioWaveform icon and keyboard shortcut 4.
Renumbered focus tab shortcuts (1-6) to match new tab order.
Add viz:waveform event emission alongside existing viz:data FFT output.
De-interleaves L/R channels from the raw sample buffer and downsamples
to 256 points per channel (512 floats = 2048 bytes). Pre-allocates the
waveform buffer outside the hot loop to avoid per-frame allocations.
The wizard step 6 was writing per-app bit-perfect rules to
pipewire-pulse.conf.d/pulse.rules, but QBZ uses pipewire-alsa (via
rodio/cpal), so those rules were never applied.
Changed to pipewire.conf.d/stream.rules which applies to ALL PipeWire
clients regardless of API (ALSA, PulseAudio, JACK). Also updated the
step indicator from "Pulse" to "Apps" in all 4 locale files.
Fixes#53 (wizard bug)
Integrations section now shows a toggle to register/deregister QBZ as
the default handler for qobuzapp:// links. Checks current status on
mount, calls v2_register/v2_deregister commands on toggle.
Import LinkResolverModal, add handleResolvedLink() that dispatches to
handleAlbumClick/handleArtistClick/selectPlaylist. Listen for
link:resolved event from OS scheme handler. Render modal in template.
Svelte 5 modal with input field for pasting Qobuz URLs. Calls
v2_resolve_qobuz_link and forwards the resolved link to the parent.
Enter key submits, error displayed inline.
Added to all 4 locales (en, es, de, fr):
- settings.integrations.qobuzLinkHandler* keys for settings toggle
- linkResolver.* keys for the modal (title, placeholder, go, resolving, invalidLink)
Single-instance plugin now inspects args for qobuzapp:// or
play.qobuz.com URLs and emits link:resolved event. Launch args
are also checked on first startup with a 1.5s delay for frontend
readiness.
v2_check_qobuzapp_handler, v2_register_qobuzapp_handler,
v2_deregister_qobuzapp_handler — use xdg-mime for scheme handler
registration and mimeapps.list editing for deregistration.