Skip to content
Nokkvi

Audio Engine

Nokkvi is built for audiophiles who want a native, high-performance listening experience.

Unlike many web-based clients, Nokkvi communicates directly with the PipeWire framework. This ensures:

  • Low Latency: Minimal delay between clicking play and hearing music.
  • Bit-Perfect Playback: Music is passed to the system with minimal processing.
  • System Integration: Nokkvi appears as a native audio stream in your system mixer.

Nokkvi supports true gapless playback by pre-decoding the next track in the queue.

Toggle crossfade_enabled in the settings or with the F hotkey.

  • Duration: crossfade_duration_secs — adjustable from 1 to 12 seconds.
  • Behavior: Smooth linear volume transition between tracks.

Nokkvi exposes four volume_normalization modes, picking how (or whether) to even out track-to-track loudness:

  • off — decoded audio passes through untouched. The peak limiter is still in the chain to catch overshoot, but no gain is applied.
  • replay_gain_track — uses each song’s replayGain.trackGain tag.
  • replay_gain_album — uses each song’s replayGain.albumGain tag, preserving the loudness contrast within an album.
  • agc — rodio’s real-time automatic gain control. No metadata required; tracks every signal envelope frame-by-frame and pushes it toward a target.

A peak limiter (rodio LimitSettings::dynamic_content()) sits at the end of every chain, so any boost — from AGC, ReplayGain pre-amp, or both — is clamped before mixing.

ReplayGain values come from the file tags (REPLAYGAIN_TRACK_GAIN, R128_TRACK_GAIN, etc.), surfaced through the Subsonic API, and applied as a static amplify() factor to each stream. Because the gain is computed offline and constant per track, both sides of a crossfade are already at target — no convergence artifacts.

If you tag with rsgain or loudgain (modern, EBU R128–based), Navidrome reads the tags during scan and serves them to nokkvi. Older replaygain_* tag pairs work too. R.128–only tags are converted to ReplayGain dB by Navidrome before the API call, so nokkvi sees a single dB-format value regardless of what the tagger wrote.

The four ReplayGain knobs:

  • replay_gain_preamp_db — added to the resolved tag value before linearization. Default 0 matches the ReplayGain reference level. +6 is typical for “modern loudness” listeners who find reference output too quiet.
  • replay_gain_fallback_db — applied to tracks whose tag is missing entirely. Default 0 (unity).
  • replay_gain_fallback_to_agc — when true, untagged tracks engage real-time AGC instead of replay_gain_fallback_db. Useful for libraries with mixed tagging coverage.
  • replay_gain_prevent_clipping — clamps gain so track_peak × gain ≤ 1.0 using the per-track peak tag. On by default. Disable only if you specifically want the limiter to handle peaks.

Smart cross-fallback is always on: in track mode, a track without track_gain falls back to album_gain (and vice versa) silently. A track with neither uses the fallback dB or the AGC fallthrough.

Choose agc for libraries without ReplayGain tags. The normalization_level target maps to rodio’s target_level — a linear amplitude target, not LUFS:

  • quiettarget_level = 0.6. Reduced loudness, maximum headroom.
  • normal (default) — target_level = 1.0. Maintain original perceived level.
  • loudtarget_level = 1.4. Boost quiet tracks more aggressively.

In AGC mode, you may hear a brief level mismatch at track boundaries if the two tracks differ much in loudness. Lowering normalization_level from normal to quiet softens it. The two ReplayGain modes pre-level both streams at construction, so this artifact does not occur there — it’s the cleanest way to combine crossfade with loudness normalization if your library is tagged.

Toggle the equalizer with eq_enabled or the Q hotkey.

  • Bands: 32Hz, 64Hz, 125Hz, 250Hz, 500Hz, 1kHz, 2kHz, 4kHz, 8kHz, 16kHz — gains stored in eq_gains.
  • Presets: You can save custom presets (custom_eq_presets) that are persisted in the state database.