Skip to content

V1.9.14

Choose a tag to compare

@fiverecords fiverecords released this 07 Oct 20:40
· 50 commits to main since this release
V1.9.14

This release has two parts. The first comes from one issue, #23: a Denon
PRIME 4+ into STC, and MTC out to a lighting console. It brings ON AIR, a
new way to follow a deck, with OFF AIR AT to set when a Denon deck counts as
quiet; StageLinQ that follows a PRIME 4+ deck at its real speed and reads
its faders over their whole travel; and one owner for each MIDI port, which
should end a frozen MTC and a crash with more than one sender on a port.
With it came Pro DJ Link fixes to on-air, BPM and track loads, checked
against Deep Symmetry's analysis of the protocol; the BPM one after a
report by @Joren2087 (#9).

The second is a review of all of STC's code against the protocol references
and captures it is built on, and against the source of JUCE, its library.
Most of what it fixed is of a few kinds: cue points that fired in a burst,
twice, or not at all; settings, presets and caches that could be lost or
overwritten; values read wrong from a device; and crashes and hangs on
malformed data, on device changes and at quit.

What has run on hardware: the #23 reporter ran two test builds of this
release on his PRIME 4+, with one engine sending MTC to his console. ON AIR
worked as described on the first, and the second, which added OFF AIR AT,
was reported working in his rig. Both carried the StageLinQ speed, fader and
on-air changes and the new MIDI port handling (two engines on one port were
not tried). The review came after them and changed some of that code,
StageLinQ most, so those changes deserve a second look. Nothing else has run
on the hardware it is for: it was checked by reading the code, against the
protocol references, in simulation, by replaying hardware captures where
there are any, and by fuzzing the parsers. "What to test" near the end lists
what to look at; "Known limits" what a fix costs or leaves open.

Upgrading. Existing configurations load, and the settings files keep
their format; a few saved values are read differently (below). The PLAYER
selector has one new choice, ON AIR, which with StageLinQ brings one new
per-engine setting, OFF AIR AT, starting at SILENCE. What behaves
differently without touching anything:

  • MTC and MIDI ports. MTC does not start on a port carrying another
    engine's MTC (status IN USE BY and its name), and with no MIDI device
    picked it opens none, where 1.9.13 opened the first port: pick one. See
    MIDI output.
  • Pro DJ Link. On players other than the CDJ-3000 the BPM sent out
    follows the pitch fader, and on mixers whose status packet STC misread,
    ON-AIR ONLY and XF-A / XF-B should follow the faders (from the protocol
    analysis; not yet run on a DJM). See Pro DJ Link.
  • StageLinQ. An engine follows a Denon deck at its real speed (SYNC no
    longer stops it, a stop pauses it, LTC follows its pitch); faders read
    full only at the top; TCNet's fader value for a PRIME 4+ deck follows the
    fader, where 1.9.13 sent it full: check receivers that use it. Track Map
    triggers fire once per new track, 0.25 to 1 s after the load, none on a
    reload of the same track. See StageLinQ.
  • Cue points. After a deck switch, a part-way load, a jump while paused
    then play, or a generator re-arm, only cues crossed from then on fire: a
    show relying on the burst gets fewer triggers. See Cue points.
  • LTC IN at a real stop runs on through FREEWHEEL (plus the device
    buffer and input latency), then steps back to the stop, as MTC IN does: a
    small backward locate on MTC OUT and Art-Net. At 25 fps that is 3 to 5
    frames with the default 150 ms and a buffer of 256 to 2048 samples, about
    12 at 8192 samples, and 50 to 58 with a 2 s FREEWHEEL. A dropout shorter
    than FREEWHEEL passes with no jump.
  • Saved values. Mixer-map MIDI and DMX numbers that are missing or out
    of range load as off; a 23.976 or 29.97 chosen on LTC IN survives a
    restart; a StageLinQ engine saved on PLAYER 5, 6 or MASTER follows DECK 1.
    See Settings, MTC and frame rates, StageLinQ.
  • Settings files (the Track Map, the presets, settings.json with
    Track Map overrides) are written in a fixed order: the first save after
    the update rotates their .bak once, even with nothing changed. See
    Settings.
  • Show Lock also locks the gain sliders and more, and closes open
    editors: unlock to change a gain. See Main window.
  • Network inputs on macOS and Linux with an interface selected take
    their port on all addresses, so broadcasts are heard; sharing a port
    behaves differently. See Known limits.
  • OSC triggers. In OSC TRIGGER ARGS of a Track Map entry, {artist},
    {title} and {offset} must stand alone as arguments: s:{title}, or a
    placeholder inside text, goes out as written (1.9.13 sent a garbled value
    holding the title, so a trigger that worked may now send {title}). Check
    your triggers.
  • Winamp stopped on a mapped track reads its offset, not 00:00:00:00.
  • Colour previews. The first session with players other than the
    CDJ-3000 downloads each track's analysis again: see Known limits.
  • Analysis cached before the update keeps its old cues until a track is
    read again, at its first load on players other than the CDJ-3000 (see
    Colour previews); until then this release's cue-reading fixes (memory and
    hot cues together, loops, emoji) do not reach it, nor Track Map entries
    filled from it. For CDJ-3000 tracks, or to fill entries from the new cues
    at once, quit STC and delete waveform_cache in STC's application data
    folder: each track's waveforms, analysis and artwork are then fetched
    again at its first load, so do it before a show, not during one.
  • Device selectors. If STC starts before the show interface is up,
    inputs and outputs fall back to another interface; the selectors show it,
    and later starts use it, until you pick the show interface or restart (in
    1.9.13 the selectors, and starts made from them, moved to it once it came
    up; a running input or output stayed on the fallback). settings.json
    keeps the show interface throughout. See Main window.

New

ON AIR: an engine follows the deck that is on air (#23)

A new choice in the PLAYER selector, for Pro DJ Link and StageLinQ. The
engine stays with its deck while it plays on air; when that deck goes quiet
(fader down, crossfader cut) or stops, it moves to the loudest deck playing
on air, or stays if there is none. The status shows the deck (ON AIR P3,
ON AIR D2), or ON AIR: NO PLAYER ON AIR / ON AIR: NO DECK ON AIR until
one plays. A change of deck brings its track: Track Map offset and trigger
at once, cues from the new playhead on. It works in THRU, where XF-A / XF-B
cannot: requested by @ivannvdlt, who mixes that way.

  • Denon (StageLinQ): on air is each deck's level as the mixer reports
    it, fader, crossfader and the DJ's assignment included. A per-engine
    setting, OFF AIR AT (under PLAYER with ON AIR selected), sets when a
    deck counts as quiet: SILENCE (the default: fader fully down or crossfader
    at the far end), -80 dB, -60 dB or -40 dB for an earlier switch; on the
    PRIME 4+, -60 dB comes with the fader at about 13-20 % of its travel or
    the crossfader 10-15 % from its end. From two PRIME 4+ captures; tried by
    @ivannvdlt on test builds.
  • Pioneer (Pro DJ Link): on air is what the DJM reports, as on the CDJs'
    on-air rings and as ON-AIR ONLY and XF-A / XF-B now read it (see On-air
    from the mixer); the loudest deck is the one whose channel fader is
    highest, when STC receives the faders. Without a DJM that reports on air,
    players normally report none and the status stays at
    ON AIR: NO PLAYER ON AIR: use a fixed player. Not run on Pioneer
    hardware yet.

Colour preview waveform for players other than the CDJ-3000

Players other than the CDJ-3000 now get a colour preview waveform in the
main window and the PDL View, read from the analysis files on their USB or
SD, drawn from its documented layout (a back bar in colour, a front bar) and
kept on disk; a damaged preview file from an older version is replaced once.
TCNet still sends such a deck's detail waveform as its small waveform, as
before. For a track in both an Engine DJ and a rekordbox library, the PDL
View could show the Engine DJ waveform the cue editor cached as such a
deck's preview, every session; it now shows the rekordbox preview once read
from the media (until then, none).


Fixed

MIDI output: a frozen MTC, and a crash, with more than one sender (#23)

Reported by @ivannvdlt: a Denon PRIME 4+ into STC, and MTC out of a Roland
USB MIDI interface into an Avolites Quartz. With a second engine sending MTC
to the same interface, the timecode froze on the console, and now and then
STC closed by itself.

  • One MIDI cable carries one MTC stream. MTC has no channels: two
    engines' MTC on one port cannot be followed, and STC allowed it, even from
    the device list. The second engine's MTC now does not start and names the
    engine holding the port; MIDI triggers, MIDI clock and mixer forward can
    still share a port with MTC.
  • Several threads sent to one MIDI port at once, which the MIDI library
    does not support: a collision could send garbage, freeze MTC and bring STC
    down, rarely with one engine, more often with two. Each port is now opened
    once for the whole application and sends one message at a time.
  • With MIDI clock on the MTC port, turning MTC OUT off or changing its
    device could crash STC. When MTC cannot open the port the MIDI triggers
    use, triggers, clock and mixer forward keep it (in 1.9.13 they were left
    without one), as they do when MTC is refused the port.

Settings, Track Map and presets

  • A missing or unreadable settings.json no longer costs the other
    files: the Track Map, presets and mixer maps still load, and the next save
    does not write defaults over them.
  • Backups. A save with no change, or a restart, leaves each file and its
    .bak alone. An unreadable file moved aside at startup also gets its
    .bak copied to <name>.previous-<time>, which no save touches and the
    warning names; the first save used to rotate defaults over that .bak.
  • A configuration restore is no longer undone by the running session:
    editors close and nothing is saved until STC restarts -- restart after a
    restore, as the message says. A backup right after a change contains it;
    backups now carry the StageLinQ mixer map (an older one leaves it alone).
  • Generator presets keep their cue points when saved or renamed (1.9.13
    deleted them on both; cues already lost are not restored), and SAVE
    updates the preset the form came from (by name), not another after an
    Import or Delete.
  • The generator's Start and Stop TC keep their frame across a restart
    (01:00:00:01 at 30 fps came back as 01:00:00:00).
  • Timecode fields in presets, generator cues and Track Map offsets
    accept ;. A typed preset or cue value is normalised on SAVE, ADD or
    Apply to the rate of the engine selected in the main window (an open
    preset editor follows it); untouched values are saved as stored (a 30 fps
    preset keeps :29 saved at 25 fps). Track Map offsets stay rate-free
    (frames up to 29, converted by each engine at its own rate); one out of
    range is clamped, not refused.
  • Track Map and cue editors: saving while the list changed under the
    form (a deck auto-fill, a column sort) no longer alters or deletes another
    track; the playing track is highlighted again for entries with a duration,
    and the status line follows track changes. In both cue editors, Apply
    after Add or Capture edits the selected cue instead of overwriting
    another, and the cue stays selected and in view.
  • Track Map lookup and offsets. With no duration match, the
    artist-and-title fallback picks the same entry every time, not another
    title starting with the same name and a | (Song|Edit). With an offset,
    everything from 23:58:33:17 at 23.976 came out near 00:00, values past
    midnight at 29.97 DF came out 2-3 frames early, and 01:01:00:00 typed at
    29.97 DF landed two frames before 01:01:00;02, where it lands now.
  • mixermap.json and slq_mixermap.json: a MIDI CC, note or DMX
    channel that is missing, not a number or out of range loads as off (a
    missing CC was CC 0, Bank Select).
  • Track Map import from rekordbox: the preview says tracks already in
    the map are left unchanged, as they always were, not overwritten.

LTC

  • LTC IN with large buffers (4096 or 8192 samples, or a large driver
    latency) no longer drops out now and then (pausing the outputs, restarting
    LTC OUT, sending MTC Full Frames).
  • Converting from LTC IN stays on the right frame with large buffers
    and with a source that runs off speed: the value passed on ran a frame or
    more late, which made LTC OUT repeat and skip frames.
  • LTC IN locks again within about 0.6 s when the source plays at normal
    speed after a brake or tape stop, a slow shuttle or a fast wind, where
    1.9.13 stayed paused until the audio device was restarted; noise during a
    pause no longer stops it locking (costs: see Known limits). Partial and
    broken frames (the cable plugged in mid-stream, dropouts, noise) are
    ignored instead of flashing a wrong value and making the outputs jump.
  • LTC OUT through a stall of STC over about 1.3 s (a debugger, a
    blocking dialog) runs on a few frames, holds with clean frames and catches
    up in one step, instead of looping over broken frames. With FPS CONVERT
    (25 to 30 fps and back) it no longer repeats and skips frames; with
    HOLD ON PAUSE, play after a hot cue or seek made while stopped no longer
    starts with part of an old frame.
  • FROM LTC IN passes the binary group flags with the user bits, so a
    passed-through date or text is declared as such.
  • ltc_gaps.log is capped at about 5 MB (the previous part kept as
    ltc_gaps.log.1); its ahead: repeated a frame lines now read
    ahead or held: repeated a frame, as LTC OUT holds write them too.

MTC and frame rates

  • MTC IN: a Full Frame is a locate. A cue while the sender is stopped
    shows the position with PAUSED and passes it on once (one MTC Full
    Frame, one Art-Net and one LA-Net frame), LTC OUT silent, instead of
    running the outputs on for the FREEWHEEL time and jumping back. Play
    starts them at the sender's first complete quarter-frame sequence, about
    two frames in; a stop then a locate stops them at the located frame
    instead of counting on through FREEWHEEL. FREEWHEEL counts from the last
    quarter frame; a Full Frame alone keeps the source present for at most two
    frames. A Full Frame naming a frame that does not exist at its rate
    (01:00:00:27 at 25 fps, 00:01:00;00 at 29.97 DF) is ignored; 1.9.13 took
    it as the position. A stale Full Frame at a sender's start-up
    (Pico-Timecode sends one) no longer starts the outputs off the stream (by
    up to 3.4 s in @mungewell's six Pico-Timecode captures in #16, which
    showed it; the fix was checked against them).
  • Changing the MTC input device no longer lets the old device through.
  • A chosen 23.976 is kept on MTC, Art-Net and LA-Net inputs instead of
    reverting to the 24 the signal reads as (LA-Net keeps 29.97 against 30
    too); on LTC IN a chosen 23.976 or 29.97 now survives a restart.

Generator and Audio BPM

  • A crash when the generator's audio device changed, or the engine left
    the generator, during a preset load.
  • Preset changes during playback no longer leave a second of silence or
    a moment of the previous song, PLAY while switching quickly starts the
    song finally selected, and from a slow disk the timecode stays with the
    audio and a timeline click during the load is kept. An audio device change
    while playing or paused no longer freezes the window for a second.
  • Audio BPM stays right after a sample-rate change (128 BPM read as
    117.5 from 44.1 to 48 kHz, also on MIDI clock and Link; detection starts
    again after it), and smooths the same at every buffer size, as at 512
    samples (it was 8x faster at 64, 4x slower at 2048).

Cue points

  • No burst of cues on a deck switch. After a change of followed deck (a
    cut under XF-A / XF-B, a MASTER handover), a part-way load (at a memory
    cue), or a title or length that arrives after play, only cues crossed from
    then on fire; ON AIR follows the same rule. The new track's Track Map
    offset and trigger still apply at once. Editing the Track Map during play
    fires no cue twice, and one about to be crossed still fires.
  • A jump while paused, then play (hot cue, scrub, jog) no longer fires
    the cues skipped over; cues gone back over (a hot cue back, a jog back
    over 0.1 s) fire again. A generator re-arm (a frame-rate change, a preset
    reapplied, the input switched away and back while running) no longer
    refires the cues up to the playhead.
  • Players without absolute position (nexus-generation players such as
    the CDJ-2000NXS, and an NXS2 until it accepts STC's bridge identity): play
    after a pause no longer jumps the timecode ahead by the pause and back,
    firing the cues between. Below 120 BPM, cues between a pause late in a
    beat and the next beat fire at that beat (up to a beat late), and a jump
    forward into the next beat during play fires the cues it skips, as from
    120 BPM up; going back a beat re-arms its cues.
  • Loops and jumps back on those players of 1 to 4 beats (a loop, a beat
    jump or hot cue back, a jog or scrub back while paused) are followed at
    the player's next status, within about a quarter of a second; before,
    every output ran up to 4 beats ahead and saw-toothed, and cues fired
    early, twice or never. What still escapes: see Known limits.
  • Cue points copied into an empty Track Map entry (rekordbox hot cues,
    Engine DJ quick cues) are used and written to trackmap.json at once, not
    at the next track change and save, so a crash no longer loses them; those
    behind the playhead are passed. An open Track Map editor shows Engine DJ
    cues at once, rekordbox cues (copied while the PDL View is open) at its
    next refresh. The PDL View also fills an entry when cues arrive with the
    waveform (from the disk cache or the media, the only route for players
    other than the CDJ-3000) or the title arrives after the analysis. Under
    Show Lock none is filled, now from Engine DJ cues too, until a reload
    after unlocking.

Pro DJ Link

The first five items were checked against Deep Symmetry's analysis of the
protocol and, where they cover the case, its captures. None of this section
has run on Pioneer hardware yet.

  • On-air from the mixer. A status packet some mixers send was read as
    on-air flags, after which the DJM's real report was ignored, so
    ON-AIR ONLY and XF-A / XF-B could follow the wrong decks; only the report
    is used now. A DJM-V10's channels 5 and 6 now work with them. With two
    DJMs, fader, on-air and VU values come only from the first registered.
  • BPM follows the pitch on every player. Players other than the CDJ-3000
    report the track tempo, which STC sent unchanged to MIDI clock, Link, OSC
    and TCNet, ignoring the pitch fader and SYNC. Reported by @Joren2087 on
    the CDJ-2000NXS2 (#9).
  • An NXS2 that sends its absolute position (once it accepts STC's bridge
    identity) no longer freezes its BPM at ten times the tempo, and its title,
    with its offset, arrives (STC asked as player 5, which an NXS2 refuses).
  • No position jump at a track load, or with unanalysed tracks and older
    players: the "no beat" value they send no longer puts the position
    hundreds of hours away for up to a second.
  • A CDJ-3000 set to player 5 is no longer ignored as STC itself.
  • Tempo. A CDJ-3000 track with no analysed tempo no longer reports
    429 million BPM to the display, OSC and TCNet (TCNet now sends 0 outside
    0-1000); after an eject the BPM goes to 0; -100 % in Wide mode reads
    -100 % and 0 BPM; a CDJ-3000 at about -50 % no longer steps LTC OUT back
    a frame.
  • A player whose IP address changes (a DHCP renewal, a replug) is
    followed at the new address about 5 s after the old one goes quiet,
    instead of freezing: XF-A / XF-B (and ON AIR) stay on it, its key, artwork
    and offset move with it, missing analysis is fetched there. Another unit
    taking its number within 10 s (another model or MAC) is a new player; a
    DJM is used at a new address after 10 s.
  • The same rekordbox ID from another player or slot is a new track
    (Track Map lookup, trigger, cue points, PDL View). Two engines on one
    player without absolute position both use the rekordbox beat grid and one
    position (in 1.9.13 that depended on which tab was on screen).
  • Emergency loop (media pulled from a playing deck) counts as playing,
    so the timecode runs on (and ON AIR stays), EMERGENCY still on the
    status line. Cue scratch and a spun-down CD show CUE SCRATCH and
    CD STOPPED, not UNKNOWN.
  • NXS2 track length. An NXS2 that sends absolute position takes its
    length from the track's metadata, and one cued at the very start is no
    longer taken for a CDJ-3000, which read hundreds of millions of seconds
    and froze the BPM (no capture has shown this yet). Its PDL View deck keeps
    elapsed and remaining time; a double-click entry gets the duration.
  • On the computer. Another DJ Link program holding port 50001
    (rekordbox, Beat Link Trigger) no longer makes STC use a whole CPU core;
    keepalives carry the selected adapter's own MAC (Windows confused
    Ethernet and Ethernet 2, macOS sent en1's for en10 to en19); the
    PDL View uses less CPU; an offset edited on a paused deck shows at once.
  • Mixer Map: the Color FX Assign row is labelled Assign = Beat FX,
    which it always read (where a DJM sends Color FX Assign is unknown); saved
    maps load as before.

Metadata and waveforms (Pro DJ Link)

  • Track information comes from the medium the track was loaded from: in
    a B2B with two USB sticks a deck no longer shows the other stick's title,
    key, artwork, beat grid or Track Map offset for the same rekordbox ID,
    copies of one export on two decks both show artwork, Track Map Learn
    learns the selected player's track, and TCNet, the metadata panel and the
    cue editor look tracks up the same way. A PDL View deck loaded over Link
    from a player that has left shows Track #N.
  • USB sticks in two players no longer get each other's beat grid, cues
    and waveforms. After a USB or SD swap, the old medium's data goes when the
    player reports the slot empty, and the new medium's track with the same ID
    is a new track (title, offset, trigger, cues); an SD door opened or a
    stick remounted without the slot emptying keeps the metadata.
  • Read from a player's media: NXS2 tracks with a record label get their
    beat grid, cues and detail waveform (the label was taken for the analysis
    path); memory and hot cues both come through; a player that refuses STC's
    queries still gets its analysis, kept when the title arrives later and in
    the disk cache. From a player's database, the standard cue list no longer
    shows memory and hot cues as loops.
  • A player whose database stops answering is retried at most every 5 s
    instead of over and over, no longer keeps the other players from being
    asked (an attempt can still delay them), and its title (with the Track
    Map offset) is asked for again, arriving within about 5 s even with the
    PDL View closed.
  • Waveforms drawn from the documented layout: NXS2 detail waveforms show
    their real shape and colours, CDJ-3000 3-band waveforms the bass, and a
    CDJ-3000 colour preview for a track with no 3-band preview, should one
    arrive, its colours instead of shades of blue. The PDL View waveform no
    longer jumps in reverse play.
  • Long tracks and large libraries: detail waveforms over about
    55 minutes read from the media are kept, a track over about 77 minutes on
    a CDJ-3000 no longer closes the metadata connection, and tracks past
    5,000 pages of a large export's track table get their analysis.
  • Also: emoji in titles, artists and cue comments display correctly
    (Pro DJ Link and StageLinQ); cache files are written whole, so a crash no
    longer leaves one that loads as an empty beat grid; quitting, or leaving
    Pro DJ Link, no longer waits for a large database download, and quitting
    with a player unreachable no longer risks a crash.

StageLinQ (Denon) (#23)

STC's Denon support was written from other people's reverse engineering,
without Denon hardware. @ivannvdlt's two PRIME 4+ captures (see Credits)
showed the first two faults below, how the unit reports each deck's level
(which ON AIR uses) and that XF-A / XF-B cannot tell sides on it (see Known
limits); read in the code review, the second also showed why the Engine
database download never started and that track lengths come in samples.
The first three items came with the test builds that ran in his rig.

  • The playback speed was the pitch fader's position (0.5 at 0 % on a
    PRIME 4+): an engine ran at about half speed between updates, LTC
    included, and did not pause at a stop; a deck synced from 130 to 104.4 BPM
    read 0.0085, stopping the outputs. The speed is now measured from the
    deck's position and the unit's clock, 0 when stopped (without those, from
    the play state and the pitch).
  • Faders and crossfader go to 1.27 on the PRIME 4+, not 1: the SLQ View
    bars and the mixer forward reached their top about four fifths of the way
    up, the main-window bars about two thirds, and TCNet's fader value was
    always full (STC waited for a channel count the unit never sends). STC now
    learns the range, and TCNet's value follows the channel fader.
  • PLAYER 5, PLAYER 6 or MASTER on a StageLinQ engine (decks 1 to 4, no
    MASTER) read INVALID DECK; it now follows and shows DECK 1.

The rest of this section came from the code review, after those test builds,
and has not run on a unit yet:

  • The Engine database download should now complete on a PRIME 4+. STC
    stopped after asking for the list of sources, taking the unit's own
    messages for the end of the exchange; it now waits for its replies, so
    artwork, overview waveform, cue and loop markers and key from the Engine
    library should appear in the SLQ View and main window. In simulation the
    whole download runs.
  • Track length comes in samples and was read as seconds (18:43 as about
    49.5 million s); the position bar, cue editor and Track Map durations now
    work, and entries saved from a Denon deck still match.
  • Smoother timecode: a playing deck's timecode no longer steps back
    several times a second.
  • Track Map triggers fire once per new track (not two or three times),
    0.25 to 1 s after the load; the same track (artist, title, length) loaded
    again is not a new track, as on Pro DJ Link. TRACK MAP off and on applies
    the map at once, not NO MAP until the next track.
  • A unit that disconnects, restarts or goes silent is reconnected, and
    an engine following it stops within about 5 s instead of staying PLAYING
    (with two units, only the leaving unit's decks clear). On Linux and macOS
    STC no longer quits when a unit drops; quitting, or leaving StageLinQ,
    while connected or connecting no longer hangs or crashes.
  • The Engine database copy is a private temporary file, read-only and
    deleted on close; crash leftovers and the STC_Denon/m.db of earlier
    versions are deleted once a day old. It is fetched again when the unit
    restarts on the same address. With two units, if the first unit's database
    cannot be loaded, the second unit's is now used.
  • Display. A new track no longer shows the previous one's artwork, cues
    or waveform in the SLQ View and StageLinQ panel, also when not in the
    database, and switching an engine between a Denon deck and a CDJ clears
    them. The pitch in the metadata line and the SLQ View is the unit's own
    figure, else from the measured speed (1.9.13 showed about -50 % at 0
    pitch). On a mixed rig a StageLinQ engine no longer shows or sends an
    unrelated rekordbox track's album or key.

Art-Net, LA-Net, TCNet and OSC

  • macOS and Linux: inputs on a selected interface receive broadcasts.
    Art-Net, LA-Net and OSC inputs heard only datagrams sent to the
    interface's own address; they now also take broadcasts from its subnet,
    and unicast from any sender. This changed how they bind (see Known
    limits); Windows, Localhost and ALL INTERFACES are unchanged.
  • macOS and Linux, point-to-point interfaces (a VPN): STC's broadcasts
    there (Art-Net, LA-Net, TCNet, Pro DJ Link keepalives, StageLinQ
    discovery) go to 255.255.255.255, not the far end of the link.
  • Art-Net mixer forward is emptied on every input switch, so a Denon
    unit's faders no longer go on after a switch to Pro DJ Link.
  • TCNet. Two receivers on one computer both get layer data; timestamps
    no longer go wrong after long uptime (hours on Intel Macs, days on Windows
    and Apple Silicon); a CDJ's waveform, beat grid and artwork go out when
    they arrive, also late or from another player's USB, and the previous
    track's clear at once. For other sources (the generator with Audio BPM)
    the beat number follows the timecode: no step at 29.97 DF minutes, no
    drift at 23.976 (0.6 s in ten minutes).
  • OSC. Triggers with quotes in the title or artist (Song (12" Mix))
    send the whole text and the arguments after it; a broadcast destination
    (x.x.x.255) works for triggers and the mixer forward; OSC input accepts
    bundles and every standard argument type (True/False, 64-bit numbers,
    blobs) instead of dropping them.

Main window, device selectors and Show Lock

  • Show Lock covers more: Refresh Devices (which interrupted LTC), the
    backup and restore shortcuts (Ctrl/Cmd+Shift+E and Ctrl/Cmd+Shift+I), the
    gain sliders (LTC in and out, Audio Thru, Audio BPM gain and smoothing),
    the OSC destination and FILE CHANNELS. Engaging it closes the Track Map,
    Mixer Map and preset editors, and the Mixer Map editor no longer opens
    while locked; an OSC address typed while locked is not saved. Output
    on/off and FREEWHEEL stay locked, as in 1.9.13, though the README said
    otherwise (it now lists all locked controls): unlock to silence an output.
  • Device selectors keep their device: MIDI and network selectors find it
    by name when a list changes, so a hot-plug or a new interface address no
    longer moves a selector to another device or overwrites its setting; a
    selector whose device is gone stays empty until it returns.
  • Inputs and outputs start on the interface the selector shows, also
    after interfaces came or went; a running Pro DJ Link or StageLinQ input
    now also restarts on an interface picked while its own is missing, or on
    its interface's new address, and stays put while that interface is briefly
    gone.
  • MTC in and out never open a MIDI port you did not choose: with the
    device unplugged MTC stays off (WAITING FOR DEVICE... or
    NO MIDI DEVICE), and the setting keeps its name.
  • Windows and display. The main window no longer reopens off-screen
    after a monitor is removed (it is centred) and maximises on a 4K display
    (it was capped at 2560 x 1440); the PDL View and SLQ View reopen with
    their title bar reachable; under Show Lock, repeated Cmd+Q opens one
    confirmation. HRS / MIN / SEC / FRM sit under their digits. The
    preset box shows (select preset) when none is selected, keeps its
    selection when rebuilt, and shows none for an engine without a preset.
    Quitting while a driver stalls an audio device scan no longer crashes STC.

Winamp (Windows)

  • Pause and stop are no longer track changes: triggers do not fire again
    and a pause no longer jumps the timecode to 0. A stopped Winamp reads the
    start of the track, as Winamp does: 00:00:00:00, or the Track Map offset
    of a mapped track (1.9.13 read 00:00:00:00, a stop counting as a track
    change). A hung player's timecode holds after about 1 s instead of running
    on, and rejoins without jumping ahead; stopping the input or quitting
    while Winamp is busy no longer kills its thread; position tracking is
    about 10 ms tighter (1.9.13 ran about 10 ms late).
  • Switching an engine to Winamp, or any input, drops the DJ track's
    offset.

Stability

Malformed or oversized data should no longer crash or hang STC: analysis
replies and files from a Pro DJ Link player (media downloads are capped at
128 MB, and stray replies no longer break one), damaged or truncated files
in the disk cache, data from a StageLinQ unit or its Engine database (opened
read-only, and refused without the expected tables), and OSC packets. These
parsers were fuzzed after the fix or checked against crafted files and
packets.

The SQLite library that reads a Denon unit's Engine database is updated
from 3.47.2 to 3.53.4, with SQLite's fixes for CVE-2025-29087,
CVE-2025-3277 and CVE-2025-6965 and its later fixes for damaged database
files.


Known limits

LTC, MTC and the generator

  • LTC IN relock: a source that dipped to about half speed relocks in about
    half a second (under a tenth before); after more than 6 s of hum on a
    stopped input the next start is read from about 0.6x speed; some starts at
    held odd speeds (0.4x after a stop, 1.6x to 3x) decode a few frames fewer.
  • LTC OUT: the catch-up after a stall of STC over about 1.3 s may break a
    frame.
  • MTC IN: a shuttle, wind or scrub of Full Frames from stop only moves the
    display (1.9.13 ran the outputs between the positions); from play, with
    Full Frames at most two frames apart, it runs them as before. A locate
    during play whose quarter frames stop for over two frames pauses the
    outputs until the next complete sequence (a step back to the located
    frame, then forward), where 1.9.13 ran on.
  • A generator audio device change, or leaving the generator, during a preset
    load waits for its first read: a slow or sleeping disk can freeze the
    window and the engines until it answers. Re-selecting a preset with the
    same file gives a few milliseconds of silence.

Cue points on players without absolute position (not a CDJ-3000, nor an
NXS2 sending it)

  • After a loop, jump or jog back of 1 to 4 beats, the timecode runs past the
    point the deck left until the next status, so a Track Map cue within about
    a quarter of a second after it can still fire early, at each loop pass.
  • A one-beat step back can go out without the resync STC sends for a seek
    (an MTC Full Frame), as a short loop on a CDJ-3000 does, most likely at
    fast tempos (around 170 BPM and up): check that your timecode reader
    follows it.
  • A move back within one beat while paused, and a loop shorter than a beat
    (a 1/2 or 1/4 roll), are not seen: the timecode runs past the loop end and
    snaps back. A load, hot cue or deck switch mid-beat can still fire the
    cues between the beat's start and the true position. Players older than
    the nexus generation send no beat count, so the Cue points fixes for
    players without absolute position do not reach them.

Pro DJ Link metadata and waveforms

  • Colour previews (players other than the CDJ-3000): the first session
    after the update downloads each track already on disk again, and
    meanwhile every other metadata request waits, other decks' titles and
    Track Map offsets included. A track whose export has no colour preview,
    or whose download fails, is downloaded again in every session; one in
    both libraries whose waveform was cached from a Denon deck, once more.
    With no deck connected, the cue editor shows such a track's rekordbox
    preview once cached. Whether STC's green and blue match the player's
    screen is still to be checked.
  • On a CDJ-3000 whose database gives no preview, an Engine DJ waveform an
    earlier version cached can still show, and go out as its TCNet small
    waveform. After a USB or SD swap, a deck playing on from its emergency
    loop that then loads the same rekordbox ID is not covered yet.

StageLinQ (Denon)

  • XF-A / XF-B cannot tell sides on a PRIME 4+, which never reports the
    crossfader assignment (second #23 capture); their status says
    XF-A: DEVICE SENDS NO SIDES - USE ON AIR. ON AIR does not need it;
    XF-A / XF-B stay for units that report it.
  • The Engine database download after the list of sources follows chrisle's
    StageLinq, not a capture: the first thing to look at on a unit. Track
    length in samples is what the PRIME 4+ captures show; a unit sending
    seconds would read 0 s.
  • The database copy: for a unit that comes back on another address, STC
    keeps the old copy; if the first unit reconnects and its download fails
    once, the second unit's database is used until the StageLinQ input
    restarts. Not handled yet: a USB stick inserted or removed on the unit,
    and a second source with a database (only the first is used).

Networks

  • macOS and Linux inputs on a selected interface: a broadcast from another
    subnet is still dropped (Windows takes it); STC's own broadcast output
    there is heard, as on Windows; with Ethernet and Wi-Fi on one network a
    broadcast may come twice (not measured).
  • macOS and Linux, one port used twice: on macOS a program binding the port
    on all interfaces after STC fails to bind, and one bound first leaves STC
    on unicast only. Two engines on two interfaces: on Linux unicast reaches
    only the last started; on macOS the second hears unicast but no
    broadcasts. One on an interface and one on ALL INTERFACES: on Linux
    unicast goes to the last started; on macOS the ALL INTERFACES input
    started second fails to bind.
  • Windows: a /32 adapter (WireGuard) still broadcasts to its own address.

Winamp, Show Lock and MIDI devices

  • Winamp: a hang over about 1.5 s with the audio playing ends in a forward
    step whose Track Map cues are passed without firing; a player that says it
    plays but gives no position for over 1 s (Winamp and its relatives do,
    briefly, after a track change) holds about 1 s, then steps: past about
    1.5 s its cues are passed, below that they fire late. Closed while playing
    and reopened stopped on the same track, it reads its last position until
    play, where Winamp shows 0, as before.
  • Show Lock leaves the generator transport and audio volume, and the OSC IN
    commands that change the generator, open on purpose; the README lists
    every control left open.
  • Two MIDI devices whose names differ only by a trailing number in brackets
    (Port, Port [2]) are saved under one name: after a restart the
    selector shows the first.

Credits

@ivannvdlt opened
#23, the
issue behind ON AIR, the PRIME 4+ fixes and the MIDI output fixes in this
release. His rig sends MTC through a Roland USB MIDI interface to an
Avolites Quartz. In order:

  • A clear description of the rig and of what he saw, which was enough to
    find both MIDI problems.
  • A network capture of his PRIME 4+ with STC connected, with a log of every
    move -- the first capture of a Denon unit sending its deck data to STC. It
    found the SYNC problem, set the fader ranges and made the ON AIR mode
    possible.
  • ON AIR tried on a first test build, which gave OFF AIR AT.
  • A second capture, started before STC and flipping the crossfader
    assignment switches, which showed what the unit does and does not report,
    that it sends track lengths in samples, and why the Engine database
    download never started.
  • A second test build run in his rig and reported working.

Thanks also to:

  • @Joren2087 -- the report in
    #9 that
    BPM did not follow the pitch fader on the CDJ-2000NXS2, and his captures
    there, which showed STC reopening database sessions to an NXS2 over and
    over (fixed in 1.9.10 for idle sockets, and now also for a player that
    stops answering). The missing waveform and metadata he also reported are
    still open: the NXS2 fixes may cover them, but nothing confirms it yet.
  • @mungewell -- the six Pico-Timecode MTC captures posted to
    #16,
    which showed the stale Full Frame at a sender's start-up and on which the
    MTC IN start-up and locate changes were replayed.
  • Deep Symmetry -- the DJ Link Ecosystem Analysis, Beat Link and Crate
    Digger, and the captures published with them, which the Pro DJ Link
    protocol, metadata and waveform fixes were checked against.
  • chrisle/StageLinq (Chris Le and Martijn Reuvers) -- the reference
    implementation whose FileTransfer flow the Engine database download
    follows.