Library interaction
This Page contains contains documentation for the simple IO protocol used to control the LEDs on the CDJ or detecting whether the user interacted with a physical control (such as buttons, knobs, etc).
Communication in both directions uses a simple header with types 0x20
(input)
or 0x21
(output).
Both packets contain a single structure with fixed offsets (similar to
the structure of packets exchanged by simpler HID controllers). Since the
information is very tightly packed, a bytefield diagram is not able to describe
the structure in enough detail, thus it will be described in table form. This
table has a Column Bytes
which identifies the position of the Byte or Bytes
in question from the very start of the message. Moreover, the Column Mask
contains a Mask (or an expression evaluating to mask) to be applied to the
current Byte(s) to identify the exact
Bit(s) in question. Control
will hold the label of the control seen on the CDJ
or an otherwise descriptive name in case the label isn’t present, while
Notes
will contain further explanation on the current Control
in case that’s required. Type
indicates the physical type of control.
CDJ→Host
The Host seems to poll control messages from the host roughly every 100ms
(TODO: seems low, need verification).
When the Type
describes a button, the bit being set means that the Button
is currently being pressed while an unset bit indicates the opposite.
All bytes that express values within a range are generally mapped linearly
to their physical control.
Bytes | Mask | Type | Control | Notes |
---|---|---|---|---|
|
|
— |
— |
First Byte of is always |
|
|
— |
|
Message Type |
|
|
Button |
Play/Pause |
|
|
|
Button |
Cue |
|
|
|
Button |
Search forward |
|
|
|
Button |
Search backward |
|
|
|
Button |
Track Search forward |
|
|
|
Button |
Cue/Loop Call 1/2X |
|
|
|
Button |
Cue/Loop Call 2X |
|
|
|
Button |
In/Cue |
(part of the loop control section) |
|
|
Button |
Out |
|
|
|
Button |
Reloop/Exit |
|
|
|
Button |
Time Mode / Auto Cue |
|
|
|
Button |
Memory |
|
|
|
Button |
Delete |
|
|
|
Button |
Jog Mode |
|
|
|
Enum |
Jogwheel Spinning direction |
|
|
|
Button |
Platter Touch |
|
|
|
Button |
Tempo |
|
|
|
Button |
Master Tempo |
|
|
|
Button |
Tempo Reset |
|
|
|
Button |
Needle Search Touched |
Only contains whether it is touched, not the position of the touch. |
|
|
Boolean |
Library/info view visibility |
Indicates whether the library (Browse Button) or track info (Info Button) view is currently visible. (TODO: doublecheck whether this is actually true or the other way around and just indicates whether the Scrolling waveform view is visible) |
|
|
Button |
Quantize |
|
|
|
Button |
Master |
|
|
|
Button |
Sync |
|
|
|
Button |
Rotary encoder press |
|
|
|
Button |
Back (near rotary encoder) |
|
|
|
Button |
Tag Track / Remove (near rotary encoder) |
|
|
|
Button |
Disk Eject press |
|
|
|
Button |
Slip |
|
|
|
Button |
Track direction (Latch Reverse) |
set when Direction switch is flipped down |
|
|
Button |
Track direction (Slip Reverse) |
set when Direction switch is held up |
|
|
Button |
Track Filter / Edit (near rotary encoder) |
|
|
|
Button |
Call / Delete |
Part of Hotcue Bank |
|
|
TODO |
TODO |
|
|
|
Button |
32 Loop |
Located in Loop Mode screen popover |
|
|
Button |
16 Loop |
Located in Loop Mode screen popover |
|
|
Button |
8 Loop |
Located in Loop Mode screen popover |
|
|
Button |
4 Loop |
Located in Loop Mode screen popover |
|
|
Button |
2 Loop |
Located in Loop Mode screen popover |
|
|
Button |
1 Loop |
Located in Loop Mode screen popover |
|
|
Button |
1/4 Loop |
Located in Loop Mode screen popover |
|
|
Button |
1/2 Loop |
Located in Loop Mode screen popover |
|
|
Button |
4/8 Beat |
|
|
|
Button |
1 Beatjump Forwards |
Located in Beat Jump screen popover |
|
|
Button |
2 Beatjump Forwards |
Located in Beat Jump screen popover |
|
|
Button |
4 Beatjump Forwards |
Located in Beat Jump screen popover |
|
|
Button |
8 Beatjump Forwards |
Located in Beat Jump screen popover |
|
|
Button |
16 Beatjump Forwards |
Located in Beat Jump screen popover |
|
|
Button |
1 Beatjump Backwards |
Located in Beat Jump screen popover |
|
|
Button |
2 Beatjump backwards |
Located in Beat Jump screen popover |
|
|
Button |
4 Beatjump backwards |
Located in Beat Jump screen popover |
|
|
Button |
8 Beatjump backwards |
Located in Beat Jump screen popover |
|
|
Button |
16 Beatjump backwards |
Located in Beat Jump screen popover |
|
|
Button |
Hotcue A |
|
|
|
Button |
Hotcue B |
|
|
|
Button |
Hotcue C |
|
|
|
Button |
Hotcue D |
|
|
|
Button |
Hotcue E |
|
|
|
Button |
Hotcue F |
|
|
|
Button |
Hotcue G |
|
|
|
Button |
Hotcue H |
|
|
|
Pot |
Vinyl Speed Adjust Touch/Brake |
Min-Max mapped to 0x00-0xFF |
|
|
Pot |
Vinyl Speed Adjust Release/Start |
Min-Max mapped to 0x00-0xFF |
|
|
Pot |
Rotary Encoder |
Position given as absolute ushort LE even though the control is technically an infinite Encoder. |
|
|
Pot |
Tempo Slider |
Min-Max mapped to 1000 in both directions (ushort LE) |
|
|
Pot |
Jogwheel Position |
Not sure why this is a feature of the protocol. Each turn contains approximately 9728 steps (encoded as ushort LE) |
|
|
Encoder |
Jogwheel Speed |
Only contains the absolute speed of the jogwheel. Direction has to be taken from the Enum in |
|
|
Pot |
Needle search position |
Maps start of track to beginning on track from 0 to 599. (ushort LE) |
the Jog Adjust Control as well as presses of the Shortcut Button do not get reported by the CDJ. |
Host→CDJ
It has been observed that Rekordbox sends these control packets roughly every 10ms but larger intervals should also work. However, that would affect output latency and the display quality of "high resolution sections" such as the Time Elapsed/Remaining and LCD of the Jog Wheel.
- SC-LED
-
Single Color LED
- Enum
-
See the attached List of Key-Value pairs (Keys being Integers)
- Boolean
-
Similar to SC-LED but causes a change on the Display instead of changing an LED
- Struct
-
Multiple bytes representing a single compound type
- Byte
-
Single Byte usually representing Integer value
- uShortLE
-
16-bit unsigned Integer serialized in little-endian byte-order. Generally controls some onscreen element
Bytes | Mask | Type | Control | Notes |
---|---|---|---|---|
|
|
— |
— |
First Byte of is always |
|
|
— |
|
Message Type |
|
|
SC-LED |
Play |
|
|
|
SC-LED |
Cue |
|
|
|
Enum |
Cursor Color |
|
|
|
SC-LED |
In/Cue |
|
|
|
SC-LED |
Out |
|
|
|
SC-LED |
Reloop/Exit |
|
|
|
Boolean |
Time mode |
display elapsed time if bit is set, otherwise display remaining time. |
|
|
Boolean |
Auto Cue |
|
|
|
SC-LED |
Rotary Ring |
|
|
|
Enum |
Tempo Range slot |
|
|
|
SC-LED |
Tempo Reset |
|
|
|
SC-LED |
Master Tempo Button |
also known as key-lock to not confuse it with Tempo/BPM/Sync Master |
|
|
SC-LED |
Jogwheel Outside Ring LED (white) |
|
|
|
SC-LED |
Jogwheel Outside Ring LED (red) |
|
|
|
SC-LED & Boolean |
Master |
Also influences border of the BPM display in addition to the Master Button |
|
|
SC-LED |
Sync |
|
|
|
Enum |
Sync Display |
|
|
|
SC-LED |
Slip |
|
|
|
SC-LED |
Reverse |
|
|
|
Enum |
Jog Mode |
|
|
|
Enum |
Quantize Resolution |
|
|
|
Boolean |
Quantize Screen Color |
if bit is set, element will be displayed in red, otherwise grey |
|
|
SC-LED |
Quantize |
|
|
|
Boolean |
Enable blue phase meter? |
TODO |
|
|
TODO |
TODO |
|
|
|
TODO |
TODO |
|
|
|
Boolean |
Jogwheel display |
if bit set, jogwheel display is enabled, if not set, jogwheel display will display plain white ring. |
|
|
Boolean |
Continue Mode |
Enables Track number display and changes text from "single" to "continue" |
|
|
Boolean |
BPM Display visible |
|
|
|
Boolean |
Disable Tempo Delta |
Exact Purpose is unknown, also changes "Tempo" to "Bpm" |
|
|
Boolean |
Loop size Display Color enable |
if bit is set, loop size display is greyed out (indicating it is disabled) |
|
|
Enum |
Current Loop Size |
|
|
|
Struct |
Elapsed time of track |
See time-struct |
|
|
Struct |
Absolute Length of track |
See time-struct |
|
|
TODO |
TODO |
|
|
|
Byte |
Whole BPM |
The whole (integer) part of the BPM displayed in the BPM field. |
|
|
Byte |
Fractional BPM |
single digit fractional part of the BPM displayed in the BPM field. |
|
|
uShortLE |
Tempo Delta |
Relative Tempo delta in comparison to track Tempo (given in percent) multiplied by 100 so it can be transported as integer |
|
TODO |
TODO |
||
|
|
Struct |
Elapsed time (Slip mode) |
When Slip-mode is active, manipulations such as looping, scratching, etc cause a slip mode cursor to keep track of the position in the track so the software can jump back to that point once the DJ has stopped manipulating the track. This time-struct tells the CDJ the position of that cursor. |
|
|
uShortLE |
same as |
TODO: investigate further |
Time-Struct
Whenever the CDJ has to transmit a relative amount of time, it serializes the time information into the following four bytes:
judging from the traffic observed between the host and the CDJ, these fields are unsigned and thus, cannot contain unsigned values. However, this hypothesis has not been confirmed yet. TODO |
- Minutes
-
amount of minutes (integer)
- Seconds
-
amount of seconds in current minutes (so only carries values from 0 to 59)
- Millseconds (LSB/MSB)
-
amount of milliseconds in current second. (serialized as ushort LE)
Serializing time in this way limits the maximum track length a CDJ can deal with via HID to roughly 4 hours and 20 minutes.
TLDR
The previous sections can’t really be shortened. However, for the sake of visualizing the packets, I will provide to bytefield-diagrams illustrating the offsets of compound fields and unknown bits. Each cell contains a bitmask expressed in hexadecimal to identify the bits whose functionality has not been discovered yet.