Skip to content

Commit

Permalink
Improve efficiency of Opus Quad check
Browse files Browse the repository at this point in the history
Use an interned string so we can compare for object equality.
Also made a bunch of updates to take advantage of the newer
Java version we build against, and fix typos in documentation.
  • Loading branch information
brunchboy committed May 27, 2024
1 parent ce66c0f commit 5b8a9f8
Show file tree
Hide file tree
Showing 7 changed files with 226 additions and 266 deletions.
17 changes: 8 additions & 9 deletions src/main/java/org/deepsymmetry/beatlink/CdjStatus.java
Original file line number Diff line number Diff line change
Expand Up @@ -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 <i>M<sub>h</sub></i> in the
* master role to another device, labeled <i>M<sub>h</sub></i> in the
* <a href="https://djl-analysis.deepsymmetry.org/djl-analysis/vcdj.html#cdj-status-packets">Packet Analysis document</a>.
*
* <p>Normally it holds the value 0xff, but during a tempo master hand-off, it holds
Expand Down Expand Up @@ -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<Integer> expectedStatusPacketSizes = Collections.newSetFromMap(new ConcurrentHashMap<>());
static {
Expand Down Expand Up @@ -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);

}
}
Expand All @@ -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);
Expand Down Expand Up @@ -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).
*
* <p>When the track being played has not been analyzed by rekordbox, or is playing on a non-nexus player, this
Expand Down Expand Up @@ -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 ||
Expand Down Expand Up @@ -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
*/
Expand Down
18 changes: 16 additions & 2 deletions src/main/java/org/deepsymmetry/beatlink/DeviceAnnouncement.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package org.deepsymmetry.beatlink;

import org.deepsymmetry.beatlink.data.OpusProvider;

import java.net.DatagramPacket;
import java.net.InetAddress;

Expand Down Expand Up @@ -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]);
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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() + "]";
Expand Down
Loading

0 comments on commit 5b8a9f8

Please sign in to comment.