Skip to content

v0.5.0 — plain sticks both ways, and what the CDJ-to-CDJ captures teach

Latest

Choose a tag to compare

@usr-ein usr-ein released this 14 Oct 17:49
fbef942

Plain sticks both ways, a medium's real size, and what the CDJ-to-CDJ captures teach.

The first release tagged since v0.3.0: it carries 0.4.0, which was never tagged, and 0.5.0. Neither has met a real CDJ. Both were shown on emulated CDJ-2000NXSs running Pioneer's own firmware, beside a TriMixxx deck (emu-captures E18-E25). CHANGELOG.md has every change with the capture behind it, and work logs 033 and 034 tell how each was found.

0.5.0: plain sticks both ways

On the wire

  • A medium's size is eight bytes, and ours is the volume's own. Total and free bytes are eight big-endian bytes at 0xb0/0xb8 of the media response, and two little-endian words each in 0x4902. We read and wrote four, so every medium we served was described as one captured 28.6 GiB stick.
  • A stick with no rekordbox library is served by its folders, as a CDJ serves one: FOLDER alone at the root, folders then files, a file's tags from GET_GENERIC_METADATA (read with lofty when first asked), five-item track info, 0x3100, zeros for the preview and seek index, the file's JPEG or its folder's cover.jpg, and NFS opening the file by ?\0D <folder> <entry>. We list only what a player can play. Covers are read when asked for, and only the last 4 MiB of them are kept, with those of files a player has loaded.
  • Three requests are answered with nothing (0x2005, 0x2205, 0x3503), as a CDJ answers them. 0x3503 comes about rekordbox tracks too, and a real NXS leaves it unanswered.
  • Our status can say a plain file is loaded: track type 2, with the file's id.
  • We ask about a player's plain files as a player does: FOLDER menus and GET_GENERIC_METADATA with track type 2, track info and artwork by the file's id, the file by its ?\0D name.
  • Each player is asked about its own media. Covers, previews and a plain stick's questions all went to whichever player was asked first, so a second player's were answered by the first. A connection a player closed by restarting is asked on again, freshly opened.

Behind the API: Medium::open and Medium::from_folders, serve::folder, serve::tags, local_volumes; the client's generic_metadata, plain_track_info, plain_artwork and NfsClient::open_plain; sizes as u64 throughout; LoadedTrack::track_type; and in prolink-cxx a session that serves plain sticks and reads a player's (fetch_plain_tree, fetch_plain_metadata, fetch_plain_artwork, fetch_plain_file_streaming, served_file_id/served_file_path).

New dependencies: lofty 0.24 (MIT OR Apache-2.0), default features off, for a plain file's tags; rustix 1 (Apache-2.0 WITH LLVM-exception OR Apache-2.0 OR MIT), fs only, for statvfs.

Rust 1.97 or later, the toolchain the workspace is built with (it was 1.88). CI is green again, and its MSRV job now runs the version it names.

0.4.0: what the CDJ-to-CDJ captures teach

On the wire

  • We give up keep-alive byte 0x25 to a real deck, so a CDJ beside us stops re-claiming its number every few seconds.
  • Status goes out at once when what we publish changes (never sooner than 62 ms), so a hand-over of tempo master runs at a deck's pace.
  • We ask a peer about a slot as a deck does: when it turns loaded, until answered, where we asked about every slot every 5 s.

Behind the API: master hand-overs wake on the monitor's events; PeerMedia forgets an emptied slot; Player::is_playing; offer_tempo_master names one successor at a time.