public class VirtualCdj extends LifecycleParticipant
BeatFinder reports, allowing you to keep track of which player is the tempo master, how many beats of
a track have been played, how close a player is getting to its next cue point, and more. It is also the foundation
for finding out the rekordbox ID of the loaded track, which supports all the features associated with the
MetadataFinder.| Modifier and Type | Field and Description |
|---|---|
static int |
UPDATE_PORT
The port to which other devices will send status update messages.
|
| Modifier and Type | Method and Description |
|---|---|
void |
addMasterListener(MasterListener listener)
Adds the specified master listener to receive device updates when there are changes related
to the tempo master.
|
void |
addUpdateListener(DeviceUpdateListener listener)
Adds the specified device update listener to receive device updates whenever they come in.
|
int |
getAnnounceInterval()
Get the interval, in milliseconds, at which we broadcast presence announcements on the network to pose as
a virtual CDJ.
|
InetAddress |
getBroadcastAddress()
Return the broadcast address used to reach the DJ Link network.
|
static String |
getDeviceName()
Get the name to be used in announcing our presence on the network.
|
byte |
getDeviceNumber()
Get the device number that is used when sending presence announcements on the network to pose as a virtual CDJ.
|
static VirtualCdj |
getInstance()
Get the singleton instance of this class.
|
Set<DeviceUpdate> |
getLatestStatus()
Get the most recent status we have seen from all devices that are recent enough to be considered still
active on the network.
|
DeviceUpdate |
getLatestStatusFor(DeviceAnnouncement device)
Look up the most recent status we have seen for a device, given its device announcement packet as returned
by
DeviceFinder.getCurrentDevices(). |
DeviceUpdate |
getLatestStatusFor(DeviceUpdate device)
Look up the most recent status we have seen for a device, given another update from it, which might be a
beat packet containing far less information.
|
DeviceUpdate |
getLatestStatusFor(int deviceNumber)
Look up the most recent status we have seen for a device from a device identifying itself
with the specified device number, if any.
|
InetAddress |
getLocalAddress()
Return the address being used by the virtual CDJ to send its own presence announcement broadcasts.
|
Set<MasterListener> |
getMasterListeners()
Get the set of master listeners that are currently registered.
|
double |
getMasterTempo()
Get the current master tempo.
|
double |
getTempoEpsilon()
Find out how large a tempo change is required before we consider it to be a real difference.
|
DeviceUpdate |
getTempoMaster()
Check which device is the current tempo master, returning the
DeviceUpdate packet in which it
reported itself to be master. |
Set<DeviceUpdateListener> |
getUpdateListeners()
Get the set of device update listeners that are currently registered.
|
boolean |
getUseStandardPlayerNumber()
When self-assigning a player number, should we try to use a value that is legal for a standard CDJ, in
the range 1 to 4? By default, we do not, to avoid any potential conflict with real players.
|
boolean |
isRunning()
Check whether we are presently posing as a virtual CDJ and receiving device status updates.
|
void |
removeMasterListener(MasterListener listener)
Removes the specified master listener so that it no longer receives device updates when
there are changes related to the tempo master.
|
void |
removeUpdateListener(DeviceUpdateListener listener)
Removes the specified device update listener so it no longer receives device updates when they come in.
|
void |
setAnnounceInterval(int interval)
Set the interval, in milliseconds, at which we broadcast presence announcements on the network to pose as
a virtual CDJ.
|
void |
setDeviceName(String name)
Set the name to be used in announcing our presence on the network.
|
void |
setDeviceNumber(byte number)
Set the device number to be used when sending presence announcements on the network to pose as a virtual CDJ.
|
void |
setTempoEpsilon(double epsilon)
Set how large a tempo change is required before we consider it to be a real difference.
|
void |
setUseStandardPlayerNumber(boolean attempt)
When self-assigning a player number, should we try to use a value that is legal for a standard CDJ, in
the range 1 to 4? By default, we do not, to avoid any potential conflict with real players.
|
boolean |
start()
Start announcing ourselves and listening for status packets.
|
void |
stop()
Stop announcing ourselves and listening for status updates.
|
String |
toString() |
addLifecycleListener, deliverLifecycleAnnouncement, ensureRunning, getLifecycleListeners, removeLifecycleListenerpublic static final int UPDATE_PORT
public boolean isRunning()
isRunning in class LifecycleParticipantpublic InetAddress getLocalAddress()
IllegalStateException - if the VirtualCdj is not activepublic InetAddress getBroadcastAddress()
IllegalStateException - if the VirtualCdj is not activepublic void setUseStandardPlayerNumber(boolean attempt)
MetadataFinder, and will always have fewer than four real players
on the network, this can be set to true, and a device number in this range will be chosen if it
is not in use on the network during startup.attempt - true if self-assignment should try to use device numbers below 5 when availablepublic boolean getUseStandardPlayerNumber()
MetadataFinder, and will always have fewer than four real players
on the network, this can be set to true, and a device number in this range will be chosen if it
is not in use on the network during startup.public byte getDeviceNumber()
VirtualCdj
should assign itself an unused device number by watching the network when you call
start(). If getUseStandardPlayerNumber() returns true, self-assignment will try to
find a value in the range 1 to 4. Otherwise (or if those values are all used by other players), it will try to
find a value in the range 5 to 15.public void setDeviceNumber(byte number)
Set the device number to be used when sending presence announcements on the network to pose as a virtual CDJ.
If this is set to zero before start() is called, the VirtualCdj will watch the network to
look for an unused device number, and assign itself that number during startup. If you
explicitly assign a non-zero value, it will use that device number instead. Setting the value to zero while
already up and running reassigns it to an unused value immediately. If getUseStandardPlayerNumber()
returns true, self-assignment will try to find a value in the range 1 to 4. Otherwise (or if those
values are all used by other players), it will try to find a value in the range 5 to 15.
The device number defaults to 0, enabling self-assignment, and will be reset to that each time the
VirtualCdj is stopped.
number - the virtual player numberpublic int getAnnounceInterval()
public void setAnnounceInterval(int interval)
interval - the announcement intervalIllegalArgumentException - if interval is not between 200 and 2000public static String getDeviceName()
public void setDeviceName(String name)
name - the device name to report in our presence announcement packets.public DeviceUpdate getTempoMaster()
DeviceUpdate packet in which it
reported itself to be master. If there is no current tempo master returns null.IllegalStateException - if the VirtualCdj is not activepublic double getTempoEpsilon()
public void setTempoEpsilon(double epsilon)
epsilon - the BPM fraction that will trigger a tempo change updatepublic double getMasterTempo()
IllegalStateException - if the VirtualCdj is not activepublic boolean start()
throws SocketException
DeviceFinder to be active in order to find out how to communicate with other devices, so will start
that if it is not already.VirtualCdj, or it was already running.SocketException - if the socket to listen on port 50002 cannot be createdpublic void stop()
public Set<DeviceUpdate> getLatestStatus()
IllegalStateException - if the VirtualCdj is not activepublic DeviceUpdate getLatestStatusFor(DeviceUpdate device)
Note: If you are trying to determine the current tempo or beat being played by the device, you should
either use the status you just received, or
TimeFinder.getLatestUpdateFor(int) instead, because that
combines both status updates and beat messages, and so is more likely to be current and definitive.
device - the update identifying the device for which current status information is desiredIllegalStateException - if the VirtualCdj is not activepublic DeviceUpdate getLatestStatusFor(DeviceAnnouncement device)
DeviceFinder.getCurrentDevices().
Note: If you are trying to determine the current tempo or beat being played by the device, you should
use TimeFinder.getLatestUpdateFor(int) instead, because that
combines both status updates and beat messages, and so is more likely to be current and definitive.
device - the announcement identifying the device for which current status information is desiredIllegalStateException - if the VirtualCdj is not activepublic DeviceUpdate getLatestStatusFor(int deviceNumber)
Note: If you are trying to determine the current tempo or beat being played by the device, you should
use TimeFinder.getLatestUpdateFor(int) instead, because that
combines both status updates and beat messages, and so is more likely to be current and definitive.
deviceNumber - the device number of interestIllegalStateException - if the VirtualCdj is not activepublic void addMasterListener(MasterListener listener)
Adds the specified master listener to receive device updates when there are changes related
to the tempo master. If listener is null or already present in the set
of registered listeners, no exception is thrown and no action is performed.
To reduce latency, tempo master updates are delivered to listeners directly on the thread that is receiving them
from the network, so if you want to interact with user interface objects in listener methods, you need to use
javax.swing.SwingUtilities.invokeLater(Runnable)
to do so on the Event Dispatch Thread.
Even if you are not interacting with user interface objects, any code in the listener method must finish quickly, or it will add latency for other listeners, and master updates will back up. If you want to perform lengthy processing of any sort, do so on another thread.
listener - the master listener to addpublic void removeMasterListener(MasterListener listener)
listener is null or not present
in the set of registered listeners, no exception is thrown and no action is performed.listener - the master listener to removepublic Set<MasterListener> getMasterListeners()
public void addUpdateListener(DeviceUpdateListener listener)
Adds the specified device update listener to receive device updates whenever they come in.
If listener is null or already present in the list
of registered listeners, no exception is thrown and no action is performed.
To reduce latency, device updates are delivered to listeners directly on the thread that is receiving them
from the network, so if you want to interact with user interface objects in listener methods, you need to use
javax.swing.SwingUtilities.invokeLater(Runnable)
to do so on the Event Dispatch Thread.
Even if you are not interacting with user interface objects, any code in the listener method must finish quickly, or it will add latency for other listeners, and device updates will back up. If you want to perform lengthy processing of any sort, do so on another thread.
listener - the device update listener to addpublic void removeUpdateListener(DeviceUpdateListener listener)
listener is null or not present
in the list of registered listeners, no exception is thrown and no action is performed.listener - the device update listener to removepublic Set<DeviceUpdateListener> getUpdateListeners()
public static VirtualCdj getInstance()
Copyright © 2016–2018 Deep Symmetry, LLC. All rights reserved.