Detailed Device Status
Although some useful information can be obtained simply by watching broadcast traffic on a network containing Pioneer gear, in order to get important details it is necessary to cause the gear to send you information directly. This can be done by simulating a “Virtual CDJ”.[1]
Creating a Virtual CDJ
To do this, bind a UDP server socket to port 50002 on the network interface on which you are receiving DJ-Link traffic, and start sending keep-alive packets to port 50000 on the broadcast address as if you were a CDJ. Copy the structure of a CDJ keep-alive packet, but use the actual MAC and IP addresses of the network interface on which you are receiving DJ-Link traffic, so the devices can see how to reach you.
You can use a value like 05
for D (the device/player number) so as
not to conflict with any actual players you have on the network, and
any name you would like. As long as you are sending these packets
roughly every 1.5 seconds, the other players and mixers will begin
sending packets directly to the socket you have opened on port 50002.
Be forewarned that use of a non-standard player number (outside
the range 1–4) will interfere with your ability to perform metadata
requests using dbserver queries as described in
the Track Metadata section. In situations
where there are four actual players on the network you can use
alternate ways to get the data, as described in
Reading Data with Four Players.
|
Each device seems to send status packets roughly every 200 milliseconds.
We are probably not finished learning all the information which can be gleaned from these packets, but here is what we know so far.[2]
Mixer Status Packets
Packets from the mixer will have a length of 38
bytes and the
following content:
Since these use packet subtype 00
, the lenr value reports there
are 14
bytes remaining after it.
Packets coming from a DJM-2000 nexus connected as the only mixer on
the network contain a value of 21
for their Device Number D
(bytes 21
and 24
).
It seems that rekordbox sometimes sends “mixer status” packets like
this as well, but with yet another packet subtype variant: it sends a
value of 01
for byte 20
, and for packets with that subtype,
the length at bytes 22
-23
is a lenp value, reporting the
length of the entire packet, rather than the number of bytes remaining
in the packet. The packets are otherwise identical.
The value marked F at byte 27
is evidently a status flag
equivalent to the CDJ version shown below,
although on a mixer the only two values seen so far are f0
when it
is the tempo master, and d0
when it is not. So evidently the mixer
always considers itself to be playing and synced, but never on-air.
There are two places that might contain pitch values,
bytes 28
–2b
and bytes 30
–33
, but since they
always 100000
(or +0%), we can’t be sure. The first value is
structurally in the same place with respect to BPM as it is found in
all other packets containing pitch information, so that is the one we
are assuming is definitive. In any case, since it is always +0%, the
current tempo in beats-per-minute identified by the mixer can be
obtained as (only the byte offsets are hexadecimal):
This value is labeled BPM in the diagram. Unfortunately, this BPM seems to only be valid when a rekordbox-analyzed source is playing; when the mixer is doing its own beat detection from unanalyzed audio sources, even though it displays the detected BPM on the mixer itself, and uses that to drive its beat effects, it does not send that value in these packets.
The current beat number within a bar (1, 2, 3 or 4) is sent in , labeled Bb. However, the beat number is not synchronized with the master player, and these packets do not arrive at the same time as the beat started anyway, so this value is not useful for much. The beat number should be determined, when needed, from beat packets that are sent by the master player.
The value at , labeled Mh (master handoff),
is used to hand off the tempo master role. It starts out with the
value 00
when there is no Master player, but as soon as one appears
it becomes ff
. If the mixer has been the tempo master and it is
currently yielding this role to another player, this value will be the
player number that is becoming tempo master during that handoff, as
described in Tempo Master Handoff.
CDJ Status Packets
Packets from a CDJ have the content shown below. Nexus players have a
length of d4
bytes. Older players send d0
-byte packets with slightly
less information (notably the current beat number is not available, so it
is impossible to interpolate playback position to calculate a virtual
timecode value). Newer firmware and Nexus 2 players send packets that are
11c
or 124
bytes long. CDJ-3000 devices send packets that are 200
bytes long.
These use yet another packet structure variant following the device
name. As always the byte after the name has the value 01
, but the
subtype value which follows that (at byte 20
) has the value
03
here, rather than 00
as we saw in the mixer status packets.
Values of 03
, 04
and 06
have been seen which may indicate this
byte represents the protocol or packet version.
Packets of subtype 03
seem structurally equivalent to subtype 00
however: the subtype indicator is followed by the Device Number D at
byte 21
and a length-remaining value lenr at
bytes 22
–23
. If anyone can think of a reason why these
packets don’t simply reuse subtype 00
, please share it!
The Device Number in D (bytes 21
and 24
) is the Player
Number as displayed on the CDJ itself. In the case of this capture,
the value of lenr was 00b0
.
The activity flag A at byte 27
seems to be 00
when the
player is idle, and 01
when it is playing, searching, or loading a
track.
When a track is loaded, the device from which the track was loaded is
reported in Dr at byte 28
(if the track was loaded from
the local device, this will be the same as D; if it was loaded over
the Link, it will be the number of a different device). When no track
is loaded, Dr has the value 00
.
Similarly, Sr at byte 29
reports the slot from which the
track was loaded: the value 00
means no track is loaded, 01
means
the CD drive, 02
means the SD slot, and 03
means the USB slot.
When a track is loaded from a rekordbox collection on a laptop, Sr
has the value 04
. Tr at byte 2a
indicates the track
type. It has the value 00
when no track is loaded, 01
when a
rekordbox track is loaded, 02
when an unanalyzed track is loaded
(from a media slot without a rekordbox database, including from a data
disc), and 05
when an audio CD track is loaded.
The XDJ-XZ presents an unusual situation because it embodies two separate players and a mixer all sharing the same IP address. Because of limitiations in the protocol, that means it can only offer one pair of slots to the network, so its two USB slots are represented as though they belong to player 1. The slot labeled USB 1 is treated on the network as the SD slot, and the slot labeled USB 2 as the USB slot. |
The field rekordbox at bytes 2c
–2f
contains the rekordbox
database ID of the loaded track when a rekordbox track is being
played. When a non-rekordboxtrack is loaded from a media slot, it is
still a unique ID by which the track can be identified for metadata
requests, and when an audio CD track is loaded, this is just the track
number. In all cases, combined with the player number and slot
information, this can be used to request the track metadata as
described in the Track Metadata
section.
The track number being played (its position within a playlist or other
scrolling list of tracks, as displayed on the CDJ) can be found at
bytes 32
and 33
, labeled Track. (It may be a 4-byte value
and also include bytes 30
and 31
, but that would seem an
unmanageable number of tracks to search through.)
The field dl at byte 37
was given this label because we
first believed it to indicate when a disc is loaded. It has the value
00
when the disc slot is empty, and seems to have the value 1e
when a CD Audio disc is loaded, and 11
when a data disc containing
files in MP3, AAC, WAV or AIFF format is loaded. However, we later
noticed that it also gets non-zero values when a track is loaded from
a playlist (05
) or another player menu (different values, depending
on the type of menu; if anyone would like to take the time to record
all the different values and their meanings, a report on the
Zulip
stream or—if you are willing to fork the project and update this
document, a pull request—would be extremely welcome). Relatedly, when
a track is loaded from a disc, playlist, or menu, the field dn at
bytes 46
–47
changes from 0000
to the number of tracks on
the disc or in the playlist or menu (a data disc will generally have
one track).
Some of the fields shown as having value 00
in this region will
sometimes have other values in them; their meanings are simply not yet
known. If you notice any patterns or figure anything out please let
us know on
Zulip
or open a pull request!
Byte 6a
, labeled Ua (for “USB activity”), alternates
between the values 04
and 06
when there is USB activity—it may
even alternate in time with the flashing USB indicator LED on the
player, although visual inspection suggests there is not a perfect
correlation. Byte 6b
, Sa, is the same kind of activity
indicator for the SD slot.
Byte 6f
(Ul for “USB local”) has the value 04
when
there is no USB media loaded, 00
when USB is loaded, and 02
or
03
when the USB Stop button has been pressed and the USB media is
being unmounted. Byte 73
(Sl for “SD local”) has the
value 04
when there is no SD media loaded, 00
when SD is loaded,
and 02
or 03
when the SD door has been opened and the SD media is
being unmounted.
Byte 75
, labeled L (for “Link available”), appears to have
the value 01
whenever USB, SD, or CD media is present in any player
on the network, whether or not the Link option is chosen in the other
players, and 00
otherwise.
Byte 7b
, labeled P1, appears to describe the current play
mode. The values seen so far, and their apparent meanings, are:
Value | Meaning |
---|---|
|
No track is loaded. |
|
A track is in the process of loading. |
|
Player is playing normally. |
|
Player is playing a loop. |
|
Player is paused anywhere other than the cue point. |
|
Player is paused at the cue point. |
|
Cue Play is in progress (playback while the cue button is held down). |
|
Cue scratch is in progress. |
|
Player is searching forwards or backwards. |
|
Audio CD has spun down due to lack of use. |
|
Player reached the end of the track and stopped. |
The value Firmware at bytes 7c
–7f
is an ASCII
represenation of the firmware version running in the player.
The value Syncn at bytes 84
–87
changes whenever a
player gives up being the tempo master; at that point it gets set to a
value one higher than the highest Syncn value reported by any
other player on the network. This is part of the Baroque master
handoff dance described in Tempo Master
Handoff.
Byte 89
, labeled F, is a bit field containing some very
useful status flags.[3]
It seems to only be available on nexus (and later) players, and older
ones always send 00
for this byte, which greatly limits the inferences
we can make about their state:
Bit 6, “Play”, is 1 when the player is playing, and 0 when it is idle. Bit 5, “Master”, indicates whether it is the current tempo master, while bit 4, “Sync” tracks whether it is in sync mode. Bit 3, “On-Air“, is 1 when it believes its output can be heard in the mix (so its platter lights will be red rather than white); this requires cooperation with the mixer. Finally, bit 1, “BPM”, is 1 when the player has degraded in to BPM Sync mode (that is, it is in Sync mode, but the DJ has used pitch bend, e.g. nudged the jog wheel, so while it is still tracking the tempo of the Master player, it is no longer trying to align beats).
Byte 8b
, labeled P2 seems to be another play state indicator,
having the value 7a
when playing and 7e
when stopped. When the CDJ
is trying to play, but is being held in place by the DJ holding down
on the jog wheel, P1 considers it to be playing (value 03
),
while P2 considers it to be stopped (value 7e
). Non-nexus
players seem to use the value 6a
when playing and 6e
when stopped,
while nxs2 players use the values fa
and fe
, and the XDJ-XZ uses
the values 9a
and 9e
so this seems to be another bit field like
F.
There are four different places where pitch information appears in
these packets: Pitch1 at bytes 8c
–8f
, Pitch2 at
bytes 98
–9b
, Pitch3 at bytes c0
–c3
, and
Pitch4 at bytes c4
–c7
.
Each of these values represents a four-byte pitch adjustment
percentage, where 00100000
represents no adjustment (0%), 00000000
represents slowing all the way to a complete stop (−100%, reachable
only in Wide tempo mode), and 00200000
represents playing at double
speed (+100%).
Note that if playback is stopped by pushing the pitch fader all the way to −100% in Wide mode, both P1 and P2 still show it as playing, which is different than when the jog wheel is held down, since P2 shows a stop in the latter situation.
The pitch adjustment percentage represented by Pitch1 would be calculated by multiplying decimal 100 by the following hexadecimal equation:
We don’t know why there are so many copies of the pitch information, or all circumstances under which they might differ from each other, but it seems that Pitch1 and Pitch3 report the current pitch adjustment actually in effect (as reflected on the BPM display), whether it is due to the local pitch fader, or a synced tempo master.
Pitch2 and Pitch4 are always tied to the position of the local
pitch fader, unless Tempo Reset is active, effectively locking the
pitch fader to 0% and Pitch2 and Pitch4 to 100000
, or the
player is paused or the jog wheel is being held down, freezing
playback and locking the local pitch to −100%, in which case they both
have the value 000000
.
When playback stops, either due to the play button being pressed or
the jog wheel held down, the value of Pitch4 drops to 000000
instantly, while the value of Pitch2 drops over time, reflecting
the gradual slowdown of playback which is controlled by the player’s
brake speed setting. When playback starts, again either due to the
play button being pressed or the jog wheel being released, both
Pitch2 and Pitch4 gradually rise to the target pitch, at a
speed controlled by the player’s release speed setting.
If the player is not synced, but the current pitch is different than what the pitch fader would indicate (in other words, the player is in the state where it tells you to move the pitch fader to the current BPM in order to change the pitch), moving the pitch fader changes the values of Pitch2 and Pitch4 until they match Pitch1 and Pitch3 and begin to affect the actual effective pitch. From that point on, moving the pitch fader sets the value of all of Pitch1, Pitch2, Pitch3, and Pitch4. This all seems more complicated than it really needs to be…
The current BPM of the track (the BPM at the point that is currently
being played, or at the location where the player is currently paused)
can be found at bytes 92
–93
(labeled BPM). It is a
two-byte integer representing one hundred times the current track BPM.
So, the current track BPM value to two decimal places can be
calculated as (only byte offsets are hexadecimal):
In order to obtain the actual playing BPM (the value shown in the BPM display), this value must be multiplied by the current effective pitch, calculated from Pitch1 as described above. Since calculating the effective BPM reported by a CDJ is a common operation, here a simplified hexadecimal equation that results in the effective BPM to two decimal places, by combinining the BPM and Pitch1 values:
Because Rekordbox and the CDJs support tracks with variable BPM, this
value can and does change over the course of playing such tracks. When
no track is loaded, BPM has the value ffff
.
Mv (bytes 90
–91
) seems to control whether the BPM value is
accepted when this player is the master. It has the value 7fff
when
no track is loaded, 8000
when a rekordbox track is loaded, and
0000
when a non-rekordbox track (like from a physical CD) is loaded,
and only when the value is 8000
are tempos from this player accepted
when it is acting as master (otherwise the mixer shows the master to
have a tempo of “---.-
” and other players do not respond to its
tempo changes).
Byte 9d
(labeled P3) seems to communicate additional
information about the current play mode. The meanings that we have
found so far are:
Value | Meaning |
---|---|
|
No track is loaded. |
|
Player is paused or playing in Reverse mode. |
|
Player is playing in Forward mode with jog mode set to Vinyl. |
|
Player is playing in Forward mode with jog mode set to CDJ. |
Byte 9e
(labeled Mm for “Master meaningful“) is another
representation of whether this player is currently the tempo master
(in addition to bit 5 of F, as shown in the
status flag bits diagram). It has the value 00
when the player is
not the master, the value 01
when it is tempo master and is playing
a rekordbox-analyzed track, so that actually has a meaningful effect,
and the value 02
when it is supposed to be the master (and the value
of F still indicates that it is), but it is playing a non-rekordbox
track, so it is unable to send tempo and beat information to other
players.
The following byte, 9f
(labeled Mh for “Master handoff“), is
related. As described in Tempo Master
Handoff, this normally has the value ff
. But when this player is
giving up the role of tempo master in response to a request from
another player that wants to take over, it holds that player’s device
number until it sees that device announce itself as the new master, at
which point it turns off its own master flags, and this value goes
back to ff
.
The 4-byte beat counter (which counts each beat from 1 through the end
of the track) is found in bytes a0
–a3
, labeled Beat. When the
player is paused at the start of the track, this seems to hold the
value 0, even though it is beat 1, and when no rekordbox-analyzed
track is loaded, and in packets from non-nexus players, this holds the
value ffffffff
.
The counter Bb at byte a6
counts out the beat within each
bar, cycling 1 → 2 → 3 → 4 repeatedly, and can be used to identify the
down beat (as is used in the Master Player display on the CDJs as a
mixing aid). Again, when no reckordbox-analyzed track is loaded, this
holds the value 0. If you want to synchronize events to the down beat,
use the CDJ status packets’ F value to identify the master player,
but use the beat packets sent by that player (described in
Tracking BPM and Beats) to determine when the
beats are actually happening.
A countdown timer to the next saved cue point is available in
bytes a4
–a5
(labeled Cue). If there is no saved cue point
after the current play location in the track, or if it is further than
64 bars ahead, these bytes contain the value 01ff
and the CDJ
displays “--.- bars
”. As soon as there are just 64 bars (256 beats)
to go before the next cue point, this value becomes 0100
. This is
the point at which the CDJ starts to display a countdown, which it
displays as “63.4 bars
”. As each beat goes by, this value decreases
by 1, until the cue point is about to be reached, at which point the
value is 0001
and the CDJ displays “00.1 bars
”. On the beat on
which the cue point was saved the value is 0000
and the CDJ displays
“00.0 Bars
”. On the next beat, the value becomes determined by the
next cue point (if any) in the track.
Byte b7
, labeled Mp, seems to indicate local media presence status
on the CDJ-3000. For other players, this value remains 0
.
Byte b8
, labeled Ue, has the value 1
if USB media has been
unsafely ejected. If media is inserted, or is safely ejected, this
value is 0
.
Byte b9
, labeled Se, has the value 1
if SD media has been
unsafely ejected. If media is inserted, or is safely ejected, this
value is 0
.
Byte ba
, labeled el, has the value 1
if an emergency loop is
currently active. Once a new track is loaded, this value returns to
0
.
Even on CDJ-3000 players with the latest firmware, which uses
full-track caching to eliminate the kinds of emergency loops which
used to previously occur, this value still becomes 1 when the player
loses contact with the source of the track media. In that state a
yellow exlamation symbol appears on the screen, and some features like
the track skip buttons are disabled. On these players it might be more
aptly described as emergency mode than an actual emergency loop.
|
Bytes c8
-cb
seem to contain a 4-byte packet counter labeled
Packet, which is incremented for each packet sent by the player. (I
am just guessing it is four bytes long, I have not yet watched long
enough for the count to need more than the last three bytes). Some
players do not seem to increment the counter, e.g. CDJ-3000 is fixed
at 00 00 00 00
. Counters are instead seen incrementing in packets
sent over UDP port 50004.
Byte cc
, labeled nx, seems to have the value 0f
for nexus
players, 1f
for the XDJ-XZ and CDJ-3000, and 05
for older players.
Byte cd
, labeled t, is used to indicate when a player supports
Touch Audio, by setting bit 5.
Byte fa
(labeled Wc) indicates the Waveform Color setting the
player is set to.
Value | Meaning |
---|---|
|
Blue |
|
RGB |
|
3-Band |
Byte fd
(labeled Wp) indicates the Waveform Current Position setting
the player is set to.
Value | Meaning |
---|---|
|
Center |
|
Left |
Bytes 11d
-11e
(Buff and Bufb respectively) seem
to indicate the in-memory buffer status of the player. The buffer is shown
on the player under the waveform with a thin red bar. As this bar expands,
the values in 11d
and 11e
increase. 11d
indicates the buffer length
in the forward direction from the playhead, 11e
indicates the buffer
length in the backwards direction from the playhead.
Byte 11f
(Bufs for “Buffer Status”) changes to value 01
when the
entire track is buffered in memory.
Byte 158
(labeled Mt) indicates whether Master Tempo is engaged
on the deck.
Bytes 15c
-15e
(labeled Key) indicate the key of the current track,
taking into account Master Tempo and the Tempo Slider position but before
Key Shift is applied. Byte 15c
represents the note, byte 15d
is 00
for minor and 01
for major. Byte 15e
represents the accidental of the
note, 00
for natural, 01
for sharp, and ff
for flat. However if the
Master Tempo is off and the Tempo Slider is moved outside the original key
of the track, byte 15e
will change to 64
.
Value | Key |
---|---|
|
Am |
|
B♭m |
|
Bm |
|
Cm |
|
C♯m |
|
Dm |
|
E♭m |
|
Em |
|
Fm |
|
F♯m |
|
Gm |
|
A♭m |
|
C |
|
D♭ |
|
D |
|
E♭ |
|
E |
|
F |
|
F♯ |
|
G |
|
A♭ |
|
A |
|
B♭ |
|
B |
Bytes 164
-16b
(labeled KeyShift) is a 64-bit signed value
indicating the Key Shift value of a CDJ-3000 in cents. The value changes
in increments of 64
(or 100 cents) for each semitone moved.
Value | Semitones Shifted |
---|---|
|
+12 |
… |
|
|
+2 |
|
+1 |
|
0 |
|
-1 |
|
-2 |
… |
|
|
-12 |
Bytes 1b6
-1b9
(labeled Loops for “Loop Start”) will be
non-zero when a CDJ-3000 is actively playing a loop (whether that loop
was stored in the track metadata or dynamically set up by the DJ). It
indicates the starting position of the loop within the track in
milliseconds, using a new format. To calculate the start time,
multiply this value by 65,536, then divide by 1,000.
Bytes 1b3
-1c1
(labeled Loope for “Loop End”) will be also
non-zero when a CDJ-3000 is actively playing a loop (whether that loop
was stored in the track metadata or dynamically set up by the DJ). It
indicates the ending position of the loop within the track in
milliseconds, using the same format as Loops: multiply this value
by 65,536, then divide by 1,000.
Bytes 1c8
-1c9
(labeled Loopb for “Loop Beats”) will be also be
non-zero when a CDJ-3000 is actively playing a loop (whether that loop
was stored in the track metadata or dynamically set up by the DJ). It
holds the number of whole beats in the loop, so is not meaningful for
sub-beat loops.
Rekordbox Status packets
Rekordbox sends status packets which appear to be essentially
identical to those sent by a mixer, sending
“rekordbox” as its device name. The device number D
(bytes 21
and 24
) seems to be 11
, although it will
probably use conflict resolution to pick an unused number if multiple
copies are running on the network. Similarly, the first instance of
rekordbox mobile picks a D value of 29
, and presumably increments
from there.
The F value we have seen remains consistent as a status flag,
showing c0
which would indicate that it is always “playing” but not
synced, tempo master, nor on the air. The BPM value seems to track
that of the master player, and the same potential pitch values (fixed
at 100000
, or +0%) are present, as is Mh. Bb always seems to
be zero.