alphatheta-connect 0.25.3 → 0.26.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cli.js +65 -29
- package/lib/cli.js.map +1 -1
- package/lib/index.js +65 -29
- package/lib/index.js.map +1 -1
- package/lib/virtualcdj/stagehand.d.ts +13 -3
- package/package.json +3 -1
package/lib/cli.js
CHANGED
|
@@ -1467,7 +1467,9 @@ async function viaLocal(local, opts) {
|
|
|
1467
1467
|
if (!orm) {
|
|
1468
1468
|
break;
|
|
1469
1469
|
}
|
|
1470
|
-
|
|
1470
|
+
// Playlist entries reference the track through trackId; entry.id is the
|
|
1471
|
+
// entry's own row id (or its index, for OneLibrary), not a track.
|
|
1472
|
+
yield orm.findTrack(entry.trackId);
|
|
1471
1473
|
}
|
|
1472
1474
|
};
|
|
1473
1475
|
const tracks = { [Symbol.asyncIterator]: iterateTracks };
|
|
@@ -3285,7 +3287,9 @@ var RekordboxAnlz = (function() {
|
|
|
3285
3287
|
this.time = this._io.readU4be();
|
|
3286
3288
|
this.loopTime = this._io.readU4be();
|
|
3287
3289
|
this.colorId = this._io.readU1();
|
|
3288
|
-
this._unnamed9 = this._io.readBytes(
|
|
3290
|
+
this._unnamed9 = this._io.readBytes(7);
|
|
3291
|
+
this.loopNumerator = this._io.readU2be();
|
|
3292
|
+
this.loopDenominator = this._io.readU2be();
|
|
3289
3293
|
if (this.lenEntry > 43) {
|
|
3290
3294
|
this.lenComment = this._io.readU4be();
|
|
3291
3295
|
}
|
|
@@ -3305,7 +3309,7 @@ var RekordboxAnlz = (function() {
|
|
|
3305
3309
|
this.colorBlue = this._io.readU1();
|
|
3306
3310
|
}
|
|
3307
3311
|
if ((this.lenEntry - this.lenComment) > 48) {
|
|
3308
|
-
this.
|
|
3312
|
+
this._unnamed18 = this._io.readBytes(((this.lenEntry - 48) - this.lenComment));
|
|
3309
3313
|
}
|
|
3310
3314
|
}
|
|
3311
3315
|
|
|
@@ -3337,6 +3341,16 @@ var RekordboxAnlz = (function() {
|
|
|
3337
3341
|
* and has been assigned a color.
|
|
3338
3342
|
*/
|
|
3339
3343
|
|
|
3344
|
+
/**
|
|
3345
|
+
* The numerator of the loop size fraction for a quantized loop,
|
|
3346
|
+
* e.g. 4 for a 4-beat loop. Zero when the loop is not quantized.
|
|
3347
|
+
*/
|
|
3348
|
+
|
|
3349
|
+
/**
|
|
3350
|
+
* The denominator of the loop size fraction for a quantized loop,
|
|
3351
|
+
* e.g. 1 for a 4-beat loop.
|
|
3352
|
+
*/
|
|
3353
|
+
|
|
3340
3354
|
/**
|
|
3341
3355
|
* The comment assigned to this cue by the DJ, if any, with a trailing NUL.
|
|
3342
3356
|
*/
|
|
@@ -5767,16 +5781,20 @@ function makeBeatGrid(data) {
|
|
|
5767
5781
|
* Fill cue and loop data from the ANLZ section
|
|
5768
5782
|
*/
|
|
5769
5783
|
function makeCueAndLoop(data) {
|
|
5770
|
-
return data.body.cues
|
|
5784
|
+
return data.body.cues
|
|
5785
|
+
.map((entry) => {
|
|
5771
5786
|
// Cues with the status 0 are likely leftovers that were removed
|
|
5772
|
-
|
|
5787
|
+
// `hotCue` is the button number (1-8, A-H); zero marks a memory cue.
|
|
5788
|
+
// `type` only says whether the entry is a cue point (1) or a loop (2).
|
|
5789
|
+
const button = entry.hotCue === 0 ? false : entry.hotCue;
|
|
5773
5790
|
const isCue = entry.type === 0x01;
|
|
5774
5791
|
const isLoop = entry.type === 0x02;
|
|
5775
5792
|
// NOTE: Unlike the remotedb, these entries are already in milliseconds.
|
|
5776
5793
|
const offset = entry.time;
|
|
5777
5794
|
const length = entry.loopTime - offset;
|
|
5778
5795
|
return (0, utils_1.makeCueLoopEntry)(isCue, isLoop, offset, length, button);
|
|
5779
|
-
})
|
|
5796
|
+
})
|
|
5797
|
+
.filter((c) => c !== null);
|
|
5780
5798
|
}
|
|
5781
5799
|
/**
|
|
5782
5800
|
* Fill waveform HD data from the ANLZ section
|
|
@@ -5812,9 +5830,13 @@ function makeExtendedCues(data) {
|
|
|
5812
5830
|
b: (_c = entry.colorBlue) !== null && _c !== void 0 ? _c : 0,
|
|
5813
5831
|
};
|
|
5814
5832
|
}
|
|
5815
|
-
// Add comment if present
|
|
5833
|
+
// Add comment if present. The tag stores it with a trailing NUL, which
|
|
5834
|
+
// is not part of what the DJ typed.
|
|
5816
5835
|
if (entry.lenComment > 0 && entry.comment) {
|
|
5817
|
-
|
|
5836
|
+
const comment = entry.comment.replace(/\0+$/, '');
|
|
5837
|
+
if (comment.length > 0) {
|
|
5838
|
+
cue.comment = comment;
|
|
5839
|
+
}
|
|
5818
5840
|
}
|
|
5819
5841
|
// Add quantized loop information if present
|
|
5820
5842
|
if (entry.loopNumerator !== undefined && entry.loopNumerator > 0) {
|
|
@@ -5880,19 +5902,24 @@ function makeSongStructure(data) {
|
|
|
5880
5902
|
},
|
|
5881
5903
|
};
|
|
5882
5904
|
const mood = (_a = moodMap[data.body.mood]) !== null && _a !== void 0 ? _a : 'high';
|
|
5883
|
-
const bank = (_b = bankMap[data.body.
|
|
5905
|
+
const bank = (_b = bankMap[data.body.bank]) !== null && _b !== void 0 ? _b : 'default';
|
|
5906
|
+
// Field names follow the Kaitai-generated object (rekordbox_anlz.ksy
|
|
5907
|
+
// `song_structure_entry`): `phraseNumber`, `beatNumber`, `fillIn`,
|
|
5908
|
+
// `fillInBeatNumber`, and `kind` is a `phrase_high` / `phrase_mid` /
|
|
5909
|
+
// `phrase_low` object whose `id` carries the raw kind value.
|
|
5884
5910
|
const phrases = data.body.entries.map((entry) => {
|
|
5885
5911
|
var _a;
|
|
5912
|
+
const kind = typeof entry.kind === 'object' ? entry.kind.id : entry.kind;
|
|
5886
5913
|
const phrase = {
|
|
5887
|
-
index: entry.
|
|
5888
|
-
beat: entry.
|
|
5889
|
-
kind
|
|
5890
|
-
phraseType: (_a = phraseTypeMap[mood][
|
|
5914
|
+
index: entry.phraseNumber,
|
|
5915
|
+
beat: entry.beatNumber,
|
|
5916
|
+
kind,
|
|
5917
|
+
phraseType: (_a = phraseTypeMap[mood][kind]) !== null && _a !== void 0 ? _a : 'Unknown',
|
|
5891
5918
|
};
|
|
5892
5919
|
// Add fill-in information if present
|
|
5893
|
-
if (entry.
|
|
5894
|
-
phrase.fill = entry.
|
|
5895
|
-
phrase.fillBeat = entry.
|
|
5920
|
+
if (entry.fillIn > 0) {
|
|
5921
|
+
phrase.fill = entry.fillIn;
|
|
5922
|
+
phrase.fillBeat = entry.fillInBeatNumber;
|
|
5896
5923
|
}
|
|
5897
5924
|
return phrase;
|
|
5898
5925
|
});
|
|
@@ -7111,7 +7138,12 @@ class ProlinkNetwork {
|
|
|
7111
7138
|
}
|
|
7112
7139
|
const tx = Telemetry.startTransaction({ name: 'connect' });
|
|
7113
7140
|
const connectMethod = (_a = __classPrivateFieldGet(this, _ProlinkNetwork_config, "f").connectMethod) !== null && _a !== void 0 ? _a : 'active';
|
|
7141
|
+
// Pick the device number once and keep it. A CDJ-3000 that already holds
|
|
7142
|
+
// a record for our IP ignores a re-claim under a different number, so a
|
|
7143
|
+
// disconnect/connect cycle must present the same identity (see
|
|
7144
|
+
// getStagehandMac).
|
|
7114
7145
|
const vcdjId = (_b = __classPrivateFieldGet(this, _ProlinkNetwork_config, "f").vcdjId) !== null && _b !== void 0 ? _b : (connectMethod === 'stagehand' ? (0, virtualcdj_1.generateStagehandDeviceId)() : constants_1.DEFAULT_VCDJ_ID);
|
|
7146
|
+
__classPrivateFieldGet(this, _ProlinkNetwork_config, "f").vcdjId = vcdjId;
|
|
7115
7147
|
const vcdjName = (_c = __classPrivateFieldGet(this, _ProlinkNetwork_config, "f").vcdjName) !== null && _c !== void 0 ? _c : (connectMethod === 'stagehand' ? 'Stagehand' : undefined);
|
|
7116
7148
|
// Create VCDJ or Stagehand device
|
|
7117
7149
|
const vcdj = connectMethod === 'stagehand'
|
|
@@ -12000,7 +12032,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
|
12000
12032
|
var _StagehandAnnouncer_instances, _StagehandAnnouncer_announceSocket, _StagehandAnnouncer_vcdj, _StagehandAnnouncer_intervalHandle, _StagehandAnnouncer_currentStage, _StagehandAnnouncer_stageCounter, _StagehandAnnouncer_iface, _StagehandAnnouncer_logger, _StagehandAnnouncer_onStartupComplete, _StagehandAnnouncer_mac, _StagehandAnnouncer_startStartup, _StagehandAnnouncer_sendPacket, _StagehandAnnouncer_sendStagePackets, _StagehandAnnouncer_advanceStage, _StagehandAnnouncer_startKeepAlive;
|
|
12001
12033
|
Object.defineProperty(exports, "__esModule", ({ value: true }));
|
|
12002
12034
|
exports.StagehandAnnouncer = exports.getVirtualStagehand = exports.StagehandStartupStage = exports.STAGEHAND_KEEP_ALIVE_INTERVAL = exports.STAGEHAND_STARTUP_INTERVAL = void 0;
|
|
12003
|
-
exports.
|
|
12035
|
+
exports.getStagehandMac = getStagehandMac;
|
|
12004
12036
|
exports.generateStagehandDeviceId = generateStagehandDeviceId;
|
|
12005
12037
|
exports.makeStagehand0aPacket = makeStagehand0aPacket;
|
|
12006
12038
|
exports.makeStagehand02Packet = makeStagehand02Packet;
|
|
@@ -12019,17 +12051,21 @@ var StagehandStartupStage;
|
|
|
12019
12051
|
StagehandStartupStage[StagehandStartupStage["KeepAlive"] = 6] = "KeepAlive";
|
|
12020
12052
|
})(StagehandStartupStage || (exports.StagehandStartupStage = StagehandStartupStage = {}));
|
|
12021
12053
|
/**
|
|
12022
|
-
*
|
|
12054
|
+
* The protocol-layer MAC a Stagehand device embeds in its 0x02 claim and 0x06
|
|
12055
|
+
* keep-alive: the AlphaTheta OUI (c8:3d:fc) followed by the low three bytes of
|
|
12056
|
+
* the interface's own MAC.
|
|
12057
|
+
*
|
|
12058
|
+
* This must stay stable for the life of the host. A CDJ-3000 records a peer by
|
|
12059
|
+
* the identity in its claim, and once it holds a record for our IP it ignores
|
|
12060
|
+
* later claims from the same IP that carry a different MAC or device number:
|
|
12061
|
+
* the new peer never receives the unicast status/position stream. Observed on
|
|
12062
|
+
* emulated CDJ-3000 firmware 3.20: a freshly randomized identity on every
|
|
12063
|
+
* connect() was served once and then never again until the player rebooted,
|
|
12064
|
+
* while the previously registered identity kept being served immediately.
|
|
12023
12065
|
*/
|
|
12024
|
-
function
|
|
12025
|
-
const
|
|
12026
|
-
|
|
12027
|
-
mac[1] = 0x3d;
|
|
12028
|
-
mac[2] = 0xfc;
|
|
12029
|
-
mac[3] = Math.floor(Math.random() * 256);
|
|
12030
|
-
mac[4] = Math.floor(Math.random() * 256);
|
|
12031
|
-
mac[5] = Math.floor(Math.random() * 256);
|
|
12032
|
-
return mac;
|
|
12066
|
+
function getStagehandMac(iface) {
|
|
12067
|
+
const ifaceMac = iface.mac.split(':').map(s => parseInt(s, 16));
|
|
12068
|
+
return Uint8Array.from([0xc8, 0x3d, 0xfc, ...ifaceMac.slice(3, 6)]);
|
|
12033
12069
|
}
|
|
12034
12070
|
/**
|
|
12035
12071
|
* Generates a random Stagehand device ID in the observed range of 141 to 211.
|
|
@@ -12043,9 +12079,9 @@ function generateStagehandDeviceId() {
|
|
|
12043
12079
|
* @param iface - The network interface to use
|
|
12044
12080
|
* @param id - The device ID to use (defaults to random Stagehand ID)
|
|
12045
12081
|
* @param name - The device name (defaults to 'Stagehand')
|
|
12046
|
-
* @param macAddr - The
|
|
12082
|
+
* @param macAddr - The protocol-layer MAC (defaults to one derived from iface)
|
|
12047
12083
|
*/
|
|
12048
|
-
const getVirtualStagehand = (iface, id = generateStagehandDeviceId(), name = 'Stagehand', macAddr =
|
|
12084
|
+
const getVirtualStagehand = (iface, id = generateStagehandDeviceId(), name = 'Stagehand', macAddr = getStagehandMac(iface)) => ({
|
|
12049
12085
|
id,
|
|
12050
12086
|
name,
|
|
12051
12087
|
type: types_1.DeviceType.Stagehand,
|