Releases: vynulldev/vynull
Release list
v0.3.0
Vynull v0.3.0
The headline features: BPM detection now lands exactly on integer tempos and beat grids stop drifting; album art appears in the web UI without needing a deck; tracks can finally be removed from playlists; the TUI gains a live Logs tab; and logs are quiet by default.
Exact BPMs, straighter grids
The tempo detector's peak interpolation could land a fraction off the true tempo (120.85 for a track that is really 121), which also poisoned the beat grid: a grid fit at the wrong period drifts a full beat over a typical track. Detection now verifies candidate tempos by tempogram coherence before any grid work:
- Tracks at integer tempos detect exactly; the roughly one-in-three that used to come out fractional snap to the right whole number
- Genuinely fractional tempos are kept when the audio supports them decisively, and half-integer tempos (a true 127.5) are recognized
- The beat grid is fit at the corrected period, so beat indicators stay locked across the whole track
- Library rows now follow re-analysis, so the displayed BPM always matches the grid that actually plays; manual BPM overrides survive untouched
Existing libraries upgrade themselves: the analysis cache version was bumped, so tracks re-analyze once in the background as they are viewed or loaded and pick up the corrected values.
Web UI
- Album art now appears the first time a track is viewed. Previously the artwork extraction was only ever triggered by a CDJ loading the track, so newly added tracks sat artless until they hit a deck
- Tracks can be removed from a playlist: a per-row button, plus a bulk action for removing a whole selection at once. Both are scoped to regular playlists, remove only the membership (the track, its tags, and its cues stay in the library), and pick the right track even with an active search or sort
- Waveform thumbnails for newly added tracks appear the moment analysis completes. Previously they could flash black on view switches, lag the analysis by half a minute, or (with analysis behind a long queue) never appear until a page refresh; a browser image-caching subtlety kept resurrecting the pre-analysis placeholder, and the thumbnail URL now changes when analysis lands so it cannot
TUI
- A new Logs tab shows the live log stream in-place: it follows the tail by default, scrolling up pauses it, and single keys jump to the oldest line or back to following. The log file remains the complete record
- The Settings tab scrolls properly instead of pushing the whole screen off on short terminals
- A DJM mixer now shows reliably in the Players view. A startup race could hide it for an entire session, and newer mixers' stripped status packets were wiping the channel state learned from their on-air broadcasts, making the mixer line flicker between states
Quiet logs
--log-level is now honoured everywhere. The default level no longer produces a line-per-packet spam stream with hex dumps while a deck browses and plays; it keeps the operationally useful record (sessions, loads, errors, deck writes). debug adds per-request browse and mount detail, trace adds wire-level hex dumps, and load-path log lines now show track titles alongside IDs.
Docs
- Run commands in the README, Makefile, and website no longer say
sudofor the default rekordbox mode, which needs no privileged ports; only--mode cdjneeds UDP 111, and the sudo-free options for that are documented - The README now leads with what the app does for hardware DJs, and a new Troubleshooting section covers the problems people actually hit (the waveform-color quirk, the post-upgrade re-analysis pass, the rekordbox slot collision) plus how to collect useful logs
Internals
A new end-to-end suite (make e2e) drives the real binary over its HTTP API against synthesized ground-truth media, covering the analysis pipeline, artwork, playlists, the cache upgrade path, and bulk-add responsiveness in about fifteen seconds. The newer-DJM status handling is additionally pinned by deterministic packet-level tests, since an idle mixer never exercises that path live. make check runs the whole pre-release gate (build, vet, formatting, unit tests, e2e) in one command.
Upgrade notes
- The one-time re-analysis pass after updating is CPU-heavy but bounded; the library stays usable while it runs
- Expect BPM values to visibly change on tracks the old detector had a fraction off; that is the fix working, and the grids move with them
- Hardware-verified on a CDJ-2000NXS2
Full changelog: git log --merges v0.2.0..v0.3.0
v0.2.0
What's Changed
- core: brand-neutral domain model + adapter interfaces by @vynulldev in #1
- analysis: produce neutral core.Analysis + lock the waveform encoders (modular-backends step 2) by @vynulldev in #2
- dsp + golden net: prep for the encoder relocation (modular-backends part 3a/3b) by @vynulldev in #3
- link/prolink: relocate the Pioneer wire encoders out of analysis (modular-backends part 3c) by @vynulldev in #4
- library: import Traktor collection.nml (tracks, playlists, cues) by @vynulldev in #5
- library: generalize the import layer behind an Importer registry by @vynulldev in #6
- web: drop the POLLING 1HZ and API-URL status-bar items by @vynulldev in #8
- web: declutter the import dialog and make progress prominent by @vynulldev in #7
- dbserver: fix CDJ-saved cue colour showing orange instead of green by @vynulldev in #11
- docs/design: import-layer plan + modular-backends reconciliation by @vynulldev in #9
- docs: document Traktor NML import in the README by @vynulldev in #10
- nfs + device + api: metadata and cover art for tracks played from USB by @vynulldev in #14
- analysis + mediadb + api: waveform and cues for external tracks by @vynulldev in #15
- api + web: configurable stream overlay (now-playing, decks, waveforms, history) by @vynulldev in #13
- mediadb: resolve external metadata per media slot (USB / SD, skip CD) by @vynulldev in #16
- api: write analysis back to the library row on every result path by @vynulldev in #18
- analysis: sharper beat-grid phase (windowed phase, gated half-beat flip, codec-aware latency) by @vynulldev in #17
- analysis: bump cacheVersion for the beat-grid phase improvements by @vynulldev in #19
New Contributors
- @vynulldev made their first contribution in #1
Full Changelog: v0.1.0-pre...v0.2.0
v0.1.0-pre
Vynull v0.1.0-pre — first public prerelease
A virtual CDJ / rekordbox source for Linux. Point Vynull at your music
collection and CDJs see it as a connected library over Pro DJ Link — with color
waveforms, beat grids, cues, and a browser-based library manager.
⚠️ First public prerelease. This is a hobby project that speaks a protocol
Pioneer never documented, worked out from other people's reverse-engineering.
Expect bugs and the occasional strange deck behaviour. Not affiliated with
Pioneer DJ / AlphaTheta. Try it before you trust it in a set.
Highlights
- Virtual CDJ / rekordbox on the Pro DJ Link network — CDJs browse (by
artist, album, genre, BPM, key, label, year, remixer, folder) and load your tracks. - Browser library manager (
--web) — browse/search, edit metadata, manage
cues/tags/(smart) playlists, view live players, zoom waveform + beat grid with
beat-jump, three UI themes, and configure CDJ settings. - Import from rekordbox —
rekordbox.xml, an encryptedmaster.db, or a
library-backup.zip: tracks, MyTags (+ categories), colors, (smart)
playlists, hot + memory cues (colors + loops), ANLZ waveforms/beat
grids/phrases, and artwork. - Color waveforms on the CDJ (PWV4 overview + PWV5 scrolling; blue / RGB /
3-band, honoring the deck's waveform-color setting). CDJ-3000 3-band
(PWV6/PWV7) supported. - Native FLAC / WAV / AIFF playback streamed over NFS (optional transcode to MP3).
- BPM detection + beat grid (dynamic-programming beat tracker), cue
management, key detection. - DJM mixer awareness — surfaces channel / master state on the link.
- Live terminal monitor (TUI), lazy analysis for instant startup, and
USB export to a rekordbox-compatible structure.
Full feature list and HTTP API in the README.
Platforms
- Linux — x86-64 & ARM64 (runs on a Raspberry Pi).
- A network interface on the same subnet as your CDJs (typically link-local
169.254.x.x). --mode rekordbox(the default) needs no privileged ports;--mode cdj
(appear as a CDJ-USB source) needs UDP port 111 — see the README.
Tested with
- CDJ-2000NXS2
- DJM-A9
Known limitations
- Beat-grid phase matches rekordbox's on only a fraction of tracks. BPM is
usually right, but the detected downbeat/phase can be off. Adjustable per
track from the web UI / API. - DJM mixers presence + master/channel state are surfaced from
broadcasts; deeper mixer control isn't implemented. - More broadly: some features are half-finished or only work in certain setups.
Treat it as a work in progress. Bug reports and PRs welcome.
Getting started
Grab the build for your platform from the Assets below, or build from source:
git clone https://github.com/vynulldev/vynull && cd vynull
make build
./vynull --web # library mode + web UI, no music dir required
# add music via the web UI or the HTTP API, then LINKSee the Quick Start for import-from-rekordbox, directory mode, and CDJ mode.
Thanks
Built on the reverse-engineering published by Deep Symmetry (dysentery / beat-link / crate-digger), rekordcrate, python-prodj-link, and pyrekordbox.
Full credits in the README.
License
GPL-3.0-or-later. Independent and unofficial — not affiliated with or endorsed by Pioneer DJ / AlphaTheta, Deep Symmetry, or any project listed above.