@arcanewizards/tcnet 0.1.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/dist/chunk-2L35L5P5.js +86 -0
- package/dist/chunk-7IUB6OJ3.cjs +435 -0
- package/dist/chunk-FAJ3XTSE.js +435 -0
- package/dist/chunk-VRXVI5VA.cjs +86 -0
- package/dist/chunk-VXAKTGOW.js +70 -0
- package/dist/chunk-VYNI4G3K.cjs +70 -0
- package/dist/errors.cjs +14 -0
- package/dist/errors.d.cts +17 -0
- package/dist/errors.d.ts +17 -0
- package/dist/errors.js +14 -0
- package/dist/index.cjs +6076 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +6076 -0
- package/dist/monitor.cjs +307 -0
- package/dist/monitor.d.cts +70 -0
- package/dist/monitor.d.ts +70 -0
- package/dist/monitor.js +307 -0
- package/dist/protocol.cjs +41 -0
- package/dist/protocol.d.cts +308 -0
- package/dist/protocol.d.ts +308 -0
- package/dist/protocol.js +41 -0
- package/dist/types.cjs +1 -0
- package/dist/types.d.cts +91 -0
- package/dist/types.d.ts +91 -0
- package/dist/types.js +0 -0
- package/dist/utils.cjs +17 -0
- package/dist/utils.d.cts +25 -0
- package/dist/utils.d.ts +25 -0
- package/dist/utils.js +17 -0
- package/package.json +68 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TCNetConfigurationError
|
|
3
|
+
} from "./chunk-VXAKTGOW.js";
|
|
4
|
+
|
|
5
|
+
// src/utils.ts
|
|
6
|
+
var differsByMoreThan = (a, b, diff) => {
|
|
7
|
+
return Math.abs(a - b) > diff;
|
|
8
|
+
};
|
|
9
|
+
var MAX_NODE_NAME_LENGTH = 8;
|
|
10
|
+
var MAX_VENDOR_NAME_LENGTH = 16;
|
|
11
|
+
var MAX_APPLICATION_NAME_LENGTH = 16;
|
|
12
|
+
var generateProtocolStrings = ({
|
|
13
|
+
nodeName,
|
|
14
|
+
vendorName,
|
|
15
|
+
appName
|
|
16
|
+
}) => {
|
|
17
|
+
const strings = {
|
|
18
|
+
nodeName: Buffer.from(
|
|
19
|
+
nodeName.padEnd(MAX_NODE_NAME_LENGTH, "\0"),
|
|
20
|
+
"ascii"
|
|
21
|
+
),
|
|
22
|
+
vendorName: Buffer.from(
|
|
23
|
+
vendorName.padEnd(MAX_VENDOR_NAME_LENGTH, "\0"),
|
|
24
|
+
"ascii"
|
|
25
|
+
),
|
|
26
|
+
appName: Buffer.from(
|
|
27
|
+
appName.padEnd(MAX_APPLICATION_NAME_LENGTH, "\0"),
|
|
28
|
+
"ascii"
|
|
29
|
+
)
|
|
30
|
+
};
|
|
31
|
+
if (strings.nodeName.length > MAX_NODE_NAME_LENGTH) {
|
|
32
|
+
throw new TCNetConfigurationError(
|
|
33
|
+
`Node name "${nodeName}" exceeds maximum length of ${MAX_NODE_NAME_LENGTH} ASCII characters`
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
if (strings.vendorName.length > MAX_VENDOR_NAME_LENGTH) {
|
|
37
|
+
throw new TCNetConfigurationError(
|
|
38
|
+
`Vendor name "${vendorName}" exceeds maximum length of ${MAX_VENDOR_NAME_LENGTH} ASCII characters`
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
if (strings.appName.length > MAX_APPLICATION_NAME_LENGTH) {
|
|
42
|
+
throw new TCNetConfigurationError(
|
|
43
|
+
`Application name "${appName}" exceeds maximum length of ${MAX_APPLICATION_NAME_LENGTH} ASCII characters`
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
return strings;
|
|
47
|
+
};
|
|
48
|
+
var generateApplicationVersion = (version) => {
|
|
49
|
+
const [major, minor, bug] = version.split(".").map((part) => parseInt(part));
|
|
50
|
+
if (major === void 0 || minor === void 0 || bug === void 0 || isNaN(major) || isNaN(minor) || isNaN(bug) || major < 0 || minor < 0 || bug < 0 || major > 255 || minor > 255 || bug > 255) {
|
|
51
|
+
throw new TCNetConfigurationError(
|
|
52
|
+
`Invalid application version "${version}". Must be in format "major.minor.bug" with each part between 0 and 255.`
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
const buffer = Buffer.alloc(3);
|
|
56
|
+
buffer.writeUInt8(major, 0);
|
|
57
|
+
buffer.writeUInt8(minor, 1);
|
|
58
|
+
buffer.writeUInt8(bug, 2);
|
|
59
|
+
return buffer;
|
|
60
|
+
};
|
|
61
|
+
var parseApplicationVersion = (buffer) => {
|
|
62
|
+
if (buffer.length !== 3) {
|
|
63
|
+
throw new TCNetConfigurationError(
|
|
64
|
+
`Invalid application version buffer length ${buffer.length}. Must be exactly 3 bytes.`
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
const major = buffer.readUInt8(0);
|
|
68
|
+
const minor = buffer.readUInt8(1);
|
|
69
|
+
const bug = buffer.readUInt8(2);
|
|
70
|
+
return `${major}.${minor}.${bug}`;
|
|
71
|
+
};
|
|
72
|
+
var getNodeDescription = (info) => {
|
|
73
|
+
return `${info.nodeName} (${info.appName} ${info.appVersion}) - ${info.host}:${info.nodeListenerPort} (${info.nodeType})`;
|
|
74
|
+
};
|
|
75
|
+
var calculateUniqueNodeId = (info) => {
|
|
76
|
+
return `${info.host}:${info.nodeId}`;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export {
|
|
80
|
+
differsByMoreThan,
|
|
81
|
+
generateProtocolStrings,
|
|
82
|
+
generateApplicationVersion,
|
|
83
|
+
parseApplicationVersion,
|
|
84
|
+
getNodeDescription,
|
|
85
|
+
calculateUniqueNodeId
|
|
86
|
+
};
|
|
@@ -0,0 +1,435 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports, "__esModule", {value: true});
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
var _chunkVYNI4G3Kcjs = require('./chunk-VYNI4G3K.cjs');
|
|
5
|
+
|
|
6
|
+
// src/protocol.ts
|
|
7
|
+
var TCNET_LAYER_COUNT = 8;
|
|
8
|
+
var TCNET_LAYER_STATE_IDS = Object.freeze({
|
|
9
|
+
IDLE: 0,
|
|
10
|
+
/**
|
|
11
|
+
* Not in spec, but seems to be what's observed.
|
|
12
|
+
*/
|
|
13
|
+
LOADING: 2,
|
|
14
|
+
PLAYING: 3,
|
|
15
|
+
LOOPING: 4,
|
|
16
|
+
PAUSED: 5,
|
|
17
|
+
STOPPED: 6,
|
|
18
|
+
CUEDOWN: 7,
|
|
19
|
+
PLATTERDOWN: 8,
|
|
20
|
+
FFWD: 9,
|
|
21
|
+
FFRV: 10,
|
|
22
|
+
HOLD: 11,
|
|
23
|
+
/**
|
|
24
|
+
* Not in spec, but seems to be what's observed.
|
|
25
|
+
*/
|
|
26
|
+
END: 17,
|
|
27
|
+
/**
|
|
28
|
+
* TODO: determine what this means, seems to be disconnected state?
|
|
29
|
+
*/
|
|
30
|
+
UNKNOWN: 255
|
|
31
|
+
});
|
|
32
|
+
var TCNET_LAYER_STATES = Object.freeze(
|
|
33
|
+
Object.fromEntries(
|
|
34
|
+
Object.entries(TCNET_LAYER_STATE_IDS).map(([key, value]) => [
|
|
35
|
+
value,
|
|
36
|
+
key
|
|
37
|
+
])
|
|
38
|
+
)
|
|
39
|
+
);
|
|
40
|
+
var getTcNetLayerState = (id) => {
|
|
41
|
+
const state = TCNET_LAYER_STATES[id];
|
|
42
|
+
if (!state) {
|
|
43
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown TCNet layer state: ${id}`);
|
|
44
|
+
}
|
|
45
|
+
return state;
|
|
46
|
+
};
|
|
47
|
+
var TCNET_MIXER_TYPE_IDS = Object.freeze({
|
|
48
|
+
STANDARD: 0,
|
|
49
|
+
EXTENDED: 2
|
|
50
|
+
});
|
|
51
|
+
var TCNET_MIXER_TYPES = Object.freeze(
|
|
52
|
+
Object.fromEntries(
|
|
53
|
+
Object.entries(TCNET_MIXER_TYPE_IDS).map(([key, value]) => [
|
|
54
|
+
value,
|
|
55
|
+
key
|
|
56
|
+
])
|
|
57
|
+
)
|
|
58
|
+
);
|
|
59
|
+
var getTcNetMixerType = (id) => {
|
|
60
|
+
const type = TCNET_MIXER_TYPES[id];
|
|
61
|
+
if (!type) {
|
|
62
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown TCNet mixer type: ${id}`);
|
|
63
|
+
}
|
|
64
|
+
return type;
|
|
65
|
+
};
|
|
66
|
+
var TCNET_MESSAGE_TYPE_IDS = Object.freeze({
|
|
67
|
+
OPT_IN: 2,
|
|
68
|
+
OPT_OUT: 3,
|
|
69
|
+
STATUS: 5,
|
|
70
|
+
TIME_SYNC: 10,
|
|
71
|
+
ERROR: 13,
|
|
72
|
+
REQUEST: 20,
|
|
73
|
+
APPLICATION_SPECIFIC_DATA_1: 30,
|
|
74
|
+
CONTROL: 101,
|
|
75
|
+
TEXT_DATA: 128,
|
|
76
|
+
KEYBOARD_DATA: 132,
|
|
77
|
+
DATA: 200,
|
|
78
|
+
FILE: 204,
|
|
79
|
+
APPLICATION_SPECIFIC_DATA_2: 213,
|
|
80
|
+
TIME: 254
|
|
81
|
+
});
|
|
82
|
+
var TCNET_MESSAGE_TYPES = Object.freeze(
|
|
83
|
+
Object.fromEntries(
|
|
84
|
+
Object.entries(TCNET_MESSAGE_TYPE_IDS).map(([key, value]) => [value, key])
|
|
85
|
+
)
|
|
86
|
+
);
|
|
87
|
+
var getTcNetMessageType = (id) => {
|
|
88
|
+
const type = TCNET_MESSAGE_TYPES[id];
|
|
89
|
+
if (!type) {
|
|
90
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown TCNet message type: ${id}`);
|
|
91
|
+
}
|
|
92
|
+
return type;
|
|
93
|
+
};
|
|
94
|
+
var TCNET_DATA_PACKET_TYPE_IDS = Object.freeze({
|
|
95
|
+
METRICS_DATA: 2,
|
|
96
|
+
METADATA: 4,
|
|
97
|
+
BEAT_GRID_DATA: 8,
|
|
98
|
+
CUE_DATA: 12,
|
|
99
|
+
SMALL_WAVEFORM: 16,
|
|
100
|
+
BIG_WAVEFORM: 32,
|
|
101
|
+
MIXER_DATA: 150
|
|
102
|
+
});
|
|
103
|
+
var TCNET_DATA_PACKET_TYPES = Object.freeze(
|
|
104
|
+
Object.fromEntries(
|
|
105
|
+
Object.entries(TCNET_DATA_PACKET_TYPE_IDS).map(([key, value]) => [
|
|
106
|
+
value,
|
|
107
|
+
key
|
|
108
|
+
])
|
|
109
|
+
)
|
|
110
|
+
);
|
|
111
|
+
var getTcNetDataPacketType = (id) => {
|
|
112
|
+
const type = TCNET_DATA_PACKET_TYPES[id];
|
|
113
|
+
if (!type) {
|
|
114
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown TCNet data packet type: ${id}`);
|
|
115
|
+
}
|
|
116
|
+
return type;
|
|
117
|
+
};
|
|
118
|
+
var TCNET_NODE_TYPE_IDS = Object.freeze({
|
|
119
|
+
AUTO: 1,
|
|
120
|
+
MASTER: 2,
|
|
121
|
+
SLAVE: 4,
|
|
122
|
+
REPEATER: 8
|
|
123
|
+
});
|
|
124
|
+
var TCNET_NODE_TYPES = Object.freeze(
|
|
125
|
+
Object.fromEntries(
|
|
126
|
+
Object.entries(TCNET_NODE_TYPE_IDS).map(([key, value]) => [value, key])
|
|
127
|
+
)
|
|
128
|
+
);
|
|
129
|
+
var getTcNetNodeType = (id) => {
|
|
130
|
+
const type = TCNET_NODE_TYPES[id];
|
|
131
|
+
if (!type) {
|
|
132
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown TCNet node type: ${id}`);
|
|
133
|
+
}
|
|
134
|
+
return type;
|
|
135
|
+
};
|
|
136
|
+
var TCNET_PORT_NODE_OPTION_FLAGS = Object.freeze({
|
|
137
|
+
NEED_AUTHENTICATION: 1,
|
|
138
|
+
/**
|
|
139
|
+
* Listens to TCNet Control Messages
|
|
140
|
+
*/
|
|
141
|
+
SUPPORTS_TCNCM: 2,
|
|
142
|
+
/**
|
|
143
|
+
* Listens to TCNet Application Specific Data Packets
|
|
144
|
+
*/
|
|
145
|
+
SUPPORTS_TCNASDP: 4,
|
|
146
|
+
/**
|
|
147
|
+
* Do not disturb/Sleeping. Node will request data itself if needed to avoid traffic
|
|
148
|
+
*/
|
|
149
|
+
DO_NOT_DISTURB: 8
|
|
150
|
+
});
|
|
151
|
+
var parseTcNetPortNodeOptions = (flags) => {
|
|
152
|
+
return Object.fromEntries(
|
|
153
|
+
Object.entries(TCNET_PORT_NODE_OPTION_FLAGS).map(([key, flag]) => [
|
|
154
|
+
key,
|
|
155
|
+
(flags & flag) !== 0 ? true : void 0
|
|
156
|
+
])
|
|
157
|
+
);
|
|
158
|
+
};
|
|
159
|
+
var generateTcNetPortNodeOptionsFlags = (options) => {
|
|
160
|
+
let flags = 0;
|
|
161
|
+
for (const [option, value] of Object.entries(options)) {
|
|
162
|
+
if (value) {
|
|
163
|
+
const flag = TCNET_PORT_NODE_OPTION_FLAGS[option];
|
|
164
|
+
flags |= flag;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return flags;
|
|
168
|
+
};
|
|
169
|
+
var TCNET_LAYER_TC_STATE_IDS = Object.freeze({
|
|
170
|
+
STOPPED: 0,
|
|
171
|
+
RUNNING: 1,
|
|
172
|
+
FORCE_RESYNC: 2
|
|
173
|
+
});
|
|
174
|
+
var TCNET_LAYER_TC_STATES = Object.freeze(
|
|
175
|
+
Object.fromEntries(
|
|
176
|
+
Object.entries(TCNET_LAYER_TC_STATE_IDS).map(([key, value]) => [
|
|
177
|
+
value,
|
|
178
|
+
key
|
|
179
|
+
])
|
|
180
|
+
)
|
|
181
|
+
);
|
|
182
|
+
var getTcNetLayerTCState = (id) => {
|
|
183
|
+
const state = TCNET_LAYER_TC_STATES[id];
|
|
184
|
+
if (!state) {
|
|
185
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown TCNet layer timecode state: ${id}`);
|
|
186
|
+
}
|
|
187
|
+
return state;
|
|
188
|
+
};
|
|
189
|
+
var MAX_NODE_ID = 256 * 256 - 1;
|
|
190
|
+
var MGMT_HEADER_VERSION = 3;
|
|
191
|
+
var MGMT_HEADER_MINOR_VERSION = 5;
|
|
192
|
+
var MGMT_MAGIC_HEADER = "TCN";
|
|
193
|
+
var writeManagementHeader = (buffer, header, messageType) => {
|
|
194
|
+
buffer.writeUInt16LE(header.nodeId, 0);
|
|
195
|
+
buffer.writeUInt8(header.protocolVersionMajor, 2);
|
|
196
|
+
buffer.writeUInt8(header.protocolVersionMinor, 3);
|
|
197
|
+
buffer.write(MGMT_MAGIC_HEADER, 4, "ascii");
|
|
198
|
+
buffer.writeUInt8(TCNET_MESSAGE_TYPE_IDS[messageType], 7);
|
|
199
|
+
header.nodeName.copy(buffer, 8, 0, 8);
|
|
200
|
+
buffer.writeUInt8(header.seq, 16);
|
|
201
|
+
buffer.writeUInt8(TCNET_NODE_TYPE_IDS[header.nodeType], 17);
|
|
202
|
+
buffer.writeUInt16LE(
|
|
203
|
+
generateTcNetPortNodeOptionsFlags(header.nodeOptions),
|
|
204
|
+
18
|
|
205
|
+
);
|
|
206
|
+
buffer.writeUInt32LE(header.timestamp, 20);
|
|
207
|
+
};
|
|
208
|
+
var parseManagementHeader = (buffer) => {
|
|
209
|
+
const magicHeader = buffer.toString("ascii", 4, 7);
|
|
210
|
+
if (magicHeader !== MGMT_MAGIC_HEADER) {
|
|
211
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(
|
|
212
|
+
`Invalid management header magic: ${magicHeader}`
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
nodeId: buffer.readUInt16LE(0),
|
|
217
|
+
protocolVersionMajor: buffer.readUInt8(2),
|
|
218
|
+
protocolVersionMinor: buffer.readUInt8(3),
|
|
219
|
+
messageType: getTcNetMessageType(buffer.readUInt8(7)),
|
|
220
|
+
nodeName: buffer.subarray(8, 16),
|
|
221
|
+
seq: buffer.readUInt8(16),
|
|
222
|
+
nodeType: getTcNetNodeType(buffer.readUInt8(17)),
|
|
223
|
+
nodeOptions: parseTcNetPortNodeOptions(buffer.readUInt16LE(18)),
|
|
224
|
+
timestamp: buffer.readUInt32LE(20)
|
|
225
|
+
};
|
|
226
|
+
};
|
|
227
|
+
var writeOptInPacket = (data) => {
|
|
228
|
+
const buffer = Buffer.alloc(68);
|
|
229
|
+
writeManagementHeader(buffer, data.header, "OPT_IN");
|
|
230
|
+
buffer.writeUInt16LE(data.nodeCount, 24);
|
|
231
|
+
buffer.writeUInt16LE(data.nodeListenerPort, 26);
|
|
232
|
+
buffer.writeUInt16LE(data.uptime, 28);
|
|
233
|
+
data.vendorName.copy(buffer, 32, 0, 16);
|
|
234
|
+
data.applicationName.copy(buffer, 48, 0, 16);
|
|
235
|
+
data.applicationVersion.copy(buffer, 64, 0, 3);
|
|
236
|
+
return buffer;
|
|
237
|
+
};
|
|
238
|
+
var parseOptInPacket = (header, buffer) => {
|
|
239
|
+
return {
|
|
240
|
+
header,
|
|
241
|
+
type: "OPT_IN",
|
|
242
|
+
nodeCount: buffer.readUInt16LE(24),
|
|
243
|
+
nodeListenerPort: buffer.readUInt16LE(26),
|
|
244
|
+
uptime: buffer.readUInt16LE(28),
|
|
245
|
+
vendorName: buffer.subarray(32, 48),
|
|
246
|
+
applicationName: buffer.subarray(48, 64),
|
|
247
|
+
applicationVersion: buffer.subarray(64, 67)
|
|
248
|
+
};
|
|
249
|
+
};
|
|
250
|
+
var writeOptOutPacket = (data) => {
|
|
251
|
+
const buffer = Buffer.alloc(28);
|
|
252
|
+
writeManagementHeader(buffer, data.header, "OPT_OUT");
|
|
253
|
+
buffer.writeUInt16LE(data.nodeCount, 24);
|
|
254
|
+
buffer.writeUInt16LE(data.nodeListenerPort, 26);
|
|
255
|
+
return buffer;
|
|
256
|
+
};
|
|
257
|
+
var parseOptOutPacket = (header, buffer) => {
|
|
258
|
+
return {
|
|
259
|
+
header,
|
|
260
|
+
type: "OPT_OUT",
|
|
261
|
+
nodeCount: buffer.readUInt16LE(24),
|
|
262
|
+
nodeListenerPort: buffer.readUInt16LE(26)
|
|
263
|
+
};
|
|
264
|
+
};
|
|
265
|
+
var parseStatusPacket = (header, buffer) => {
|
|
266
|
+
const nodeCount = buffer.readUInt16LE(24);
|
|
267
|
+
const nodeListenerPort = buffer.readUInt16LE(26);
|
|
268
|
+
const smpteMode = buffer.readUInt8(83);
|
|
269
|
+
const autoMasterMode = buffer.readUInt8(84);
|
|
270
|
+
const layers = new Array(8);
|
|
271
|
+
for (let n = 0; n < 8; n++) {
|
|
272
|
+
layers[n] = {
|
|
273
|
+
source: buffer.readUInt8(34 + n),
|
|
274
|
+
status: getTcNetLayerState(buffer.readUInt8(42 + n)),
|
|
275
|
+
trackId: buffer.readUInt32LE(50 + n * 4),
|
|
276
|
+
name: buffer.slice(172 + n * 16, 172 + (n + 1) * 16).toString("ascii").replace(/\0/g, "")
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
return {
|
|
280
|
+
header,
|
|
281
|
+
type: "STATUS",
|
|
282
|
+
nodeCount,
|
|
283
|
+
nodeListenerPort,
|
|
284
|
+
smpteMode,
|
|
285
|
+
autoMasterMode,
|
|
286
|
+
layers
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
var writeRequestPacket = (data) => {
|
|
290
|
+
const buffer = Buffer.alloc(26);
|
|
291
|
+
writeManagementHeader(buffer, data.header, "REQUEST");
|
|
292
|
+
buffer.writeUInt8(TCNET_DATA_PACKET_TYPE_IDS[data.dataType], 24);
|
|
293
|
+
buffer.writeUInt8(data.layer, 25);
|
|
294
|
+
return buffer;
|
|
295
|
+
};
|
|
296
|
+
var parseApplicationSpecificData1Packet = (header, _buffer) => {
|
|
297
|
+
return {
|
|
298
|
+
header,
|
|
299
|
+
type: "APPLICATION_SPECIFIC_DATA_1"
|
|
300
|
+
};
|
|
301
|
+
};
|
|
302
|
+
var parseMetricsDataPacket = (header, buffer) => {
|
|
303
|
+
return {
|
|
304
|
+
header,
|
|
305
|
+
type: "DATA",
|
|
306
|
+
dataType: "METRICS_DATA",
|
|
307
|
+
layer: buffer.readUInt8(25),
|
|
308
|
+
state: getTcNetLayerState(buffer.readUInt8(27)),
|
|
309
|
+
syncMaster: buffer.readUInt8(29),
|
|
310
|
+
beatMarker: buffer.readUInt8(31),
|
|
311
|
+
trackLengthMillis: buffer.readUInt32LE(32),
|
|
312
|
+
currentPositionMillis: buffer.readUInt32LE(36),
|
|
313
|
+
speed: buffer.readUInt32LE(40),
|
|
314
|
+
beatNumber: buffer.readUInt32LE(57),
|
|
315
|
+
bpm: buffer.readUInt32LE(112),
|
|
316
|
+
pitchBend: buffer.readInt16LE(116),
|
|
317
|
+
trackId: buffer.readUInt32LE(118)
|
|
318
|
+
};
|
|
319
|
+
};
|
|
320
|
+
var parseMetadataDataPacket = (header, buffer) => {
|
|
321
|
+
const encoding = header.protocolVersionMajor >= 3 && header.protocolVersionMinor >= 5 ? "utf16le" : "utf-8";
|
|
322
|
+
return {
|
|
323
|
+
header,
|
|
324
|
+
type: "DATA",
|
|
325
|
+
dataType: "METADATA",
|
|
326
|
+
layer: buffer.readUInt8(25),
|
|
327
|
+
trackArtist: buffer.toString(encoding, 29, 285).replace(/\0/g, ""),
|
|
328
|
+
trackTitle: buffer.toString(encoding, 285, 541).replace(/\0/g, ""),
|
|
329
|
+
trackKey: buffer.readUInt16LE(541),
|
|
330
|
+
trackId: buffer.readUInt32LE(543)
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
var parseMixerDataPacket = (header, buffer) => {
|
|
334
|
+
return {
|
|
335
|
+
header,
|
|
336
|
+
type: "DATA",
|
|
337
|
+
dataType: "MIXER_DATA",
|
|
338
|
+
mixerId: buffer.readUInt8(25),
|
|
339
|
+
mixerType: getTcNetMixerType(buffer.readUInt8(26)),
|
|
340
|
+
mixerName: buffer.toString("ascii", 29, 45).replace(/\0/g, ""),
|
|
341
|
+
micEqHi: buffer.readUInt8(59),
|
|
342
|
+
micEqLow: buffer.readUInt8(60),
|
|
343
|
+
masterAudioLevel: buffer.readUInt8(61),
|
|
344
|
+
masterFaderLevel: buffer.readUInt8(62)
|
|
345
|
+
};
|
|
346
|
+
};
|
|
347
|
+
var parseDataPacket = (header, buffer) => {
|
|
348
|
+
const dataType = getTcNetDataPacketType(buffer.readUInt8(24));
|
|
349
|
+
if (dataType === "METRICS_DATA") {
|
|
350
|
+
return parseMetricsDataPacket(header, buffer);
|
|
351
|
+
} else if (dataType === "MIXER_DATA") {
|
|
352
|
+
return parseMixerDataPacket(header, buffer);
|
|
353
|
+
} else if (dataType === "METADATA") {
|
|
354
|
+
return parseMetadataDataPacket(header, buffer);
|
|
355
|
+
}
|
|
356
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetError)(`Library support for ${dataType} not implemented`);
|
|
357
|
+
};
|
|
358
|
+
var parseSMPTEFramerate = (framerate) => {
|
|
359
|
+
if (framerate === 24 || framerate === 25 || framerate === 29 || framerate === 30) {
|
|
360
|
+
return framerate;
|
|
361
|
+
}
|
|
362
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetProtocolError)(`Unknown SMPTE framerate: ${framerate}`);
|
|
363
|
+
};
|
|
364
|
+
var parseTimePacket = (header, buffer) => {
|
|
365
|
+
const layers = new Array(8);
|
|
366
|
+
for (let i = 0; i < 8; i++) {
|
|
367
|
+
const smpteMode = buffer.readUInt8(106 + i * 6);
|
|
368
|
+
layers[i] = {
|
|
369
|
+
currentTimeMillis: buffer.readUInt32LE(24 + i * 4),
|
|
370
|
+
totalTimeMillis: buffer.readUInt32LE(56 + i * 4),
|
|
371
|
+
beatMarker: buffer.readUInt8(88 + i),
|
|
372
|
+
state: getTcNetLayerState(buffer.readUInt8(96 + i)),
|
|
373
|
+
smpte: {
|
|
374
|
+
/**
|
|
375
|
+
* Spec says 0 here, but ShowKontrol seems to also be sending 1.
|
|
376
|
+
*/
|
|
377
|
+
mode: smpteMode === 0 || smpteMode === 1 ? null : parseSMPTEFramerate(smpteMode),
|
|
378
|
+
state: getTcNetLayerTCState(buffer.readUInt8(107 + i * 6)),
|
|
379
|
+
hours: buffer.readUInt8(108 + i * 6),
|
|
380
|
+
minutes: buffer.readUInt8(109 + i * 6),
|
|
381
|
+
seconds: buffer.readUInt8(110 + i * 6),
|
|
382
|
+
frames: buffer.readUInt8(111 + i * 6)
|
|
383
|
+
},
|
|
384
|
+
onAir: buffer.length > 154 ? buffer.readUInt8(154 + i) : 255
|
|
385
|
+
};
|
|
386
|
+
}
|
|
387
|
+
return {
|
|
388
|
+
header,
|
|
389
|
+
type: "TIME",
|
|
390
|
+
layers,
|
|
391
|
+
generalSmpteFramerate: parseSMPTEFramerate(buffer.readUInt8(105))
|
|
392
|
+
};
|
|
393
|
+
};
|
|
394
|
+
var parsePacket = (buffer) => {
|
|
395
|
+
const header = parseManagementHeader(buffer);
|
|
396
|
+
switch (header.messageType) {
|
|
397
|
+
case "OPT_IN":
|
|
398
|
+
return parseOptInPacket(header, buffer);
|
|
399
|
+
case "OPT_OUT":
|
|
400
|
+
return parseOptOutPacket(header, buffer);
|
|
401
|
+
case "STATUS":
|
|
402
|
+
return parseStatusPacket(header, buffer);
|
|
403
|
+
case "DATA":
|
|
404
|
+
return parseDataPacket(header, buffer);
|
|
405
|
+
case "APPLICATION_SPECIFIC_DATA_1":
|
|
406
|
+
return parseApplicationSpecificData1Packet(header, buffer);
|
|
407
|
+
case "TIME":
|
|
408
|
+
return parseTimePacket(header, buffer);
|
|
409
|
+
default:
|
|
410
|
+
throw new (0, _chunkVYNI4G3Kcjs.TCNetError)(
|
|
411
|
+
`Library support for ${header.messageType} not implemented`
|
|
412
|
+
);
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
|
|
424
|
+
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
|
|
435
|
+
exports.TCNET_LAYER_COUNT = TCNET_LAYER_COUNT; exports.getTcNetLayerState = getTcNetLayerState; exports.getTcNetMixerType = getTcNetMixerType; exports.getTcNetMessageType = getTcNetMessageType; exports.getTcNetDataPacketType = getTcNetDataPacketType; exports.getTcNetNodeType = getTcNetNodeType; exports.parseTcNetPortNodeOptions = parseTcNetPortNodeOptions; exports.generateTcNetPortNodeOptionsFlags = generateTcNetPortNodeOptionsFlags; exports.getTcNetLayerTCState = getTcNetLayerTCState; exports.MAX_NODE_ID = MAX_NODE_ID; exports.MGMT_HEADER_VERSION = MGMT_HEADER_VERSION; exports.MGMT_HEADER_MINOR_VERSION = MGMT_HEADER_MINOR_VERSION; exports.writeManagementHeader = writeManagementHeader; exports.parseManagementHeader = parseManagementHeader; exports.writeOptInPacket = writeOptInPacket; exports.writeOptOutPacket = writeOptOutPacket; exports.writeRequestPacket = writeRequestPacket; exports.parsePacket = parsePacket;
|