Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions doc/modules/ROOT/pages/exports.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -395,6 +395,24 @@ Regardless of the names assigned to the colors by the user, the row _id_ values
|8 |Purple
|===

[#column-rows]
=== Column Rows
Column rows represent the different browsing columns that can be shown on a CDJ or XDJ for navigating tracks. They contain the labels used by the menus, and are linked to by the <<menu-rows,Menu table>>.

These rows hold a numeric _id_ at bytes{nbsp}``00``-`01`, which is referenced by the _column_id_ field found in menu rows. After that, there's an _unknown_ two byte field (labeled _u_) at bytes{nbsp}``02``-`03`. Finally, starting at byte{nbsp}``04`` is the _name_ of the column, which is a <<devicesql-strings,DeviceSQL string>>. It has been observed that, in databases generated by rekordbox, the _name_ strings are weirdly prefixed by the "interlinear annotation" characters _\u\{fffa\}_ and postfixed with _\u\{fffb\}_, unlike any other strings in the database.

The rows have the structure shown below:

.Column row.
[bytefield]
----
(draw-column-headers)
(draw-box (text "id" :math) {:span 2})
(draw-box (text "u" :math) {:span 2})
(draw-gap (text "name" :math))
(draw-bottom)
----

[#genre-rows]
=== Genre Rows

Expand Down Expand Up @@ -479,6 +497,29 @@ Label rows represent record labels.
They hold a numeric genre _id_ (which tracks can be assigned) at bytes{nbsp}``00``-`03` and a text_name_ starting at byte{nbsp}``04`` which is a <<devicesql-strings,DeviceSQL string>>.
The rows have the structure shown in <<genre-label-row,Genre or Label row>>, above.

[#menu-rows]
=== Menu Rows

Menu rows represent the menus that appear on a CDJ or XDJ for browsing tracks in different ways.
The first field is a two-byte _category_id_ (labeled _cat~id~_) at bytes{nbsp}``00``-`01` which links the row to a <<column-rows,Column row>> and thus provides a label to the menu. This is followed by another two-byte value called _content_pointer_ (labeled _c~p~_) at bytes{nbsp}``02``-`03` that determines the internal content list that is accessed via this menu (e.g. the list of Artists, Labels, Genres...).

Next, there is a one byte _unknown_ value (labeled _u_) at byte{nbsp}``04``, followed by a one byte _menu_visibility_ (labeled _m~v~_) flag at byte{nbsp}``05`` which seems to determine whether the menu is shown or hidden on the player: value '00' means visible, while '01' means hidden. The value '02' has also been observed, but its meaning could't yet be determined, at least by testing with a CDJ-350 player which is quite old. It could be that this value is used by newer players only.

Finally, there is a two-byte _sort_order_ (labeled _s~o~_) value at bytes{nbsp}``06``-`07` which seems to determine the order in which the menus are shown on the player. A value of '0' is valid and puts the menu at the top of the list, while higher values put the menu further down. The heuristic used by players to order menus with the same _sort_order_ value is unknown; it might be non-deterministic and/or depending on the specific player device.

.Menu row.
[bytefield]
----
(def boxes-per-row 0x08)
(def left-margin 1)
(draw-column-headers)
(draw-box (text "cat" :math [:sub "id"]) {:span 2})
(draw-box (text "c" :math [:sub "p"]) {:span 2})
(draw-box (text "u" :math) {:span 1})
(draw-box (text "m" :math [:sub "v"]) {:span 1})
(draw-box (text "s" :math [:sub "o"]) {:span 2})
----

[#playlist-tree-rows]
=== Playlist Tree Rows

Expand Down