x32-osc
Version:
X32/M32 interface to all OSC parameters and meters
1,050 lines • 89.8 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.X32 = void 0;
///<reference path="x32-osc.d.ts" />
var events_1 = require("events");
var dgram = __importStar(require("dgram"));
var x32definitions_1 = require("./x32definitions");
var fs = __importStar(require("fs"));
var x32branches = [
'config',
'ch',
'auxin',
'fxrtn',
'bus',
'mtx',
'main',
'dca',
'fx',
'outputs',
'headamp',
];
var X32 = /** @class */ (function (_super) {
__extends(X32, _super);
/**
*
* @param address - IP address or url to the x32
* @param x32UpdateFrequency - number of milliseconds between meter updates. Between ? and ?
*
*/
function X32(address, x32UpdateFrequency) {
var _this = _super.call(this) || this;
_this._serverVersion = '';
_this._model = '';
_this._firmwareVersion = '';
_this._connected = false;
_this._ready = false;
_this._x32Meta = { _address: [] };
_this._linkcfg = {
hadly: true,
eq: true,
dyn: true,
fdrmute: true,
mono: false,
};
_this._lastValidMessage = Date.now();
_this._x32UpdateFrequency = 10;
_this._meterSubscriptions = [];
_this._OSCProxy = {
get: function (x32Node, property) {
if (!property || typeof property == 'symbol')
return null;
var prop = x32Node[property];
if (!prop || Array.isArray(prop) || property[0] == '_')
return null;
if (!prop._type) {
//@ts-ignore
return new Proxy(prop, this);
}
else
return prop._value;
},
//set needs to be an arrow function so that "this" will be the X32 object
set: function (x32Node, property, value) {
if (!property || typeof property == 'symbol')
return false;
var prop = x32Node[property];
if (!prop || Array.isArray(prop) || property[0] == '_')
return false;
if (prop._type && typeof value == 'string') {
var oscAddress = '/' + prop._address.join('/');
_this._send(oscAddress, [{ type: 's', data: value }]);
return true;
}
if (!prop._type && typeof value == 'object' && value != null) {
var properties = Object.getOwnPropertyNames(value);
for (var i = 0; i < properties.length; i++) {
_this._OSCProxy.set(prop, properties[i], value[properties[i]], 0);
}
return true;
}
return false;
},
ownKeys: function (x32Node) {
var rtn = [];
var keys = Object.getOwnPropertyNames(x32Node);
for (var i = 0; i < keys.length; i++) {
if (keys[i][0] != '_')
rtn.push(keys[i]);
}
return rtn;
},
defineProperty: function () {
return false;
},
deleteProperty: function () {
return false;
},
};
_this._nodeEmitter = new events_1.EventEmitter();
_this._leafEmitter = new events_1.EventEmitter();
if (x32UpdateFrequency) {
_this._x32UpdateFrequency = x32UpdateFrequency / 50;
if (_this._x32UpdateFrequency > 99) {
_this.emit('info', 'Lowering X32 update frequency to highest possible: 4950ms');
_this._x32UpdateFrequency = 99;
}
if (_this._x32UpdateFrequency < 1) {
_this.emit('info', 'raising X32 update frequency to lowest possible: 50ms');
_this._x32UpdateFrequency = 1;
}
}
//calculate frequency
_this.address = address;
_this._socket = dgram.createSocket({ type: 'udp4', reuseAddr: true });
_this._socket.on('close', function () {
_this.emit('closed');
});
_this._socket.on('error', function (err) {
_this.emit('error', err);
});
_this._socket.on('connect', function () {
_this._x32Verify();
});
_this._socket.on('message', function (buf) {
_this._processDataFromX32(buf);
});
_this._socket.bind(0, '0.0.0.0', function () {
_this.emit('info', 'Connecting to X32 at ' + address);
_this._socket.connect(10023, address);
});
_this.on('connected', function () {
_this._connected = true;
_this.subscribe();
_this._subscription = setInterval(function () {
if (_this.connected)
_this.subscribe();
}, 9000);
_this.refreshState();
/* this._getNode('ch/17/mix')
.then((values) => {
console.log('promise res:');
console.log(values);
})
.catch((err) => {
console.log('err:' + err);
}); */
});
_this._heartbeat = setInterval(function () {
var time = Math.round((Date.now() - _this._lastValidMessage) / 1000);
if (time > 20) {
if (_this.connected) {
_this.emit('error', new Error('It has been ' +
time +
' seconds since last valid message from X32. Closing connection'));
}
else
_this.emit('error', new Error('Unable to connect to X32 at ' + _this.address));
_this.close();
}
else if (time > 10 && _this.connected) {
_this.emit('info', 'Warning: It has been ' +
time +
' seconds since last valid message from X32');
}
}, 5000);
_this.on('closed', function () {
_this.removeAllListeners();
});
return _this;
}
Object.defineProperty(X32.prototype, "serverVersion", {
get: function () {
return this._serverVersion;
},
enumerable: false,
configurable: true
});
Object.defineProperty(X32.prototype, "model", {
get: function () {
return this._model;
},
enumerable: false,
configurable: true
});
Object.defineProperty(X32.prototype, "firmwareVersion", {
get: function () {
return this._firmwareVersion;
},
enumerable: false,
configurable: true
});
Object.defineProperty(X32.prototype, "connected", {
get: function () {
return this._connected;
},
enumerable: false,
configurable: true
});
Object.defineProperty(X32.prototype, "ready", {
get: function () {
return this._ready;
},
enumerable: false,
configurable: true
});
X32.prototype.close = function () {
this.emit('info', 'Closing connection to X32');
this._connected = false;
if (this._subscription)
clearInterval(this._subscription);
clearInterval(this._heartbeat);
this._socket.close();
};
X32.prototype._send = function (cmd, args) {
var _this = this;
if (!this.connected && cmd != '/info') {
this.emit('error', new Error('Cannot send message to X32 unless connected'));
return;
}
if (args == undefined)
args = [];
var cmdBuf = stringToBuffer(cmd);
var argTypes = ',';
var argBufs = [];
if (args.length > 0) {
for (var i = 0; i < args.length; i++) {
argTypes += args[i].type;
argBufs.push(oscArgumentToBuffer(args[i]));
}
}
var typesBuf = stringToBuffer(argTypes);
var argsBuf = Buffer.concat(argBufs);
this._socket.send(Buffer.concat([cmdBuf, typesBuf, argsBuf]), function (err) {
if (err)
_this.emit('error', err);
});
};
X32.prototype.subscribe = function () {
if (!this.connected) {
this.emit('error', new Error('Cannot subscribe until X32 is connected.'));
return;
}
this._send('/xremote');
if (this._meterSubscriptions.length) {
for (var i = 0; i < this._meterSubscriptions.length; i++) {
var sub = this._meterSubscriptions[i];
var meterArgs = void 0;
if (typeof sub == 'number') {
meterArgs = [sub, 0, 0];
}
else if (sub.length == 2) {
meterArgs = [sub[0], sub[1], 0];
}
else
meterArgs = sub;
this._send('/meters', [
{ type: 's', data: '/meters/' + meterArgs[0] },
{ type: 'i', data: meterArgs[1] },
{ type: 'i', data: meterArgs[2] },
{ type: 'i', data: this._x32UpdateFrequency },
]);
}
}
else
this._send('/status');
};
X32.prototype._processDataFromX32 = function (buf) {
var split = buf.indexOf(0);
var oscAddress = buf.slice(0, split).toString();
split++;
split = Math.ceil(split / 4) * 4;
buf = buf.slice(split);
switch (oscAddress) {
case 'node':
this._lastValidMessage = Date.now();
var nodeArgs = oscFormatBufferToArguments(buf);
if (Array.isArray(nodeArgs)) {
if (nodeArgs.length == 1 && nodeArgs[0].type == 's') {
var values = oscNodeStringToValueArray(nodeArgs[0].data);
if (values.length) {
var nodeAddress = values.shift();
this._nodeEmitter.emit(nodeAddress, values);
//console.log('node' + ' ' + nodeAddress);
}
}
else
this.emit('error', new Error('Bad /node data from X32'));
}
else
this.emit('error', new Error(nodeArgs.error));
break;
case '/status':
this._lastValidMessage = Date.now();
break;
case '/info':
this._lastValidMessage = Date.now();
var infoArgs = oscFormatBufferToArguments(buf);
if (Array.isArray(infoArgs)) {
if (infoArgs.length == 4 &&
infoArgs.every(function (x) {
return x.type == 's';
})) {
this._serverVersion = infoArgs[0].data;
this._model = infoArgs[2].data;
this._firmwareVersion = infoArgs[3].data;
this.emit('info', 'Connected to X32. Model: ' +
this.model +
', firmware version: ' +
this.firmwareVersion);
this.emit('connected');
}
else
this.emit('error', new Error('Bad console info from X32'));
}
else
this.emit('error', new Error(infoArgs.error));
break;
default:
var possibleFirstNode = oscAddress.slice(1, oscAddress.indexOf('/', 1));
if (x32branches.indexOf(possibleFirstNode) != -1) {
var args = oscFormatBufferToArguments(buf);
if (Array.isArray(args) && args.length == 1) {
this._lastValidMessage = Date.now();
this._processChangeFromX32(oscAddress, args[0]);
if (args[0].type == 'f')
this._leafEmitter.emit(oscAddress, args[0].data);
}
else if (!Array.isArray(args)) {
this.emit('error', new Error(args.error));
}
else
this.emit('error', new Error('Unknown change type from X32: Multiple OSC arguments'));
}
else {
if (possibleFirstNode == 'meters') {
var args = oscFormatBufferToArguments(buf);
if (Array.isArray(args)) {
if (args.length == 1 &&
args[0].type == 'b' &&
args[0].data.length % 4 == 0) {
this._lastValidMessage = Date.now();
var meterNumber = oscAddress.slice(oscAddress.indexOf('/', 1) + 1);
var meterBuf = args[0].data.slice(4);
var meterData = [];
for (var i = 0; i < meterBuf.length; i += 4) {
meterData.push(meterBuf.readFloatLE(i));
}
this.emit('meter', {
number: parseInt(meterNumber),
meters: meterData,
});
}
else
this.emit('error', new Error('Bad meter data from X32'));
}
else
this.emit('error', new Error(args.error));
}
else if (possibleFirstNode.slice(0, 1) == '-') {
//console.log("Control info I don't care about from X32: " + oscAddress);
}
else
this.emit('error', new Error('Unknown OSC address from x32: ' + oscAddress));
}
break;
}
};
X32.prototype._x32Verify = function () {
this._send('/info');
};
X32.prototype._getNode = function (address) {
var _this = this;
return new Promise(function (res, rej) {
var nodeTimeout;
var nodeListener = function (values) {
_this._nodeEmitter.off(address, nodeListener);
clearTimeout(nodeTimeout);
res(values);
};
nodeTimeout = setTimeout(function () {
_this._nodeEmitter.off(address, nodeListener);
_this.emit('error', new Error('Timeout on X32 node request for ' +
address +
'. Closing X32 connection.'));
_this.close();
rej('timeout');
}, 5000);
_this._nodeEmitter.on(address, nodeListener);
_this._send('/node', [{ type: 's', data: address }]);
});
};
X32.prototype.refreshState = function () {
var _this = this;
var start = Date.now();
this._refreshState()
.then(function () {
_this._markAllRedundant();
_this.emit('info', 'Received X32 state in ' + (Date.now() - start) + ' ms');
if (!_this._ready) {
_this._ready = true;
_this.emit('ready');
//fs.writeFile('./x32-obj.json', JSON.stringify(this.OSC), () => {});
}
})
.catch(function (err) {
_this.emit('error', err);
});
};
X32.prototype._refreshState = function (node, prefix) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
return [2 /*return*/, new Promise(function (res, rej) {
if (!node) {
node = x32definitions_1.x32NodeStructure;
_this._x32Meta = { _address: [] };
_this._OSC = new Proxy(_this._x32Meta, _this._OSCProxy);
}
if (!prefix)
prefix = '';
var nodeProperties = Object.getOwnPropertyNames(node);
var i = -1;
var getNextNode = function () { return __awaiter(_this, void 0, void 0, function () {
var child, childName_1, childNode, hasLeavesNodesVar;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
i++;
if (!(i < nodeProperties.length)) return [3 /*break*/, 7];
child = node[nodeProperties[i]];
childName_1 = nodeProperties[i];
if (childName_1[0] == "'")
childName_1 = childName_1.slice(1);
childNode = void 0;
if (!child._type) return [3 /*break*/, 2];
return [4 /*yield*/, getNextNode()];
case 1:
_a.sent();
return [2 /*return*/];
case 2:
hasLeavesNodesVar = hasLeavesNodes(child);
if (!hasLeavesNodesVar[0]) return [3 /*break*/, 4];
return [4 /*yield*/, this._getNode(prefix + childName_1)
.then(function (values) {
_this._populateX32Object(prefix + childName_1, values);
})
.catch(function (err) {
rej(err);
})];
case 3:
_a.sent();
_a.label = 4;
case 4:
if (!hasLeavesNodesVar[1]) return [3 /*break*/, 6];
return [4 /*yield*/, this._refreshState(child, prefix + childName_1 + '/').catch(function (err) {
rej(err);
})];
case 5:
_a.sent();
_a.label = 6;
case 6:
getNextNode();
return [3 /*break*/, 8];
case 7:
res();
_a.label = 8;
case 8: return [2 /*return*/];
}
});
}); };
getNextNode();
})];
});
});
};
X32.prototype._markAllRedundant = function () {
if (isNode(this._x32Meta.config) && isNode(this._x32Meta.config.linkcfg)) {
if (isMetaLeaf(this._x32Meta.config.linkcfg.hadly))
this._linkcfg.hadly = this._x32Meta.config.linkcfg.hadly._value == 'ON';
if (isMetaLeaf(this._x32Meta.config.linkcfg.eq))
this._linkcfg.eq = this._x32Meta.config.linkcfg.eq._value == 'ON';
if (isMetaLeaf(this._x32Meta.config.linkcfg.dyn))
this._linkcfg.dyn = this._x32Meta.config.linkcfg.dyn._value == 'ON';
if (isMetaLeaf(this._x32Meta.config.linkcfg.fdrmute))
this._linkcfg.fdrmute =
this._x32Meta.config.linkcfg.fdrmute._value == 'ON';
}
if (isNode(this._x32Meta.config) && isNode(this._x32Meta.config.mono)) {
if (isMetaLeaf(this._x32Meta.config.mono.link))
this._linkcfg.mono = this._x32Meta.config.mono.link._value == 'ON';
}
for (var i = 1; i <= 32; i += 2) {
this._markRedundant('ch', i);
}
for (var i = 1; i <= 8; i += 2) {
this._markRedundant('aux', i);
}
for (var i = 1; i <= 8; i += 2) {
this._markRedundant('fx', i);
}
for (var i = 1; i <= 16; i += 2) {
this._markRedundant('bus', i);
}
for (var i = 1; i <= 6; i += 2) {
this._markRedundant('mtx', i);
}
};
X32.prototype._markRedundant = function (type, num) {
num = num + (num % 2);
var linked = false;
var linkAddress = type + 'link';
var address = type;
if (type == 'fx') {
address = 'fxrtn';
}
if (type == 'aux') {
address = 'auxin';
}
if (isNode(this._x32Meta.config)) {
var linkNode = this._x32Meta.config[linkAddress];
if (isNode(linkNode)) {
var linkLeaf = linkNode[num - 1 + '-' + num];
if (isMetaLeaf(linkLeaf))
linked = linkLeaf._value == 'ON';
}
else
console.error('Tried to mark redundant flags from nonexistent node ' + linkNode);
}
var _a = [
linked && this._linkcfg.hadly,
linked && this._linkcfg.eq,
linked && this._linkcfg.dyn,
linked && this._linkcfg.fdrmute,
], hadly = _a[0], eq = _a[1], dyn = _a[2], fdrmute = _a[3];
var parentNode = this._x32Meta[address];
if (isNode(parentNode)) {
var node = parentNode[num.toString().padStart(2, '0')];
if (isNode(node)) {
if (isNode(node.preamp))
markRedundantTree(node.preamp, hadly);
if (isNode(node.eq))
markRedundantTree(node.eq, eq);
if (isNode(node.dyn))
markRedundantTree(node.dyn, dyn);
if (isNode(node.gate))
markRedundantTree(node.gate, dyn);
if (isNode(node.insert))
markRedundantTree(node.insert, dyn);
if (isNode(node.mix))
markRedundantTree(node.mix, fdrmute);
if (isNode(node.grp))
markRedundantTree(node.grp, fdrmute);
}
else
console.error('Tried to mark redundant flags from nonexistent node ' +
address +
'/' +
num.toString().padStart(2, '0'));
}
else
console.error('Tried to mark redundant flags from nonexistent node ' + address);
//hadly, eq, dyn, fdrmute
};
X32.prototype._populateX32Object = function (address, values, leaves, node) {
if (!leaves) {
//assume root
leaves = getLeafDefs(address);
}
if (leaves.length != values.length) {
this.emit('error', new Error('X32 definitions do not match data from X32 for address: ' + address));
return;
}
if (!node)
node = this._x32Meta;
var index = address.indexOf('/');
var property;
if (index == -1) {
property = address;
}
else
property = address.slice(0, index);
if (!node[property])
node[property] = { _address: __spreadArray(__spreadArray([], node._address, true), [property], false) };
var nodeProperty = node[property];
if (nodeProperty._type) {
this.emit('error', new Error('Corrupt X32 tree. Leaf where a node should be.'));
}
else {
if (index == -1) {
var nodeProperty_1 = node[property];
for (var i = 0; i < leaves.length; i++) {
nodeProperty_1[leaves[i].name] = __assign({ _address: __spreadArray(__spreadArray([], nodeProperty_1._address, true), [leaves[i].name], false), _value: values[i] }, leaves[i].type);
}
}
else {
this._populateX32Object(address.slice(index + 1), values, leaves, node[property]);
}
}
};
Object.defineProperty(X32.prototype, "OSC", {
get: function () {
//@ts-ignore /*I don't know how to tell typescript that _OSCProxy doesn't preserve type
return this._OSC;
},
set: function (value) {
this.emit('error', new Error('Replacing the entire parameter tree is not yet coded'));
},
enumerable: false,
configurable: true
});
Object.defineProperty(X32.prototype, "meterSubscriptions", {
get: function () {
return __spreadArray([], this._meterSubscriptions, true);
},
set: function (value) {
this._meterSubscriptions = value;
if (this.ready)
this.subscribe();
},
enumerable: false,
configurable: true
});
X32.prototype._setOSC = function (address, value, x32InNode, strAddress) {
var _this = this;
var x32Node;
var arrayAddress;
var stringAddress;
if (typeof address == 'string') {
if (address[0] == '/')
address = address.slice(1);
arrayAddress = address.split('/');
}
else {
arrayAddress = address;
}
if (x32InNode) {
x32Node = x32InNode;
}
else
x32Node = this._x32Meta;
if (strAddress) {
stringAddress = strAddress;
}
else
stringAddress = '/' + arrayAddress.join('/');
return new Promise(function (res, rej) {
if (arrayAddress.length == 1) {
var leaf = x32Node[address[0]];
if (!Array.isArray(leaf) && leaf._type) {
leaf._value = value;
_this._sendDatawTimeout(stringAddress, value)
.then(function () {
res();
})
.catch(function (err) {
rej(err);
});
}
else
rej('Address ' + stringAddress + ' does not point to leaf');
}
else {
var nodeName = arrayAddress[0];
var nextNode = x32Node[nodeName];
if (!Array.isArray(nextNode) && !nextNode._type) {
_this._setOSC(arrayAddress.slice(1), value, nextNode, stringAddress)
.then(function () {
res();
})
.catch(function (err) {
rej(err);
});
}
else
rej('Bad address or metatree: ' + stringAddress);
}
});
};
X32.prototype._sendDatawTimeout = function (address, value, int, timeout) {
var _this = this;
if (!timeout)
timeout = 20;
var arg;
if (typeof value == 'string') {
arg = [{ type: 's', data: value }];
}
else
arg = [{ type: 'f', data: value }];
if (int && typeof value == 'number')
arg = [{ type: 'i', data: value }];
return new Promise(function (res, rej) {
_this._send(address, arg);
setTimeout(function () {
res();
}, timeout);
});
};
X32.prototype._learnTextFromNumber = function (address, node, valueIndex, steps, int, delay) {
var _this = this;
return new Promise(function (res, rej) { return __awaiter(_this, void 0, void 0, function () {
var rtn, i, change, valueCount, lastVal, numToSend;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
rtn = [];
i = -1;
change = 0;
valueCount = 0;
lastVal = '';
_a.label = 1;
case 1:
if (!(i < steps)) return [3 /*break*/, 3];
i++;
numToSend = i;
if (!int)
numToSend = i / steps;
return [4 /*yield*/, this._sendDatawTimeout(address, numToSend, int, delay)
.then(function () {
return _this._getNode(node);
})
.then(function (values) {
rtn.push(values[valueIndex]);
//console.log(i)
//console.log(numToSend + ' ' + values[valueIndex]);
if (values[valueIndex] != lastVal) {
//console.log(i - change);
valueCount++;
//console.log('change:' + numToSend)
change = i;
}
lastVal = values[valueIndex];
})
.catch(function (err) {
rej(err);
})];
case 2:
_a.sent();
return [3 /*break*/, 1];
case 3:
//console.log('valueCount: ' + valueCount);
res(rtn);
return [2 /*return*/];
}
});
}); });
};
X32.prototype.testX32NodeStructure = function () {
var _this = this;
return new Promise(function (res, rej) {
var startTime = Date.now();
var test = x32definitions_1.x32NodeStructure;
_this._testTree(test)
.then(function (rtn) {
var seconds = Math.round((Date.now() - startTime) / 1000);
var minutes = Math.floor(seconds / 60);
seconds = seconds % 60;
var hours = Math.floor(minutes / 60);
minutes = minutes % 60;
console.log('Testing finished in ' +
hours +
':' +
minutes.toString().padStart(2, '0') +
':' +
seconds.toString().padStart(2, '0'));
res(rtn);
})
.catch(function (err) {
rej(err);
});
});
};
X32.prototype._testTree = function (node, inAddress, leaveKeys) {
var _this = this;
var address = '';
if (inAddress)
address = inAddress;
return new Promise(function (res, rej) {
var rtn = [];
var leavesNodes = hasLeavesNodes(node);
if (leavesNodes[0] || leavesNodes[1]) {
var properties_1 = Object.getOwnPropertyNames(node);
var i_1 = -1;
var checkLeaf_1 = function () {
i_1++;
if (i_1 == properties_1.length - 1 && properties_1[i_1][0] == "'")
i_1 = properties_1.length;
if (address == '/ch' && i_1 >= 6)
i_1 = properties_1.length;
if (address == '/fx' && i_1 >= 3)
i_1 = properties_1.length;
if (i_1 < properties_1.length) {
if (properties_1[i_1][0] == "'" &&
i_1 < properties_1.length - 2 &&
!leaveKeys) {
if (address.slice(-3) == '/eq') {
i_1 = properties_1.length - 1;
}
else
i_1 = properties_1.length - 2;
}
if (address == '/ch')
i_1 = 6;
if (address == '/fx')
i_1 = 3;
var maybeLeaf = node[properties_1[i_1]];
if (maybeLeaf._type) {
var leafName_1 = properties_1[i_1];
if (leafName_1[0] == "'")
leafName_1 = leafName_1.slice(1);
console.log('Testing leaf: ' + address + '/' + leafName_1);
if (maybeLeaf._type == 'conditional' && leaveKeys) {
var key = getLeafValue(maybeLeaf._keyAddress, _this.OSC);
if (typeof key == 'object') {
rtn.push(key.error);
}
else {
if (maybeLeaf._conditional[key]) {
if (maybeLeaf._conditional[key][maybeLeaf._index]) {
maybeLeaf = JSON.parse(JSON.stringify(maybeLeaf._conditional[key][maybeLeaf._index]));
}
else {
i_1 = properties_1.length - 1;
maybeLeaf = { _type: 'unused' };
}
}
else
rtn.push('Incomplete conditional data');
}
}
switch (maybeLeaf._type) {
case 'bitmap':
var bitmapArray_1 = [
'%'.padEnd(maybeLeaf._size + 1, '0'),
'%'.padEnd(maybeLeaf._size, '0') + '1',
];
_this._learnTextFromNumber(address + '/' + leafName_1, address.slice(1), i_1, 1, true)
.then(function (values) {
if (JSON.stringify(values) != JSON.stringify(bitmapArray_1)) {
rtn.push(address + '/' + leafName_1);
}
checkLeaf_1();
})
.catch(function (err) {
rej(err);
});
break;
case 'btnString':
var btnStringArray_1 = ['X001', 'X002'];
var btnReturnArray_1 = [];
_this._sendDatawTimeout(address + '/' + leafName_1, btnStringArray_1[0])
.then(function () {
return _this._getNode(address.slice(1));
})
.then(function (nodeValues) {
btnReturnArray_1.push(nodeValues[i_1]);
return _this._sendDatawTimeout(address + '/' + leafName_1, btnStringArray_1[1]);
})
.then(function () {
return _this._getNode(address.slice(1));
})
.then(function (nodeValues) {
btnReturnArray_1.push(nodeValues[i_1]);
if (JSON.stringify(btnReturnArray_1) !=
JSON.stringify(btnStringArray_1)) {
//fs.writeFile('./test.json', JSON.stringify(btnReturnArray), () => {});
//fs.writeFile('./test2.json', JSON.stringify(btnStringArray), () => {});
rtn.push(address + '/' + leafName_1);
}
checkLeaf_1();
})
.catch(function (err) {
rej(err);
});
break;
case 'encString':
var encStringArray_1 = ['X001', 'X002'];
var encReturnArray_1 = [];
_this._sendDatawTimeout(address + '/' + leafName_1, encStringArray_1[0])
.then(function () {
return _this._getNode(address.slice(1));
})
.then(function (nodeValues) {
encReturnArray_1.push(nodeValues[i_1]);
return _this._sendDatawTimeout(address + '/' + leafName_1, encStringArray_1[1]);
})
.then(function () {
return _this._getNode(address.slice(1));
})
.then(function (nodeValues) {
encReturnArray_1.push(nodeValues[i_1]);
if (JSON.stringify(encReturnArray_1) !=
JSON.stringify(encStringArray_1)) {
//fs.writeFile('./test.json', JSON.stringify(encReturnArray), () => {});
//fs.writeFile('./test2.json', JSON.stringify(encStringArray), () => {});
rtn.push(address + '/' + leafName_1);
}
checkLeaf_1();
})
.catch(function (err) {
rej(err);
});
break;
case 'enum':
if (!leaveKeys || !maybeLeaf._isKey) {
var isKey_1 = !!maybeLeaf._isKey;
var enumArray_1 = maybeLeaf._enum;
var enumDelay = 10;
if (address.slice(-4) == 'link')
enumDelay = 70;
_this._learnTextFromNumber(address + '/' + leafName_1, address.slice(1), i_1, enumArray_1.length - 1, true, enumDelay)
.then(function (values) {
if (JSON.stringify(values) != JSON.stringify(enumArray_1)) {
//fs.writeFile('./test.json', JSON.stringify(values), () => {});
//fs.writeFile('./test2.json', JSON.stringify(enumArray), () => {});
/* for (let i = 0; i < enumArray.length; i++) {
if (values[i] != enumArray[i]) console.log(values[i] + ' ' + enumArray[i]);
} */
rtn.push(address + '/' + leafName_1);
checkLeaf_1();
}
else {
if (isKey_1 && !leaveKeys) {
(function () { return __awaiter(_this, void 0, void 0, function () {
var _loop_1, this_1, i_2;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
_loop_1 = function (i_2) {
return __generator(this, function (_b) {
switch (_b.label) {
case 0: return [4 /*yield*/, this_1._setOSC(address + '/' + leafName_1, enumArray_1[i_2])
.then(function () {
console.log('Testing leaf: ' +
address +
'/' +
leafName_1 +
', setting: ' +
enumArray_1[i_2]);
return _this._testTree(node, address, true);
})
.then(function (values) {
var identifiedValues = values.map(function (x) {
return enumArray_1[i_2] + ' ' + x;
});
rtn = __spreadArray(__spreadArray([], rtn, true), identifiedValues, true);
})
.catch(function (err) {
rej(err);
})];
case 1:
_b.sent();
return [2 /*return*/];
}
});
};
this_1 = this;
i_2