Package org.deepsymmetry.beatlink
Class PrecisePosition
- java.lang.Object
-
- org.deepsymmetry.beatlink.DeviceUpdate
-
- org.deepsymmetry.beatlink.PrecisePosition
-
public class PrecisePosition extends DeviceUpdate
A device update that reports the exact playback position of a CDJ-3000 (or newer?) player, even if it is not currently playing. These are sent very frequently (roughly every 30 milliseconds) as long as the player has a track loaded.- Author:
- James Elliott
-
-
Constructor Summary
Constructors Constructor Description PrecisePosition(DatagramPacket packet)
Constructor sets all the immutable interpreted fields based on the packet content.
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description int
getBeatWithinBar()
Get the position within a measure of music at which the most recent beat fell (a value from 1 to 4, where 1 represents the downbeat).int
getBpm()
Get the playback BPM at the time of the update.Integer
getDeviceMasterIsBeingYieldedTo()
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 benull
.double
getEffectiveTempo()
Get the effective tempo reflected by this update, which reflects both its track BPM and pitch as needed.int
getPitch()
Get the device pitch at the time of the beat.int
getPlaybackPosition()
Get the current position of the player's playback head within the track, in milliseconds.int
getTrackLength()
Get the length of the track that is loaded in the player, in seconds, rounded down to the nearest second.boolean
isBeatWithinBarMeaningful()
Returnstrue
if this update is coming from a device wheregetBeatWithinBar()
can reasonably be expected to have musical significance, because it respects the way a track was configured within rekordbox.boolean
isSynced()
Was this beat sent by a device that is synced to the tempo master?boolean
isTempoMaster()
Was this beat sent by the current tempo master?String
toString()
-
Methods inherited from class org.deepsymmetry.beatlink.DeviceUpdate
getAddress, getDeviceName, getDeviceNumber, getPacketBytes, getTimestamp, isPreNexusCdj
-
-
-
-
Constructor Detail
-
PrecisePosition
public PrecisePosition(DatagramPacket packet)
Constructor sets all the immutable interpreted fields based on the packet content.- Parameters:
packet
- the beat announcement packet that was received
-
-
Method Detail
-
getTrackLength
public int getTrackLength()
Get the length of the track that is loaded in the player, in seconds, rounded down to the nearest second.- Returns:
- the track length
-
getPlaybackPosition
public int getPlaybackPosition()
Get the current position of the player's playback head within the track, in milliseconds.- Returns:
- the playback position
-
getPitch
public int getPitch()
Get the device pitch at the time of the beat. 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 toUtil.pitchToPercentage(long)
, and the corresponding fractional scaling value by passing it toUtil.pitchToMultiplier(long)
.- Specified by:
getPitch
in classDeviceUpdate
- Returns:
- the raw device pitch
-
getBpm
public int getBpm()
Description copied from class:DeviceUpdate
Get the playback 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. Mixers always report a pitch of +0%, so tempo changes are purely reflected in the BPM value.When the CDJ has just started up and no track has been loaded, it will report a BPM of 65535.
- Specified by:
getBpm
in classDeviceUpdate
- Returns:
- the track BPM to two decimal places multiplied by 100
-
toString
public String toString()
- Overrides:
toString
in classDeviceUpdate
-
isTempoMaster
public boolean isTempoMaster()
Was this beat sent by the current tempo master?- Specified by:
isTempoMaster
in classDeviceUpdate
- Returns:
true
if the device that sent this beat is the master- Throws:
IllegalStateException
- if theVirtualCdj
is not running
-
isSynced
public boolean isSynced()
Was this beat sent by a device that is synced to the tempo master?- Specified by:
isSynced
in classDeviceUpdate
- Returns:
true
if the device that sent this beat is synced- Throws:
IllegalStateException
- if theVirtualCdj
is not running
-
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 benull
.- Specified by:
getDeviceMasterIsBeingYieldedTo
in classDeviceUpdate
- 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 classDeviceUpdate
- Returns:
- the beats per minute this device is reporting
-
getBeatWithinBar
public int getBeatWithinBar()
Get the position within a measure of music at which the most recent beat fell (a value from 1 to 4, where 1 represents the downbeat). This value will be accurate for players when the track was properly configured within rekordbox (and if the music follows a standard House 4/4 time signature). The mixer makes no effort to synchronize downbeats with players, however, so this value is meaningless when coming from the mixer. The usefulness of this value can be checked withisBeatWithinBarMeaningful()
.- Specified by:
getBeatWithinBar
in classDeviceUpdate
- Returns:
- the beat number within the current measure of music
- Throws:
IllegalStateException
- if theVirtualCdj
is not running
-
isBeatWithinBarMeaningful
public boolean isBeatWithinBarMeaningful()
Returnstrue
if this update is coming from a device wheregetBeatWithinBar()
can reasonably be expected to have musical significance, because it respects the way a track was configured within rekordbox.- Specified by:
isBeatWithinBarMeaningful
in classDeviceUpdate
- Returns:
- true for status packets from players, false for status packets from mixers
- Throws:
IllegalStateException
- if theVirtualCdj
is not running
-
-