Skip to content

memory cues: create from the web UI, survive the wire - #48

Merged
vynulldev merged 2 commits into
mainfrom
ui-memory-cues
Oct 3, 2026
Merged

vynulldev merged 2 commits into
mainfrom
ui-memory-cues

Conversation

@vynulldev

@vynulldev vynulldev commented Oct 3, 2026 •

Copy link
Copy Markdown
Owner

What & why

Shoutout to @kayrozen (#46) for the report!

Two halves, one subject: memory cues were second-class citizens, creatable nowhere and mishandled on the wire in both directions.

Web UI (1c37a29), fixes #46: memory cues imported from a rekordbox library displayed fine, but the UI could only create hot cues. + CUE picks the lowest free pad in A-H, and the 9+ memory range had no creation path. A + MEM button next to + CUE adds a memory cue at the zoom-waveform cursor, numbered from 9 upward (the convention imported rekordbox memory cues already use, so the cue list, exports and serving treat created and imported cues identically). Verified headless with Playwright: + CUE then + MEM twice yields cues 1, 9, 10 through the API.

dbserver (50183da): setting a second memory cue FROM THE DECK overwrote the first. Decks mark memory cues with 0 in the cue blob's number field: that is the wire convention separating them from hot pads 1-8, and the store keys cues by number, so every deck-saved memory cue landed on key 0. Confirmed against a packet capture of real rekordbox taking two memory-cue saves from a CDJ-2000NXS2: number 0 inbound on both saves, and rekordbox serves them back with number 0 too.

The fix translates the convention at the wire boundary, both directions. Inbound, the 0x2705 handler remaps number 0 to the next free internal memory number (the raw blob is stored as-is, it already says 0, which is exactly what the deck must be served back). Outbound, MarshalCueBlob writes 0 on the wire for internal numbers 9+, which also fixes a latent bug: memory cues imported from rekordbox libraries had been served to decks as nonexistent hot pads 9+ since #42.

Bonus RE from the capture, recorded for later: rekordbox's 0x4e02 responses use compact 56-byte cue records; our 76/124-byte records are NXS2-proven but worth normalizing if other models misbehave. The deck-side memory-cue DELETE message was not in this capture and remains unsupported until one is.

TestDeckMemoryCueSavesDontOverwrite and TestMarshalCueBlobMemoryWireNumber pin both directions.

Hardware testing

This changes what decks receive for memory cues (the wire number mapping) and how deck saves are stored. The v0.5.0 checklist covers both directions on the rig: two deck-saved memory cues persist and come back on re-load, and a web-created memory cue renders as a MEMORY cue (not a hot pad) on the CDJ.

  • Tested on: wire convention validated against a real-rekordbox packet capture (CDJ-2000NXS2 setting two memory cues); UI + API verified headless. Deck round-trip is the v0.5.0 checklist's F item.

Checklist

  • go build ./..., go vet ./..., and go test ./... pass
  • gofmt -l . is clean
  • New source files carry an SPDX header (GPL-3.0-or-later) (n/a, no new files)
  • Tested on real hardware (deck + firmware noted above), or this change doesn't affect deck behaviour
  • I agree my contribution is licensed under the project's GPLv3

Issue #46: memory cues imported from rekordbox served and displayed
fine, but the web UI could only create hot cues - + CUE picks the
lowest free pad in A-H and there was no creation path for the 9+
range at all. The server API accepts any number, so this is UI-only.

A + MEM button next to + CUE adds a memory cue at the cursor,
numbered from 9 up (matching how imported rekordbox memory cues are
stored, so serving, exports and the cue list treat both kinds
identically). Default colour, like the deck's own memory cues.

Verified headless: + CUE then + MEM twice yields cues 1, 9, 10 via
the API.
Field report: setting a second memory cue from the CDJ overwrote the
first. Decks mark memory cues with 0 in the cue blob's number field -
that's the wire convention separating them from hot pads 1-8 - and
the store keys cues by number, so every deck-saved memory cue landed
on key 0. Verified against a capture of real rekordbox taking two
memory-cue saves from a CDJ-2000NXS2: both 0x2705 blobs carry number
0, and rekordbox's 0x4e02 responses serve them back with number 0.

Inbound: a 0x2705 cue with number 0 is remapped to the next free
internal memory number (9+, the convention imported rekordbox memory
cues already use); the raw blob is stored as-is since it already says
0, which is what the deck must be served back. Outbound:
MarshalCueBlob now writes 0 on the wire for internal numbers 9+, so
synthesized memory cues (web-created or imported without raw blobs)
stop going out as nonexistent hot pads.

Also drops MarshalCueBlob's stale doc block (described a 76-byte
layout; the function has emitted 124-byte NXS2 blobs for ages).
TestDeckMemoryCueSavesDontOverwrite and
TestMarshalCueBlobMemoryWireNumber pin both directions.
@vynulldev vynulldev changed the title UI memory cues memory cues: create from the web UI, survive the wire Oct 3, 2026
@vynulldev
vynulldev marked this pull request as ready for review October 3, 2026 20:27
@vynulldev
vynulldev merged commit 6aad4f7 into main Oct 3, 2026
1 check passed
@vynulldev
vynulldev deleted the ui-memory-cues branch October 3, 2026 20:31
vynulldev added a commit that referenced this pull request Oct 3, 2026
Behavior-neutral v0.5.0 audit. Test hygiene: the real-audio beat and
phrase harnesses move from link/prolink (where the part-3c encoder
relocation stranded them) to analysis/, switching to the format-aware
encoder delay on the way (they called the lossy default, shifting
lossless files' printed grids by 25ms); encoder dumps stay in prolink
as encoders_realaudio_test.go; bench_test.go becomes
pipeline_timing_test.go; proto/dbmessage_test.go drops two tests
skipped since the initial commit (a marshal->parse combination that
doesn't exist on the wire) and notes that real coverage needs golden
fixtures captured from a deck session.

go mod tidy was a no-op.

README: serve-a-rekordbox-USB (the release headline) gets a feature
bullet and a rewritten section (default-mode example without sudo,
what decks/web get, read-only rule, OneLibrary dual-format note); the
colour-waveform bullet no longer claims FFT analysis (it's been
time-domain Butterworth banks for ages); the BPM/beat-grid bullets
now describe the shipped tempogram engine; the cue bullet covers hot
and memory cues (post-#48).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Separate Hot cues from Memory Cues

1 participant