Class CdjStatus


  • public class CdjStatus
    extends DeviceUpdate
    Represents a status update sent by a CDJ (or perhaps other player) on a DJ Link network.
    Author:
    James Elliott
    • Field Detail

      • MASTER_HAND_OFF

        public static final int MASTER_HAND_OFF
        The byte within a status packet which indicates that the device is in the process of handing off the tempo master role to anther device, labeled Mh in the Packet Analysis document.

        Normally it holds the value 0xff, but during a tempo master hand-off, it holds the device number of the incoming tempo master, until that device asserts the master state, after which this device will stop doing so.

        See Also:
        Constant Field Values
      • ON_AIR_FLAG

        public static final int ON_AIR_FLAG
        The bit within the status flag that indicates the player is on the air, as illustrated in the Packet Analysis document. A player is considered to be on the air when it is connected to a mixer channel that is not faded out. Only Nexus mixers seem to support this capability.
        See Also:
        Constant Field Values
      • TRACK_SOURCE_SLOT_MAP

        public static final Map<Byte,​CdjStatus.TrackSourceSlot> TRACK_SOURCE_SLOT_MAP
        Allows a known track source slot value to be looked up based on the byte that was seen in a status update.
      • TRACK_TYPE_MAP

        public static final Map<Byte,​CdjStatus.TrackType> TRACK_TYPE_MAP
        Allows a known track source type value to be looked up based on the byte that was seen in a status update.
      • PLAY_STATE_1_MAP

        public static final Map<Byte,​CdjStatus.PlayState1> PLAY_STATE_1_MAP
        Allows a known P1 value to be looked up based on the byte that was seen in a status update.
      • PLAY_STATE_2_MAP

        public static final Map<Byte,​CdjStatus.PlayState2> PLAY_STATE_2_MAP
        Allows a known P2 value to be looked up based on the byte that was seen in a status update.
      • PLAY_STATE_3_MAP

        public static final Map<Byte,​CdjStatus.PlayState3> PLAY_STATE_3_MAP
        Allows a known P3 value to be looked up based on the byte that was seen in a status update.
      • MINIMUM_PACKET_SIZE

        public static final int MINIMUM_PACKET_SIZE
        The smallest packet size from which we can be constructed. Anything less than this and we are missing crucial information.
        See Also:
        Constant Field Values
    • Constructor Detail

      • CdjStatus

        public CdjStatus​(DatagramPacket packet)
        Constructor sets all the immutable interpreted fields based on the packet content.
        Parameters:
        packet - the CDJ status packet that was received
    • Method Detail

      • getTrackSourcePlayer

        public int getTrackSourcePlayer()
        Get the device number of the player from which the track was loaded, if any; labeled Dr in the Packet Analysis document.
        Returns:
        the device number from which the current track was loaded
      • getRekordboxId

        public int getRekordboxId()
        Get the rekordbox ID of the track that was loaded, if any; labeled rekordbox in Figure 11 of the Packet Analysis document. Will be zero if no track is loaded, and is simply the track number when an ordinary audio CD track has been loaded.
        Returns:
        the rekordbox database ID of the current track
      • getPitch

        public int getPitch()
        Get the device pitch at the time of the update. This is an integer ranging from 0 to 2097152, which corresponds to a range between completely stopping playback to playing at twice normal tempo. The equivalent percentage value can be obtained by passing the pitch to Util.pitchToPercentage(long), and the corresponding fractional scaling value by passing it to Util.pitchToMultiplier(long).

        CDJ update packets actually have four copies of the pitch value which behave slightly differently under different circumstances. This method returns one which seems to provide the most useful information (labeled Pitch1 in the Packet Analysis document), reflecting the effective BPM currently being played when it is combined with the track BPM. To probe the other pitch values that were reported, you can use getPitch(int).

        Specified by:
        getPitch in class DeviceUpdate
        Returns:
        the raw effective device pitch at the time of the update
      • getPitch

        public int getPitch​(int number)
        Get a specific copy of the device pitch information at the time of the update. This is an integer ranging from 0 to 2097152, which corresponds to a range between completely stopping playback to playing at twice normal tempo. The equivalent percentage value can be obtained by passing the pitch to Util.pitchToPercentage(long), and the corresponding fractional scaling value by passing it to Util.pitchToMultiplier(long).

        CDJ update packets contain four copies of the pitch value which behave slightly differently under different circumstances, labeled Pitch1 through Pitch4 in the Packet Analysis document. This method returns the one you choose by specifying number. If all you want is the current effective pitch, you can use getPitch().

        Parameters:
        number - the subscript identifying the copy of the pitch information you are interested in
        Returns:
        the specified raw device pitch information copy found in the update
      • getBpm

        public int getBpm()
        Get the track BPM at the time of the update. This is an integer representing the BPM times 100, so a track running at 120.5 BPM would be represented by the value 12050.

        When the CDJ has just started up and no track has been loaded, it will report a BPM of 65535.

        Specified by:
        getBpm in class DeviceUpdate
        Returns:
        the track BPM to two decimal places multiplied by 100
      • getBeatWithinBar

        public int getBeatWithinBar()
        Get the position within a measure of music at which the most recent beat occurred (a value from 1 to 4, where 1 represents the down beat). This value will be accurate when the track was properly configured within rekordbox (and if the music follows a standard House 4/4 time signature).

        When the track being played has not been analyzed by rekordbox, or is playing on a non-nexus player, this value will always be zero.

        Specified by:
        getBeatWithinBar in class DeviceUpdate
        Returns:
        the beat number within the current measure of music
      • isBeatWithinBarMeaningful

        public boolean isBeatWithinBarMeaningful()
        Returns true if this beat is coming from a device where getBeatWithinBar() can reasonably be expected to have musical significance, because it respects the way a track was configured within rekordbox. For CDJs this is true whenever the value is not zero (i.e. this is a nexus player playing a track that was analyzed by rekordbox), because players report their beats according to rekordbox-identified measures.
        Specified by:
        isBeatWithinBarMeaningful in class DeviceUpdate
        Returns:
        true whenever we are reporting a non-zero value
      • isTempoMaster

        public boolean isTempoMaster()
        Is this CDJ reporting itself to be the current tempo master?
        Specified by:
        isTempoMaster in class DeviceUpdate
        Returns:
        true if the player that sent this update is the master
      • getDeviceMasterIsBeingYieldedTo

        public Integer getDeviceMasterIsBeingYieldedTo()
        Description copied from class: DeviceUpdate
        If this packet indicates the device in the process of yielding the tempo master role to another player, this will hold the device number of that player, otherwise it will be null.
        Specified by:
        getDeviceMasterIsBeingYieldedTo in class DeviceUpdate
        Returns:
        the device number, if any, this update is yielding the tempo master role to
      • getEffectiveTempo

        public double getEffectiveTempo()
        Description copied from class: DeviceUpdate
        Get the effective tempo reflected by this update, which reflects both its track BPM and pitch as needed.
        Specified by:
        getEffectiveTempo in class DeviceUpdate
        Returns:
        the beats per minute this device is reporting
      • isPlaying

        public boolean isPlaying()
        Was the CDJ playing a track when this update was sent?
        Returns:
        true if the play flag was set, or, if this seems to be a non-nexus player, if P1 has a value corresponding to a playing state.
      • isBpmOnlySynced

        public boolean isBpmOnlySynced()
        Was the CDJ in degraded BPM Sync mode when this update was sent? This indicates that the player had been in Sync mode, but the DJ used pitch bend (for example by nudging the jog wheel), so while it is still tracking the tempo of the master player, it is no longer aligning beats.
        Returns:
        true if the bpm-sync flag was set
      • isSynced

        public boolean isSynced()
        Was the CDJ in Sync mode when this update was sent?
        Specified by:
        isSynced in class DeviceUpdate
        Returns:
        true if the sync flag was set
      • isOnAir

        public boolean isOnAir()
        Was the CDJ on the air when this update was sent? A player is considered to be on the air when it is connected to a mixer channel that is not faded out. Only Nexus mixers seem to support this capability.
        Returns:
        true if the on-air flag was set
      • isLocalUsbLoaded

        public boolean isLocalUsbLoaded()
        Is USB media loaded in this particular CDJ?
        Returns:
        true if there is a USB drive mounted locally
      • isLocalUsbUnloading

        public boolean isLocalUsbUnloading()
        Is USB media being unloaded from this particular CDJ?
        Returns:
        true if there is a local USB drive currently being unmounted
      • isLocalUsbEmpty

        public boolean isLocalUsbEmpty()
        Is USB media absent from this particular CDJ?
        Returns:
        true if there is no local USB drive mounted
      • isLocalSdLoaded

        public boolean isLocalSdLoaded()
        Is SD media loaded in this particular CDJ?
        Returns:
        true if there is a Secure Digital card mounted locally
      • isLocalSdUnloading

        public boolean isLocalSdUnloading()
        Is SD media being unloaded from this particular CDJ?
        Returns:
        true if there is a local Secure Digital card currently being unmounted
      • isLocalSdEmpty

        public boolean isLocalSdEmpty()
        Is SD media absent from this particular CDJ?
        Returns:
        true if there is no local Secure Digital card mounted
      • isDiscSlotEmpty

        public boolean isDiscSlotEmpty()
        Is disc media absent from this particular CDJ? Also returns true if the CD drive has powered off from being unused for too long, in which case isDiscSlotAsleep() will also return true. Note that it's not really accurate to call the slot “empty” because it might still have a disc in it, but it is unmounted when the player is using a playlist or menu of tracks loaded from somewhere else.
        Returns:
        true if there is no disc mounted or the disc drive has powered off
      • isDiscSlotAsleep

        public boolean isDiscSlotAsleep()
        Has this player's CD drive powered down due to prolonged disuse? When this returns true, the other methods asking about the disc slot do not provide reliable values.
        Returns:
        true if the disc drive has powered off
      • getDiscTrackCount

        public int getDiscTrackCount()
        How many tracks are on the mounted disc (or in the playlist or player menu from which the current track was loaded)? Audio CDs will reflect the audio track count, while data discs will generally have one track regardless of how many usable audio files they contain when mounted. Also, if the CD drive has powered off because of an extended period of not being used, when a track had been loaded from that disc, this seems to return 1 (you can check for that condition by calling isDiscSlotAsleep().
        Returns:
        the number of tracks found on the mounted disc or loaded playlist/player menu, or zero if no disc is mounted nor is a playlist/menu in use
      • isTrackLoaded

        public boolean isTrackLoaded()
        Is a track loaded?
        Returns:
        true if a track has been loaded
      • isLooping

        public boolean isLooping()
        Is the player currently playing a loop?
        Returns:
        true if a loop is being played
      • isPaused

        public boolean isPaused()
        Is the player currently paused?
        Returns:
        true if the player is paused, whether or not at the cue point
      • isCued

        public boolean isCued()
        Is the player currently cued?
        Returns:
        true if the player is paused at the cue point
      • isSearching

        public boolean isSearching()
        Is the player currently searching?
        Returns:
        true if the player is searching forwards or backwards
      • isAtEnd

        public boolean isAtEnd()
        Is the player currently stopped at the end of a track?
        Returns:
        true if playback stopped because a track ended
      • isPlayingForwards

        public boolean isPlayingForwards()
        Is the player currently playing forwards?
        Returns:
        true if forward playback is underway
      • isPlayingBackwards

        public boolean isPlayingBackwards()
        Is the player currently playing backwards?
        Returns:
        true if reverse playback is underway
      • isPlayingVinylMode

        public boolean isPlayingVinylMode()
        Is the player currently playing with the jog wheel in Vinyl mode?
        Returns:
        true if forward playback in vinyl mode is underway
      • isPlayingCdjMode

        public boolean isPlayingCdjMode()
        Is the player currently playing with the jog wheel in CDJ mode?
        Returns:
        true if forward playback in CDJ mode is underway
      • isLinkMediaAvailable

        public boolean isLinkMediaAvailable()
        Is link media available somewhere on the network?
        Returns:
        true if some player has USB, SD, or other media that can be linked to
      • isBusy

        public boolean isBusy()
        Check if the player is doing anything.
        Returns:
        true if the player is playing, searching, or loading a track
      • getTrackNumber

        public int getTrackNumber()
        Get the track number of the loaded track. Identifies the track within a playlist or other scrolling list of tracks in the CDJ's browse interface.
        Returns:
        the index of the current track
      • getSyncNumber

        public int getSyncNumber()
        Get the sync counter used in the tempo master handoff.
        Returns:
        a number that becomes one greater than the value reported by any other player when a player gives up its role as the tempo master.
      • getBeatNumber

        public int getBeatNumber()
        Identify the beat of the track that is being played. This counter starts at beat 1 as the track is played, and increments on each beat. When the player is paused at the start of the track before playback begins, the value reported is 0.

        When the track being played has not been analyzed by rekordbox, or is being played on a non-nexus player, this information is not available, and the value -1 is returned.

        Returns:
        the number of the beat within the track that is currently being played, or -1 if unknown
      • getCueCountdown

        public int getCueCountdown()
        How many beats away is the next cue point in the track? If there is no saved cue point after the current play location, or if it is further than 64 bars ahead, the value 511 is returned (and the CDJ will display "--.- bars"). As soon as there are just 64 bars (256 beats) to go before the next cue point, this value becomes 256. 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 decrements by 1, until the cue point is about to be reached, at which point the value is 1 and the CDJ displays "00.1 Bars". On the beat on which the cue point was saved the value is 0 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.
        Returns:
        the cue beat countdown, or 511 if no countdown is in effect
        See Also:
        formatCueCountdown()
      • formatCueCountdown

        public String formatCueCountdown()
        Format a cue countdown indicator in the same way as the CDJ would at this point in the track.
        Returns:
        the value that the CDJ would display to indicate the distance to the next cue
        See Also:
        getCueCountdown()
      • getFirmwareVersion

        public String getFirmwareVersion()
        Return the firmware version string reported in the packet.
        Returns:
        the version of the firmware in the player
      • getPacketNumber

        public long getPacketNumber()
        Return the sequence number of this update packet, a value that increments with each packet sent.
        Returns:
        the number of this packet
      • canReportLooping

        public boolean canReportLooping()
        Checks whether the packet is large enough (from a new enough player, such as the CDJ-3000) that it can report the player's currently active loop boundaries.
        Returns:
        true if the loop-related methods can ever return nonzero values
      • getActiveLoopBeats

        public int getActiveLoopBeats()
        If there is an active loop (and canReportLooping() is true), returns the number of beats in the loop.
        Returns:
        0 if no loop is active (or can be reported), or the number of beats being looped over
      • getLoopStart

        public long getLoopStart()
        If there is an active loop (and canReportLooping() is true), returns position within the track (in milliseconds) at which the loop begins. Because this can conceivably be zero even when a loop is active, code should check getLoopEnd() to determine that loop information is being reported.
        Returns:
        0 if no loop is active (or can be reported), or the millisecond time at which the loop starts
      • getLoopEnd

        public long getLoopEnd()
        If there is an active loop (and canReportLooping() is true), returns position within the track (in milliseconds) at which the loop ends.
        Returns:
        0 if no loop is active (or can be reported), or the millisecond time at which the loop ends