diff --git a/src/main/java/org/deepsymmetry/beatlink/CdjStatus.java b/src/main/java/org/deepsymmetry/beatlink/CdjStatus.java
index 31eb8db..87dcade 100644
--- a/src/main/java/org/deepsymmetry/beatlink/CdjStatus.java
+++ b/src/main/java/org/deepsymmetry/beatlink/CdjStatus.java
@@ -28,7 +28,7 @@ public class CdjStatus extends DeviceUpdate {
/**
* 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
+ * master role to another device, labeled Mh in the
* Packet Analysis document.
*
*
Normally it holds the value 0xff, but during a tempo master hand-off, it holds
@@ -570,8 +570,8 @@ private PlayState3 findPlayState3() {
}
/**
- * Contains the sizes we expect CDJ status packets to have so we can log a warning if we get an unusual
- * one. We will then add the new size to the list so it only gets logged once per run.
+ * Contains the sizes we expect CDJ status packets to have, so we can log a warning if we get an unusual
+ * one. We will then add the new size to the list, so it only gets logged once per run.
*/
private static final Set expectedStatusPacketSizes = Collections.newSetFromMap(new ConcurrentHashMap<>());
static {
@@ -610,8 +610,7 @@ public CdjStatus(DatagramPacket packet) {
if (packetBytes.length != reportedPacketSize) {
final String reportedKey = reportedPacketSize + "," + packetBytes.length;
if (misreportedPacketSizes.add(reportedKey)) {
- logger.warn("Received CDJ status packet with reported payload length of " + payloadLength + " and actual payload length of " +
- (packetBytes.length - 0x24));
+ logger.warn("Received CDJ status packet with reported payload length of {} and actual payload length of {}", payloadLength, packetBytes.length - 0x24);
}
}
@@ -630,7 +629,7 @@ public CdjStatus(DatagramPacket packet) {
handingMasterToDevice = Util.unsign(packetBytes[MASTER_HAND_OFF]);
final byte trackSourceByte = packetBytes[40];
- if (Util.isOpusQuad(deviceName) && (trackSourceByte < 16)) {
+ if (isFromOpusQuad() && (trackSourceByte < 16)) {
int sourcePlayer = Util.translateOpusPlayerNumbers(trackSourceByte);
if (sourcePlayer != 0) {
final SlotReference matchedSourceSlot = VirtualRekordbox.getInstance().findMatchedTrackSourceSlotForPlayer(deviceNumber);
@@ -707,7 +706,7 @@ public int getBpm() {
/**
* 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
+ * represents the downbeat). 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
@@ -766,7 +765,7 @@ public double getEffectiveTempo() {
public boolean isPlaying() {
if (packetBytes.length >= 212) {
final boolean simpleResult = (packetBytes[STATUS_FLAGS] & PLAYING_FLAG) > 0;
- if (!simpleResult && Util.isOpusQuad(deviceName)) {
+ if (!simpleResult && isFromOpusQuad()) {
// Sometimes the Opus Quad lies and reports that it is not playing in this flag, even though it actually is.
// Try to recover from that.
return playState1 == PlayState1.PLAYING || playState1 == PlayState1.LOOPING ||
@@ -897,7 +896,7 @@ public boolean isDiscSlotAsleep() {
* 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 {@link #isDiscSlotAsleep()}.
+ * from that disc, this seems to return 1 (you can check for that condition by calling {@link #isDiscSlotAsleep()}).
*
* @return 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
*/
diff --git a/src/main/java/org/deepsymmetry/beatlink/DeviceAnnouncement.java b/src/main/java/org/deepsymmetry/beatlink/DeviceAnnouncement.java
index 1420080..73d6296 100644
--- a/src/main/java/org/deepsymmetry/beatlink/DeviceAnnouncement.java
+++ b/src/main/java/org/deepsymmetry/beatlink/DeviceAnnouncement.java
@@ -1,5 +1,7 @@
package org.deepsymmetry.beatlink;
+import org.deepsymmetry.beatlink.data.OpusProvider;
+
import java.net.DatagramPacket;
import java.net.InetAddress;
@@ -50,7 +52,7 @@ public DeviceAnnouncement(DatagramPacket packet) {
packetBytes = new byte[packet.getLength()];
System.arraycopy(packet.getData(), 0, packetBytes, 0, packet.getLength());
timestamp = System.currentTimeMillis();
- name = new String(packetBytes, 12, 20).trim();
+ name = new String(packetBytes, 12, 20).trim().intern();
number = Util.unsign(packetBytes[36]);
}
@@ -69,7 +71,7 @@ public DeviceAnnouncement(DatagramPacket packet, int deviceNumber) {
packetBytes = new byte[packet.getLength()];
System.arraycopy(packet.getData(), 0, packetBytes, 0, packet.getLength());
timestamp = System.currentTimeMillis();
- name = new String(packetBytes, 12, 20).trim();
+ name = new String(packetBytes, 12, 20).trim().intern();
number = deviceNumber;
}
@@ -153,6 +155,18 @@ public byte[] getPacketBytes() {
return result;
}
+ /**
+ * Check whether a device update came from an Opus Quad, which behaves very differently from true Pro DJ Link hardware.
+ *
+ * @return {@code true} when the device name reported in this update matches the one reported by the Opus Quad
+ */
+ public boolean isOpusQuad() {
+ //noinspection StringEquality
+ return name == OpusProvider.opusName; // Since strings are interned, can be compared this way.
+ }
+
+
+
@Override
public String toString() {
return "DeviceAnnouncement[device:" + number + ", name:" + name + ", address:" + address.getHostAddress() + "]";
diff --git a/src/main/java/org/deepsymmetry/beatlink/DeviceFinder.java b/src/main/java/org/deepsymmetry/beatlink/DeviceFinder.java
index 528f817..1d4d154 100644
--- a/src/main/java/org/deepsymmetry/beatlink/DeviceFinder.java
+++ b/src/main/java/org/deepsymmetry/beatlink/DeviceFinder.java
@@ -4,7 +4,6 @@
import java.net.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
@@ -38,7 +37,7 @@ public class DeviceFinder extends LifecycleParticipant {
/**
* The socket used to listen for announcement packets while we are active.
*/
- private final AtomicReference socket = new AtomicReference(null);
+ private final AtomicReference socket = new AtomicReference<>(null);
/**
* Track when we started listening for announcement packets.
@@ -92,15 +91,15 @@ public long getFirstDeviceTime() {
/**
* Keep track of the announcements we have seen.
*/
- private final Map devices = new ConcurrentHashMap();
+ private final Map devices = new ConcurrentHashMap<>();
/**
* Remove any device announcements that are so old that the device seems to have gone away.
*/
private void expireDevices() {
long now = System.currentTimeMillis();
- // Make a copy so we don't have to worry about concurrent modification.
- Map copy = new HashMap(devices);
+ // Make a copy, so we don't have to worry about concurrent modification.
+ Map copy = new HashMap<>(devices);
for (Map.Entry entry : copy.entrySet()) {
if (now - entry.getValue().getTimestamp() > MAXIMUM_AGE) {
devices.remove(entry.getKey());
@@ -138,7 +137,7 @@ private boolean isDeviceNew(DeviceAnnouncement announcement) {
* its socket to this set when it is active so that it does not show up in the set of devices found on the network.
*/
private final Set ignoredAddresses =
- Collections.newSetFromMap(new ConcurrentHashMap());
+ Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
* Start ignoring any device updates which are received from the specified address. Intended for use by the
@@ -161,8 +160,8 @@ public void removeIgnoredAddress(InetAddress address) {
}
/**
- * Check whether an address is being ignored. (The {@link BeatFinder} will call this so it can filter out the
- * {@link VirtualCdj}'s beat messages when it is broadcasting them, for example.
+ * Check whether an address is being ignored. (The {@link BeatFinder} will call this, so it can filter out the
+ * {@link VirtualCdj}'s beat messages when it is broadcasting them, for example).
*
* @param address the address to be checked as a candidate to be ignored
*
@@ -222,71 +221,63 @@ public synchronized void start() throws SocketException {
final byte[] buffer = new byte[512];
final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
- Thread receiver = new Thread(null, new Runnable() {
- @Override
- public void run() {
- boolean received;
- while (isRunning()) {
- try {
- if (getCurrentDevices().isEmpty()) {
- socket.get().setSoTimeout(60000); // We have no devices to check for timeout; block for a whole minute to check for shutdown
- } else {
- socket.get().setSoTimeout(1000); // Check every second to see if a device has vanished
- }
- socket.get().receive(packet);
- received = !ignoredAddresses.contains(packet.getAddress());
- } catch (SocketTimeoutException ste) {
- received = false;
- } catch (IOException e) {
- // Don't log a warning if the exception was due to the socket closing at shutdown.
- if (isRunning()) {
- // We did not expect to have a problem; log a warning and shut down.
- logger.warn("Problem reading from DeviceAnnouncement socket, stopping", e);
- stop();
- }
- received = false;
+ Thread receiver = new Thread(null, () -> {
+ boolean received;
+ while (isRunning()) {
+ try {
+ if (getCurrentDevices().isEmpty()) {
+ socket.get().setSoTimeout(60000); // We have no devices to check for timeout; block for a whole minute to check for shutdown
+ } else {
+ socket.get().setSoTimeout(1000); // Check every second to see if a device has vanished
}
- try {
- if (received) {
- final Util.PacketType kind = Util.validateHeader(packet, ANNOUNCEMENT_PORT);
- if (kind == Util.PacketType.DEVICE_KEEP_ALIVE) {
- // Looks like the kind of packet we need
- if (packet.getLength() < 54) {
- logger.warn("Ignoring too-short " + kind.name + " packet; expected 54 bytes, but only got " +
- packet.getLength() + ".");
- } else {
- if (packet.getLength() > 54) {
- logger.warn("Processing too-long " + kind.name + " packet; expected 54 bytes, but got " +
- packet.getLength() + ".");
- }
-
- DeviceAnnouncement announcement = new DeviceAnnouncement(packet);
-
- if (Util.isOpusQuad(announcement.getDeviceName())) {
-
- createAndProcessOpusAnnouncements(packet);
- } else {
+ socket.get().receive(packet);
+ received = !ignoredAddresses.contains(packet.getAddress());
+ } catch (SocketTimeoutException ste) {
+ received = false;
+ } catch (IOException e) {
+ // Don't log a warning if the exception was due to the socket closing at shutdown.
+ if (isRunning()) {
+ // We did not expect to have a problem; log a warning and shut down.
+ logger.warn("Problem reading from DeviceAnnouncement socket, stopping", e);
+ stop();
+ }
+ received = false;
+ }
+ try {
+ if (received) {
+ final Util.PacketType kind = Util.validateHeader(packet, ANNOUNCEMENT_PORT);
+ if (kind == Util.PacketType.DEVICE_KEEP_ALIVE) {
+ // Looks like the kind of packet we need
+ if (packet.getLength() < 54) {
+ logger.warn("Ignoring too-short {} packet; expected 54 bytes, but only got {}.", kind.name, packet.getLength());
+ } else {
+ if (packet.getLength() > 54) {
+ logger.warn("Processing too-long {} packet; expected 54 bytes, but got {}.", kind.name, packet.getLength());
+ }
- processAnnouncement(announcement);
+ DeviceAnnouncement announcement = new DeviceAnnouncement(packet);
+ if (announcement.isOpusQuad()) {
+ createAndProcessOpusAnnouncements(packet);
+ } else {
+ processAnnouncement(announcement);
- if (VirtualCdj.getInstance().isRunning() &&
- announcement.getDeviceNumber() == VirtualCdj.getInstance().getDeviceNumber()) {
- // Someone is using the same device number as we are! Try to defend it.
- VirtualCdj.getInstance().defendDeviceNumber(announcement.getAddress());
- }
+ if (VirtualCdj.getInstance().isRunning() &&
+ announcement.getDeviceNumber() == VirtualCdj.getInstance().getDeviceNumber()) {
+ // Someone is using the same device number as we are! Try to defend it.
+ VirtualCdj.getInstance().defendDeviceNumber(announcement.getAddress());
}
}
- } else if (kind == Util.PacketType.DEVICE_HELLO) {
- logger.debug("Received device hello packet.");
- } else if (kind != null) {
- VirtualCdj.getInstance().handleSpecialAnnouncementPacket(kind, packet);
}
+ } else if (kind == Util.PacketType.DEVICE_HELLO) {
+ logger.debug("Received device hello packet.");
+ } else if (kind != null) {
+ VirtualCdj.getInstance().handleSpecialAnnouncementPacket(kind, packet);
}
- expireDevices();
- } catch (Throwable t) {
- logger.warn("Problem processing DeviceAnnouncement packet", t);
}
+ expireDevices();
+ } catch (Throwable t) {
+ logger.warn("Problem processing DeviceAnnouncement packet", t);
}
}
}, "beat-link DeviceFinder receiver");
@@ -301,17 +292,14 @@ public void run() {
* reachable.
*/
synchronized void flush() {
- final Set lastDevices = new HashSet(devices.values());
+ final Set lastDevices = new HashSet<>(devices.values());
devices.clear();
firstDeviceTime.set(0);
// Report the loss of all our devices, on the proper thread, also outside our lock.
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- for (DeviceAnnouncement announcement : lastDevices) {
- deliverLostAnnouncement(announcement);
- }
+ SwingUtilities.invokeLater(() -> {
+ for (DeviceAnnouncement announcement : lastDevices) {
+ deliverLostAnnouncement(announcement);
}
});
}
@@ -345,7 +333,7 @@ public Set getCurrentDevices() {
}
expireDevices(); // Get rid of anything past its sell-by date.
// Make a copy so callers get an immutable snapshot of the current state.
- return Collections.unmodifiableSet(new HashSet(devices.values()));
+ return Collections.unmodifiableSet(new HashSet<>(devices.values()));
}
/**
@@ -372,7 +360,7 @@ public DeviceAnnouncement getLatestAnnouncementFrom(int deviceNumber) {
* Keeps track of the registered device announcement listeners.
*/
private final Set deviceListeners =
- Collections.newSetFromMap(new ConcurrentHashMap());
+ Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
* Adds the specified device announcement listener to receive device announcements when DJ Link devices
* are found on or leave the network. If {@code listener} is {@code null} or already present in the list
@@ -412,7 +400,7 @@ public void removeDeviceAnnouncementListener(DeviceAnnouncementListener listener
@SuppressWarnings("WeakerAccess")
public Set getDeviceAnnouncementListeners() {
// Make a copy so callers get an immutable snapshot of the current state.
- return Collections.unmodifiableSet(new HashSet(deviceListeners));
+ return Collections.unmodifiableSet(new HashSet<>(deviceListeners));
}
/**
@@ -422,14 +410,11 @@ public Set getDeviceAnnouncementListeners() {
*/
private void deliverFoundAnnouncement(final DeviceAnnouncement announcement) {
for (final DeviceAnnouncementListener listener : getDeviceAnnouncementListeners()) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- try {
- listener.deviceFound(announcement);
- } catch (Throwable t) {
- logger.warn("Problem delivering device found announcement to listener", t);
- }
+ SwingUtilities.invokeLater(() -> {
+ try {
+ listener.deviceFound(announcement);
+ } catch (Throwable t) {
+ logger.warn("Problem delivering device found announcement to listener", t);
}
});
}
@@ -442,14 +427,11 @@ public void run() {
*/
private void deliverLostAnnouncement(final DeviceAnnouncement announcement) {
for (final DeviceAnnouncementListener listener : getDeviceAnnouncementListeners()) {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- try {
- listener.deviceLost(announcement);
- } catch (Throwable t) {
- logger.warn("Problem delivering device lost announcement to listener", t);
- }
+ SwingUtilities.invokeLater(() -> {
+ try {
+ listener.deviceLost(announcement);
+ } catch (Throwable t) {
+ logger.warn("Problem delivering device lost announcement to listener", t);
}
});
}
diff --git a/src/main/java/org/deepsymmetry/beatlink/DeviceUpdate.java b/src/main/java/org/deepsymmetry/beatlink/DeviceUpdate.java
index a925ec5..deb6d98 100644
--- a/src/main/java/org/deepsymmetry/beatlink/DeviceUpdate.java
+++ b/src/main/java/org/deepsymmetry/beatlink/DeviceUpdate.java
@@ -1,5 +1,7 @@
package org.deepsymmetry.beatlink;
+import org.deepsymmetry.beatlink.data.OpusProvider;
+
import java.net.DatagramPacket;
import java.net.InetAddress;
@@ -57,10 +59,10 @@ public DeviceUpdate(DatagramPacket packet, String name, int length) {
address = packet.getAddress();
packetBytes = new byte[packet.getLength()];
System.arraycopy(packet.getData(), 0, packetBytes, 0, packet.getLength());
- deviceName = new String(packetBytes, 11, 20).trim();
+ deviceName = new String(packetBytes, 11, 20).trim().intern();
preNexusCdj = deviceName.startsWith("CDJ") && (deviceName.endsWith("900") || deviceName.endsWith("2000"));
- if (Util.isOpusQuad(deviceName)){
+ if (isFromOpusQuad()) {
deviceNumber = Util.translateOpusPlayerNumbers(packetBytes[40]);
} else {
deviceNumber = Util.unsign(packetBytes[33]);
@@ -98,7 +100,7 @@ public String getDeviceName() {
* Check whether this packet seems to have come from a CDJ older
* than the original Nexus series (which means, for example, that
* beat numbers will not be available, so the {@link org.deepsymmetry.beatlink.data.TimeFinder}
- * can't work with it.
+ * can't work with it).
*
* @return {@code true} if the device name starts with "CDJ" and ends with "0".
*/
@@ -115,6 +117,16 @@ public int getDeviceNumber() {
return deviceNumber;
}
+ /**
+ * Check whether a device update came from an Opus Quad, which behaves very differently from true Pro DJ Link hardware.
+ *
+ * @return {@code true} when the device name reported in this update matches the one reported by the Opus Quad
+ */
+ public boolean isFromOpusQuad() {
+ //noinspection StringEquality
+ return deviceName == OpusProvider.opusName; // Since strings are interned, can be compared this way.
+ }
+
/**
* Get the raw data bytes of the device update packet.
*
@@ -183,9 +195,9 @@ public byte[] getPacketBytes() {
/**
* 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 down beat). This value will be accurate for players when the track was properly configured within rekordbox
+ * 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
- * down beats with players, however, so this value is meaningless when coming from the mixer. The usefulness of
+ * downbeats with players, however, so this value is meaningless when coming from the mixer. The usefulness of
* this value can be checked with {@link #isBeatWithinBarMeaningful()}.
*
* @return the beat number within the current measure of music
diff --git a/src/main/java/org/deepsymmetry/beatlink/Util.java b/src/main/java/org/deepsymmetry/beatlink/Util.java
index 35d3b9b..f5661c4 100644
--- a/src/main/java/org/deepsymmetry/beatlink/Util.java
+++ b/src/main/java/org/deepsymmetry/beatlink/Util.java
@@ -9,7 +9,6 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.IntStream;
-import org.deepsymmetry.beatlink.data.OpusProvider;
import org.deepsymmetry.cratedigger.pdb.RekordboxAnlz;
import org.deepsymmetry.cratedigger.pdb.RekordboxAnlz.SongStructureEntry;
import org.slf4j.Logger;
@@ -140,7 +139,7 @@ public enum PacketType {
/**
* Metadata that includes track album art, possibly waveforms and more. We do not use this information at the moment
- * because it is not complete enough to support all of the Beat Link Trigger functionality. Instead, we download
+ * because it is not complete enough to support all the Beat Link Trigger functionality. Instead, we download
* the track data from a Rekordbox USB.
*/
OPUS_METADATA(0x56, "OPUS Metadata", VirtualCdj.UPDATE_PORT),
@@ -289,8 +288,7 @@ public static PacketType validateHeader(DatagramPacket packet, int port) {
byte[] data = packet.getData();
if (data.length < PACKET_TYPE_OFFSET) {
- logger.warn("Packet is too short to be a Pro DJ Link packet; must be at least " + PACKET_TYPE_OFFSET +
- " bytes long, was only " + data.length + ".");
+ logger.warn("Packet is too short to be a Pro DJ Link packet; must be at least " + PACKET_TYPE_OFFSET + " bytes long, was only {}.", data.length);
return null;
}
@@ -302,8 +300,7 @@ public static PacketType validateHeader(DatagramPacket packet, int port) {
final Map portMap = PACKET_TYPE_MAP.get(port);
if (portMap == null) { // Warn about unrecognized port, once, and return null for packet type.
if (!unknownPortsReported.contains(port)) {
- logger.warn("Do not know any Pro DJ Link packets that are received on port " + port +
- " (this will be reported only once).");
+ logger.warn("Do not know any Pro DJ Link packets that are received on port {} (this will be reported only once).", port);
unknownPortsReported.add(port);
}
return null;
@@ -314,8 +311,7 @@ public static PacketType validateHeader(DatagramPacket packet, int port) {
Set typesReportedForPort = unknownPortTypesReported.computeIfAbsent(port, k -> Collections.newSetFromMap(new ConcurrentHashMap<>()));
// First problem we have seen for this port, set up set for it.
if (!typesReportedForPort.contains(data[PACKET_TYPE_OFFSET])) {
- logger.warn("Do not know any Pro DJ Link packets received on port " + port + " with type " +
- String.format("0x%02x", data[PACKET_TYPE_OFFSET]) + " (this will be reported only once).");
+ logger.warn("Do not know any Pro DJ Link packets received on port {} with type {} (this will be reported only once).", port, String.format("0x%02x", data[PACKET_TYPE_OFFSET]));
typesReportedForPort.add(data[PACKET_TYPE_OFFSET]);
}
}
@@ -434,7 +430,7 @@ public static long addressToLong(InetAddress address) {
*/
public static boolean sameNetwork(int prefixLength, InetAddress address1, InetAddress address2) {
if (logger.isDebugEnabled()) {
- logger.debug("Comparing address " + address1.getHostAddress() + " with " + address2.getHostAddress() + ", prefixLength=" + prefixLength);
+ logger.debug("Comparing address {} with {}, prefixLength={}", address1.getHostAddress(), address2.getHostAddress(), prefixLength);
}
long prefixMask = 0xffffffffL & (-1L << (32 - prefixLength));
return (addressToLong(address1) & prefixMask) == (addressToLong(address2) & prefixMask);
@@ -1004,10 +1000,6 @@ public static String highResolutionPath(String artPath) {
return artPath.replaceFirst("(\\.\\w+$)", "_m$1");
}
- public static boolean isOpusQuad(String deviceName){
- return deviceName.equals(OpusProvider.opusName);
- }
-
/**
* Adjust the player numbers from the Opus-Quad so that they are 1-4 as expected by users and the rest of the
* ecosystem.
diff --git a/src/main/java/org/deepsymmetry/beatlink/VirtualCdj.java b/src/main/java/org/deepsymmetry/beatlink/VirtualCdj.java
index b779950..34bbea8 100644
--- a/src/main/java/org/deepsymmetry/beatlink/VirtualCdj.java
+++ b/src/main/java/org/deepsymmetry/beatlink/VirtualCdj.java
@@ -42,10 +42,10 @@ public class VirtualCdj extends LifecycleParticipant {
/**
* The socket used to receive device status packets while we are active.
*/
- private final AtomicReference socket = new AtomicReference();
+ private final AtomicReference socket = new AtomicReference<>();
/**
- * Indicates we started {@link VirtualRekordbox} running so we are just acting as a proxy for it, to
+ * Indicates we started {@link VirtualRekordbox} running, so we are just acting as a proxy for it, to
* work with the Opus Quad.
*/
private final AtomicBoolean proxyingForVirtualRekordbox = new AtomicBoolean(false);
@@ -86,7 +86,7 @@ public InetAddress getLocalAddress() {
* up by finding the network interface address on which we are receiving the other devices'
* announcement broadcasts.
*/
- private final AtomicReference broadcastAddress = new AtomicReference();
+ private final AtomicReference broadcastAddress = new AtomicReference<>();
/**
* Return the broadcast address used to reach the DJ Link network.
@@ -102,7 +102,7 @@ public InetAddress getBroadcastAddress() {
/**
* Keep track of the most recent updates we have seen, indexed by the address they came from.
*/
- private final Map updates = new ConcurrentHashMap();
+ private final Map updates = new ConcurrentHashMap<>();
/**
* Should we try to use a device number in the range 1 to 4 if we find one is available?
@@ -142,7 +142,7 @@ public boolean getUseStandardPlayerNumber() {
* This starts out being zero unless you explicitly assign another value, which means that the VirtualCdj
* should assign itself an unused device number by watching the network when you call
* {@link #start()}. If {@link #getUseStandardPlayerNumber()} returns {@code true}, self-assignment will try to
- * find a value in the range 1 to 4. Otherwise it will try to find a value in the range 7 to 15 (so that it does
+ * find a value in the range 1 to 4. Otherwise, it will try to find a value in the range 7 to 15 (so that it does
* not even conflict with newer CDJ-3000 networks, which can use channels 5 and 6). Even when told
* to use a standard player number, if all device numbers in that range are already in use, we will be forced to
* use a larger number.
@@ -261,12 +261,7 @@ public synchronized void setDeviceName(String name) {
/**
* Reacts to player status updates to reflect the current playback state.
*/
- private final DeviceUpdateListener updateListener = new DeviceUpdateListener() {
- @Override
- public void received(DeviceUpdate update) {
- processUpdate(update);
- }
- };
+ private final DeviceUpdateListener updateListener = this::processUpdate;
public DeviceUpdateListener getUpdateListener() {
return updateListener;
@@ -331,7 +326,7 @@ public DeviceUpdateListener getUpdateListener() {
/**
* Keep track of which device has reported itself as the current tempo master.
*/
- private final AtomicReference tempoMaster = new AtomicReference();
+ private final AtomicReference tempoMaster = new AtomicReference<>();
/**
* Check which device is the current tempo master, returning the {@link DeviceUpdate} packet in which it
@@ -437,7 +432,7 @@ private DeviceUpdate buildUpdate(DatagramPacket packet) {
switch (kind) {
case MIXER_STATUS:
if (length != 56) {
- logger.warn("Processing a Mixer Status packet with unexpected length " + length + ", expected 56 bytes.");
+ logger.warn("Processing a Mixer Status packet with unexpected length {}, expected 56 bytes.", length);
}
if (length >= 56) {
return new MixerStatus(packet);
@@ -451,13 +446,12 @@ private DeviceUpdate buildUpdate(DatagramPacket packet) {
return new CdjStatus(packet);
} else {
- logger.warn("Ignoring too-short CDJ Status packet with length " + length + " (we need " + CdjStatus.MINIMUM_PACKET_SIZE +
- " bytes).");
+ logger.warn("Ignoring too-short CDJ Status packet with length {} (we need " + CdjStatus.MINIMUM_PACKET_SIZE + " bytes).", length);
return null;
}
case LOAD_TRACK_ACK:
- logger.info("Received track load acknowledgment from player " + packet.getData()[0x21]);
+ logger.info("Received track load acknowledgment from player {}", packet.getData()[0x21]);
return null;
case MEDIA_QUERY:
@@ -469,7 +463,7 @@ private DeviceUpdate buildUpdate(DatagramPacket packet) {
return null;
default:
- logger.warn("Ignoring " + kind.name + " packet sent to update port.");
+ logger.warn("Ignoring {} packet sent to update port.", kind.name);
return null;
}
}
@@ -507,11 +501,9 @@ void processUpdate(DeviceUpdate update) {
syncCounter.set(largestSyncCounter.get() + 1);
} else {
if (nextMaster.get() == 0xff) {
- logger.warn("Saw master asserted by player " + update.deviceNumber +
- " when we were not yielding it.");
+ logger.warn("Saw master asserted by player {} when we were not yielding it.", update.deviceNumber);
} else {
- logger.warn("Expected to yield master role to player " + nextMaster.get() +
- " but saw master asserted by player " + update.deviceNumber);
+ logger.warn("Expected to yield master role to player {} but saw master asserted by player {}", nextMaster.get(), update.deviceNumber);
}
}
}
@@ -530,8 +522,7 @@ void processUpdate(DeviceUpdate update) {
if (masterYieldedFrom.get() == 0) {
logger.info("Accepting unsolicited Master yield; we must be the only synced device playing.");
} else {
- logger.warn("Expected player " + masterYieldedFrom.get() + " to yield master to us, but player " +
- update.deviceNumber + " did.");
+ logger.warn("Expected player {} to yield master to us, but player {} did.", masterYieldedFrom.get(), update.deviceNumber);
}
}
master.set(true);
@@ -597,14 +588,14 @@ private boolean selfAssignDeviceNumber() {
if (claimingNumber.get() == 0) {
// We have not yet tried a number. If we are not supposed to use standard player numbers, make sure
- // the first one we try is 7 (to accommodate the CDJ-3000, which can use channels 5 and 6.
+ // the first one we try is 7 (to accommodate the CDJ-3000, which can use channels 5 and 6).
if (!getUseStandardPlayerNumber()) {
claimingNumber.set(6);
}
}
// Record what numbers we have already seen, since there is no point trying one of them.
- Set numbersUsed = new HashSet();
+ Set numbersUsed = new HashSet<>();
for (DeviceAnnouncement device : DeviceFinder.getInstance().getCurrentDevices()) {
numbersUsed.add(device.getDeviceNumber());
}
@@ -615,13 +606,12 @@ private boolean selfAssignDeviceNumber() {
if (!numbersUsed.contains(result)) { // We found one that is not used, so we can use it
claimingNumber.set(result);
if (getUseStandardPlayerNumber() && (result > 4)) {
- logger.warn("Unable to self-assign a standard player number, all are in use. Trying number " +
- result + ".");
+ logger.warn("Unable to self-assign a standard player number, all are in use. Trying number {}.", result);
}
return true;
}
}
- logger.warn("Found no unused device numbers between " + startingNumber + " and 15, giving up.");
+ logger.warn("Found no unused device numbers between {} and 15, giving up.", startingNumber);
return false;
}
@@ -656,7 +646,7 @@ public List getMatchingInterfaces() {
/**
* If we are in the process of trying to establish a device number, this will hold the number we are
- * currently trying to claim. Otherwise it will hold the value 0.
+ * currently trying to claim. Otherwise, it will hold the value 0.
*/
private final AtomicInteger claimingNumber = new AtomicInteger(0);
@@ -696,8 +686,7 @@ private void requestNumberFromMixer(InetAddress mixerAddress) {
try {
DatagramPacket announcement = new DatagramPacket(assignmentRequestBytes, assignmentRequestBytes.length,
mixerAddress, DeviceFinder.ANNOUNCEMENT_PORT);
- logger.debug("Sending device number request to mixer at address " + announcement.getAddress().getHostAddress() +
- ", port " + announcement.getPort());
+ logger.debug("Sending device number request to mixer at address {}, port {}", announcement.getAddress().getHostAddress(), announcement.getPort());
currentSocket.send(announcement);
} catch (Exception e) {
logger.warn("Unable to send device number request to mixer.", e);
@@ -725,8 +714,7 @@ void defendDeviceNumber(InetAddress invaderAddress) {
try {
DatagramPacket defense = new DatagramPacket(deviceNumberDefenseBytes, deviceNumberDefenseBytes.length,
invaderAddress, DeviceFinder.ANNOUNCEMENT_PORT);
- logger.info("Sending device number defense packet to invader at address " + defense.getAddress().getHostAddress() +
- ", port " + defense.getPort());
+ logger.info("Sending device number defense packet to invader at address {}, port {}", defense.getAddress().getHostAddress(), defense.getPort());
currentSocket.send(defense);
} catch (Exception e) {
logger.error("Unable to send device defense packet.", e);
@@ -749,7 +737,7 @@ private boolean claimDeviceNumber() {
System.arraycopy(getDeviceName().getBytes(), 0, helloBytes, DEVICE_NAME_OFFSET, getDeviceName().getBytes().length);
for (int i = 1; i <= 3; i++) {
try {
- logger.debug("Sending hello packet " + i);
+ logger.debug("Sending hello packet {}", i);
DatagramPacket announcement = new DatagramPacket(helloBytes, helloBytes.length,
broadcastAddress.get(), DeviceFinder.ANNOUNCEMENT_PORT);
socket.get().send(announcement);
@@ -781,7 +769,7 @@ private boolean claimDeviceNumber() {
for (int i = 1; i <= 3 && mixerAssigned.get() == 0; i++) {
claimStage1bytes[0x24] = (byte)i; // The packet counter.
try {
- logger.debug("Sending claim stage 1 packet " + i);
+ logger.debug("Sending claim stage 1 packet {}", i);
DatagramPacket announcement = new DatagramPacket(claimStage1bytes, claimStage1bytes.length,
broadcastAddress.get(), DeviceFinder.ANNOUNCEMENT_PORT);
socket.get().send(announcement);
@@ -796,7 +784,7 @@ private boolean claimDeviceNumber() {
if (getDeviceNumber() == 0) { // We are trying to pick a number.
continue selfAssignLoop; // Try the next available number, if any.
}
- logger.warn("Unable to use device number " + getDeviceNumber() + ", another device has it. Failing to go online.");
+ logger.warn("Unable to use device number {}, another device has it. Failing to go online.", getDeviceNumber());
claimingNumber.set(0);
return false;
}
@@ -813,7 +801,7 @@ private boolean claimDeviceNumber() {
for (int i = 1; i <= 3 && mixerAssigned.get() == 0; i++) {
claimStage2bytes[0x2f] = (byte)i; // The packet counter.
try {
- logger.debug("Sending claim stage 2 packet " + i + " for device " + claimStage2bytes[0x2e]);
+ logger.debug("Sending claim stage 2 packet {} for device {}", i, claimStage2bytes[0x2e]);
DatagramPacket announcement = new DatagramPacket(claimStage2bytes, claimStage2bytes.length,
broadcastAddress.get(), DeviceFinder.ANNOUNCEMENT_PORT);
socket.get().send(announcement);
@@ -828,7 +816,7 @@ private boolean claimDeviceNumber() {
if (getDeviceNumber() == 0) { // We are trying to pick a number.
continue selfAssignLoop; // Try the next available number, if any.
}
- logger.warn("Unable to use device number " + getDeviceNumber() + ", another device has it. Failing to go online.");
+ logger.warn("Unable to use device number {}, another device has it. Failing to go online.", getDeviceNumber());
claimingNumber.set(0);
return false;
}
@@ -848,7 +836,7 @@ private boolean claimDeviceNumber() {
for (int i = 1; i <= 3 && mixerAssigned.get() == 0; i++) {
claimStage3bytes[0x25] = (byte)i; // The packet counter.
try {
- logger.debug("Sending claim stage 3 packet " + i + " for device " + claimStage3bytes[0x24]);
+ logger.debug("Sending claim stage 3 packet {} for device {}", i, claimStage3bytes[0x24]);
DatagramPacket announcement = new DatagramPacket(claimStage3bytes, claimStage3bytes.length,
broadcastAddress.get(), DeviceFinder.ANNOUNCEMENT_PORT);
socket.get().send(announcement);
@@ -863,7 +851,7 @@ private boolean claimDeviceNumber() {
if (getDeviceNumber() == 0) { // We are trying to pick a number.
continue selfAssignLoop; // Try the next available number, if any.
}
- logger.warn("Unable to use device number " + getDeviceNumber() + ", another device has it. Failing to go online.");
+ logger.warn("Unable to use device number {}, another device has it. Failing to go online.", getDeviceNumber());
claimingNumber.set(0);
return false;
}
@@ -886,7 +874,7 @@ private boolean claimDeviceNumber() {
*/
private boolean createVirtualCdj() throws SocketException {
// Find the network interface and address to use to communicate with the first device we found.
- matchingInterfaces = new ArrayList();
+ matchingInterfaces = new ArrayList<>();
matchedAddress = null;
DeviceAnnouncement aDevice = DeviceFinder.getInstance().getCurrentDevices().iterator().next();
for (NetworkInterface networkInterface : Collections.list(NetworkInterface.getNetworkInterfaces())) {
@@ -900,18 +888,15 @@ private boolean createVirtualCdj() throws SocketException {
}
if (matchedAddress == null) {
- logger.warn("Unable to find network interface to communicate with " + aDevice +
- ", giving up.");
+ logger.warn("Unable to find network interface to communicate with {}, giving up.", aDevice);
return false;
}
- logger.info("Found matching network interface " + matchingInterfaces.get(0).getDisplayName() + " (" +
- matchingInterfaces.get(0).getName() + "), will use address " + matchedAddress);
+ logger.info("Found matching network interface {} ({}), will use address {}", matchingInterfaces.get(0).getDisplayName(), matchingInterfaces.get(0).getName(), matchedAddress);
if (matchingInterfaces.size() > 1) {
for (ListIterator it = matchingInterfaces.listIterator(1); it.hasNext(); ) {
NetworkInterface extra = it.next();
- logger.warn("Network interface " + extra.getDisplayName() + " (" + extra.getName() +
- ") sees same network: we will likely get duplicate DJ Link packets, causing severe problems.");
+ logger.warn("Network interface {} ({}) sees same network: we will likely get duplicate DJ Link packets, causing severe problems.", extra.getDisplayName(), extra.getName());
}
}
@@ -941,12 +926,9 @@ private boolean createVirtualCdj() throws SocketException {
receiver.start();
// Create the thread which announces our participation in the DJ Link network, to request update packets
- Thread announcer = new Thread(null, new Runnable() {
- @Override
- public void run() {
- while (isRunning()) {
- sendAnnouncement(broadcastAddress.get());
- }
+ Thread announcer = new Thread(null, () -> {
+ while (isRunning()) {
+ sendAnnouncement(broadcastAddress.get());
}
}, "beat-link VirtualCdj announcement sender");
announcer.setDaemon(true);
@@ -965,34 +947,31 @@ private Thread createStatusReceiver() {
final DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
// Create the update reception thread
- Thread receiver = new Thread(null, new Runnable() {
- @Override
- public void run() {
- boolean received;
- while (isRunning()) {
- try {
- socket.get().receive(packet);
- received = true;
- } catch (IOException e) {
- // Don't log a warning if the exception was due to the socket closing at shutdown.
- if (isRunning()) {
- // We did not expect to have a problem; log a warning and shut down.
- logger.warn("Problem reading from DeviceStatus socket, flushing DeviceFinder due to likely network change and shutting down.", e);
- DeviceFinder.getInstance().flush();
- stop();
- }
- received = false;
+ Thread receiver = new Thread(null, () -> {
+ boolean received;
+ while (isRunning()) {
+ try {
+ socket.get().receive(packet);
+ received = true;
+ } catch (IOException e) {
+ // Don't log a warning if the exception was due to the socket closing at shutdown.
+ if (isRunning()) {
+ // We did not expect to have a problem; log a warning and shut down.
+ logger.warn("Problem reading from DeviceStatus socket, flushing DeviceFinder due to likely network change and shutting down.", e);
+ DeviceFinder.getInstance().flush();
+ stop();
}
- try {
- if (received && (packet.getAddress() != socket.get().getLocalAddress())) {
- DeviceUpdate update = buildUpdate(packet);
- if (update != null && isRunning()) {
- processUpdate(update);
- }
+ received = false;
+ }
+ try {
+ if (received && (packet.getAddress() != socket.get().getLocalAddress())) {
+ DeviceUpdate update = buildUpdate(packet);
+ if (update != null && isRunning()) {
+ processUpdate(update);
}
- } catch (Throwable t) {
- logger.warn("Problem processing device update packet", t);
}
+ } catch (Throwable t) {
+ logger.warn("Problem processing device update packet", t);
}
}
}, "beat-link VirtualCdj status receiver");
@@ -1011,7 +990,7 @@ public void run() {
*/
public Set findUnreachablePlayers() {
ensureRunning();
- Set result = new HashSet();
+ Set result = new HashSet<>();
for (DeviceAnnouncement candidate: DeviceFinder.getInstance().getCurrentDevices()) {
if (!Util.sameNetwork(matchedAddress.getNetworkPrefixLength(), matchedAddress.getAddress(), candidate.getAddress())) {
result.add(candidate);
@@ -1075,7 +1054,7 @@ public synchronized boolean start() throws Exception {
// Set up so we know we have to shut down if the DeviceFinder shuts down.
DeviceFinder.getInstance().addLifecycleListener(deviceFinderLifecycleListener);
- // Find some DJ Link devices so we can figure out the interface and address to use to talk to them
+ // Find some DJ Link devices, so we can figure out the interface and address to use to talk to them
DeviceFinder.getInstance().start();
for (int i = 0; DeviceFinder.getInstance().getCurrentDevices().isEmpty() && i < 20; i++) {
try {
@@ -1094,7 +1073,7 @@ public synchronized boolean start() throws Exception {
// See if there is an Opus Quad on the network, which means we need to be in the limited compatibility mode.
for (DeviceAnnouncement device : DeviceFinder.getInstance().getCurrentDevices()) {
- if (Util.isOpusQuad(device.getDeviceName())) {
+ if (device.isOpusQuad()) {
proxyingForVirtualRekordbox.set(true);
VirtualRekordbox.getInstance().addLifecycleListener(virtualRekordboxLifecycleListener);
final boolean success = VirtualRekordbox.getInstance().start();
@@ -1195,7 +1174,7 @@ private void sendAnnouncement(InetAddress broadcastAddress) {
*/
public Set getLatestStatus() {
ensureRunning();
- Set result = new HashSet();
+ Set result = new HashSet<>();
long now = System.currentTimeMillis();
for (DeviceUpdate update : updates.values()) {
if (now - update.getTimestamp() <= DeviceFinder.MAXIMUM_AGE) {
@@ -1269,7 +1248,7 @@ public DeviceUpdate getLatestStatusFor(int deviceNumber) {
* Keeps track of the registered master listeners.
*/
private final Set masterListeners =
- Collections.newSetFromMap(new ConcurrentHashMap());
+ Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
* Adds the specified master listener to receive device updates when there are changes related
@@ -1314,7 +1293,7 @@ public void removeMasterListener(MasterListener listener) {
@SuppressWarnings("WeakerAccess")
public Set getMasterListeners() {
// Make a copy so callers get an immutable snapshot of the current state.
- return Collections.unmodifiableSet(new HashSet(masterListeners));
+ return Collections.unmodifiableSet(new HashSet<>(masterListeners));
}
/**
@@ -1366,7 +1345,7 @@ private void deliverBeatAnnouncement(final Beat beat) {
* Keeps track of the registered device update listeners.
*/
private final Set updateListeners =
- Collections.newSetFromMap(new ConcurrentHashMap());
+ Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
* Adds the specified device update listener to receive device updates whenever they come in.
@@ -1411,7 +1390,7 @@ public void removeUpdateListener(DeviceUpdateListener listener) {
*/
public Set getUpdateListeners() {
// Make a copy so callers get an immutable snapshot of the current state.
- return Collections.unmodifiableSet(new HashSet(updateListeners));
+ return Collections.unmodifiableSet(new HashSet<>(updateListeners));
}
/**
@@ -1433,7 +1412,7 @@ private void deliverDeviceUpdate(final DeviceUpdate update) {
* Keeps track of the registered media details listeners.
*/
private final Set detailsListeners =
- Collections.newSetFromMap(new ConcurrentHashMap());
+ Collections.newSetFromMap(new ConcurrentHashMap<>());
/**
* Adds the specified media details listener to receive detail responses whenever they come in.
@@ -1477,7 +1456,7 @@ public void removeMediaDetailsListener(MediaDetailsListener listener) {
*/
public Set getMediaDetailsListeners() {
// Make a copy so callers get an immutable snapshot of the current state.
- return Collections.unmodifiableSet(new HashSet(detailsListeners));
+ return Collections.unmodifiableSet(new HashSet<>(detailsListeners));
}
/**
@@ -1959,7 +1938,7 @@ public void stopped(LifecycleParticipant sender) {
* Will hold an instance when we are actively sending beats, so we can let it know when the metronome changes,
* and when it is time to shut down.
*/
- private final AtomicReference beatSender = new AtomicReference();
+ private final AtomicReference beatSender = new AtomicReference<>();
/**
* Check whether we are currently running a {@link BeatSender}; if we are, notify it that there has been a change
@@ -2067,17 +2046,14 @@ public synchronized void setSendingStatus(boolean send) throws IOException {
final AtomicBoolean stillRunning = new AtomicBoolean(true);
sendingStatus = stillRunning; // Allow other threads to stop us when necessary.
- Thread sender = new Thread(null, new Runnable() {
- @Override
- public void run() {
- while (stillRunning.get()) {
- sendStatus();
- try {
- //noinspection BusyWait
- Thread.sleep(getStatusInterval());
- } catch (InterruptedException e) {
- logger.warn("beat-link VirtualCDJ status sender thread was interrupted; continuing");
- }
+ Thread sender = new Thread(null, () -> {
+ while (stillRunning.get()) {
+ sendStatus();
+ try {
+ //noinspection BusyWait
+ Thread.sleep(getStatusInterval());
+ } catch (InterruptedException e) {
+ logger.warn("beat-link VirtualCDJ status sender thread was interrupted; continuing");
}
}
}, "beat-link VirtualCdj status sender");
@@ -2125,7 +2101,7 @@ public synchronized boolean isSendingStatus() {
* playing, and it will keep time from there. When we stop again, we save the metronome's current beat here.
*/
private final AtomicReference whereStopped =
- new AtomicReference(metronome.getSnapshot(metronome.getStartTime()));
+ new AtomicReference<>(metronome.getSnapshot(metronome.getStartTime()));
/**
* Indicates whether we should currently pretend to be playing. This will only have an impact when we are sending
@@ -2216,7 +2192,7 @@ public void adjustPlaybackPosition(int ms) {
/**
* When have started the process of requesting the tempo master role from another player, this gets set to its
- * device number. Otherwise it has the value {@code 0}.
+ * device number. Otherwise, it has the value {@code 0}.
*/
private final AtomicInteger requestingMasterRoleFromPlayer = new AtomicInteger(0);
@@ -2242,7 +2218,7 @@ public synchronized void becomeTempoMaster() throws IOException {
payload[2] = getDeviceNumber();
payload[8] = getDeviceNumber();
if (logger.isDebugEnabled()) {
- logger.debug("Sending master yield request to player " + currentMaster);
+ logger.debug("Sending master yield request to player {}", currentMaster);
}
requestingMasterRoleFromPlayer.set(currentMaster.deviceNumber);
assembleAndSendPacket(Util.PacketType.MASTER_HANDOFF_REQUEST, payload, currentMaster.address, BeatFinder.BEAT_PORT);
@@ -2358,7 +2334,7 @@ public boolean isOnAir() {
/**
* Controls the tempo at which we report ourselves to be playing. Only meaningful if we are sending status packets.
* If {@link #isSynced()} is {@code true} and we are not the tempo master, any value set by this method will
- * overridden by the the next tempo master change.
+ * be overridden by the next tempo master change.
*
* @param bpm the tempo, in beats per minute, that we should report in our status and beat packets
*/
@@ -2503,7 +2479,7 @@ private Snapshot avoidBeatPacket() {
/**
* Send a status packet to all devices on the network. Used when we are actively sending status, presumably so we
- * we can be the tempo master. Avoids sending one within twice {@link BeatSender#BEAT_THRESHOLD} milliseconds of
+ * can be the tempo master. Avoids sending one within twice {@link BeatSender#BEAT_THRESHOLD} milliseconds of
* a beat, to make sure the beat packet announces the new beat before an early status packet confuses matters.
*/
private void sendStatus() {
@@ -2537,7 +2513,7 @@ private void sendStatus() {
try {
socket.get().send(packet);
} catch (IOException e) {
- logger.warn("Unable to send status packet to " + device, e);
+ logger.warn("Unable to send status packet to {}", device, e);
}
}
}
@@ -2563,21 +2539,13 @@ private VirtualCdj() {
masterTempo.set(Double.doubleToLongBits(0.0)); // Note that we have no master tempo yet.
// Arrange to have our status accurately reflect any relevant updates and commands from the mixer.
- BeatFinder.getInstance().addOnAirListener(new OnAirListener() {
- @Override
- public void channelsOnAir(Set audibleChannels) {
- setOnAir(audibleChannels.contains((int)getDeviceNumber()));
- }
- });
+ BeatFinder.getInstance().addOnAirListener(audibleChannels -> setOnAir(audibleChannels.contains((int)getDeviceNumber())));
- BeatFinder.getInstance().addFaderStartListener(new FaderStartListener() {
- @Override
- public void fadersChanged(Set playersToStart, Set playersToStop) {
- if (playersToStart.contains((int)getDeviceNumber())) {
- setPlaying(true);
- } else if (playersToStop.contains((int)getDeviceNumber())) {
- setPlaying(false);
- }
+ BeatFinder.getInstance().addFaderStartListener((playersToStart, playersToStop) -> {
+ if (playersToStart.contains((int)getDeviceNumber())) {
+ setPlaying(true);
+ } else if (playersToStop.contains((int)getDeviceNumber())) {
+ setPlaying(false);
}
});
@@ -2591,14 +2559,11 @@ public void setSyncMode(boolean synced) {
public void becomeMaster() {
logger.debug("Received packet telling us to become master.");
if (isSendingStatus()) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- becomeTempoMaster();
- } catch (Throwable t) {
- logger.error("Problem becoming tempo master in response to sync command packet", t);
- }
+ new Thread(() -> {
+ try {
+ becomeTempoMaster();
+ } catch (Throwable t) {
+ logger.error("Problem becoming tempo master in response to sync command packet", t);
}
}).start();
} else {
@@ -2611,14 +2576,14 @@ public void run() {
@Override
public void yieldMasterTo(int deviceNumber) {
if (logger.isDebugEnabled()) {
- logger.debug("Received instruction to yield master to device " + deviceNumber);
+ logger.debug("Received instruction to yield master to device {}", deviceNumber);
}
if (isTempoMaster()) {
if (isSendingStatus() && getDeviceNumber() != deviceNumber) {
nextMaster.set(deviceNumber);
final DeviceUpdate lastStatusFromNewMaster = getLatestStatusFor(deviceNumber);
if (lastStatusFromNewMaster == null) {
- logger.warn("Unable to send master yield response to device " + deviceNumber + ": no status updates have been received from it!");
+ logger.warn("Unable to send master yield response to device {}: no status updates have been received from it!", deviceNumber);
} else {
byte[] payload = new byte[YIELD_ACK_PAYLOAD.length];
System.arraycopy(YIELD_ACK_PAYLOAD, 0, payload, 0, YIELD_ACK_PAYLOAD.length);
@@ -2627,12 +2592,12 @@ public void yieldMasterTo(int deviceNumber) {
try {
assembleAndSendPacket(Util.PacketType.MASTER_HANDOFF_RESPONSE, payload, lastStatusFromNewMaster.getAddress(), UPDATE_PORT);
} catch (Throwable t) {
- logger.error("Problem sending master yield acknowledgment to player " + deviceNumber, t);
+ logger.error("Problem sending master yield acknowledgment to player {}", deviceNumber, t);
}
}
}
} else {
- logger.warn("Ignoring instruction to yield master to device " + deviceNumber + ": we were not tempo master.");
+ logger.warn("Ignoring instruction to yield master to device {}: we were not tempo master.", deviceNumber);
}
}
@@ -2640,7 +2605,7 @@ public void yieldMasterTo(int deviceNumber) {
@Override
public void yieldResponse(int deviceNumber, boolean yielded) {
if (logger.isDebugEnabled()) {
- logger.debug("Received yield response of " + yielded + " from device " + deviceNumber);
+ logger.debug("Received yield response of {} from device {}", yielded, deviceNumber);
}
if (yielded) {
if (isSendingStatus()) {
@@ -2649,11 +2614,9 @@ public void yieldResponse(int deviceNumber, boolean yielded) {
masterYieldedFrom.set(deviceNumber);
} else {
if (requestingMasterRoleFromPlayer.get() == 0) {
- logger.warn("Ignoring master yield response from player " + deviceNumber +
- " because we are not trying to become tempo master.");
+ logger.warn("Ignoring master yield response from player {} because we are not trying to become tempo master.", deviceNumber);
} else {
- logger.warn("Ignoring master yield response from player " + deviceNumber +
- " because we asked player " + requestingMasterRoleFromPlayer.get());
+ logger.warn("Ignoring master yield response from player {} because we asked player {}", deviceNumber, requestingMasterRoleFromPlayer.get());
}
}
} else {
@@ -2697,7 +2660,7 @@ void handleSpecialAnnouncementPacket(Util.PacketType kind, DatagramPacket packet
} else if (kind == Util.PacketType.DEVICE_NUMBER_STAGE_3) {
handleDeviceClaimPacket(packet, 0x24);
} else if (kind == Util.PacketType.DEVICE_NUMBER_WILL_ASSIGN) {
- logger.debug("The mixer at address " + packet.getAddress().getHostAddress() + " wants to assign us a specific device number.");
+ logger.debug("The mixer at address {} wants to assign us a specific device number.", packet.getAddress().getHostAddress());
if (claimingNumber.get() != 0) {
requestNumberFromMixer(packet.getAddress());
} else {
@@ -2706,9 +2669,9 @@ void handleSpecialAnnouncementPacket(Util.PacketType kind, DatagramPacket packet
} else if (kind == Util.PacketType.DEVICE_NUMBER_ASSIGN) {
mixerAssigned.set(packet.getData()[0x24]);
if (mixerAssigned.get() == 0) {
- logger.debug("Mixer at address " + packet.getAddress().getHostAddress() + " told us to use any device.");
+ logger.debug("Mixer at address {} told us to use any device.", packet.getAddress().getHostAddress());
} else {
- logger.info("Mixer at address " + packet.getAddress().getHostAddress() + " told us to use device number " + mixerAssigned.get());
+ logger.info("Mixer at address {} told us to use device number {}", packet.getAddress().getHostAddress(), mixerAssigned.get());
}
} else if (kind == Util.PacketType.DEVICE_NUMBER_ASSIGNMENT_FINISHED) {
mixerAssigned.set(claimingNumber.get());
@@ -2718,20 +2681,20 @@ void handleSpecialAnnouncementPacket(Util.PacketType kind, DatagramPacket packet
if (defendedDevice == 0) {
logger.warn("Ignoring unexplained attempt to defend device 0.");
} else if (defendedDevice == claimingNumber.get()) {
- logger.warn("Another device is defending device number " + defendedDevice + ", so we can't use it.");
+ logger.warn("Another device is defending device number {}, so we can't use it.", defendedDevice);
claimRejected.set(true);
} else if (isRunning()) {
if (defendedDevice == getDeviceNumber()) {
logger.warn("Another device has claimed it owns our device number, shutting down.");
stop();
} else {
- logger.warn("Another device is defending a number we are not using, ignoring: " + defendedDevice);
+ logger.warn("Another device is defending a number we are not using, ignoring: {}", defendedDevice);
}
} else {
- logger.warn("Received device number defense message for device number " + defendedDevice + " when we are not even running!");
+ logger.warn("Received device number defense message for device number {} when we are not even running!", defendedDevice);
}
} else {
- logger.warn("Received unrecognized special announcement packet type: " + kind);
+ logger.warn("Received unrecognized special announcement packet type: {}", kind);
}
}
diff --git a/src/main/java/org/deepsymmetry/beatlink/data/OpusProvider.java b/src/main/java/org/deepsymmetry/beatlink/data/OpusProvider.java
index 44aab18..c866bec 100644
--- a/src/main/java/org/deepsymmetry/beatlink/data/OpusProvider.java
+++ b/src/main/java/org/deepsymmetry/beatlink/data/OpusProvider.java
@@ -36,12 +36,10 @@ public class OpusProvider {
private static final Logger logger = LoggerFactory.getLogger(OpusProvider.class);
/**
- * Public constant for the opus name to be used throughout the codebase.
+ * The device name reported by Opus Quad, so we can recognize when we are dealing with one of these devices.
*/
public static final String opusName = "OPUS-QUAD";
-
-
/**
* Keep track of whether we are running.
*/