Files
Cue-View/plugins/xair/main.js
T

124 lines
3.3 KiB
JavaScript

exports.config = {
defaultName: 'X Air Mixer',
connectionType: 'UDPsocket',
defaultPort: 10024,
mayChangePort: false,
heartbeatInterval: 9000,
heartbeatTimeout: 15000,
searchOptions: {
type: 'UDPsocket',
searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]),
devicePort: 10024,
listenPort: 0,
validateResponse(msg, info) {
return msg.toString().startWith('/xinfo');
},
},
};
exports.ready = function ready(device) {
const d = device;
d.data.channelFaders = new Array(32).fill(0);
d.data.channelFadersDB = new Array(32).fill(0);
d.data.channelMutes = new Array(32).fill(0);
d.data.channelNames = new Array(32).fill('end');
d.data.channelColors = new Array(32);
d.data.stereoFader = 0;
d.data.stereoFaderDB = 0;
d.data.stereoMute = 0;
d.send('/xinfo');
};
function parseAddress(msg) {
const addr = msg.split('/');
addr.shift();
return addr;
}
function convertToDBTheBehringerWay(f) {
if (f >= 0.5) {
return f * 40 - 30;
}
if (f >= 0.25) {
return f * 80 - 50;
}
if (f >= 0.0625) {
return f * 160 - 70;
}
return f * 480 - 90;
}
exports.data = function data(device, buf) {
this.deviceInfoUpdate(device, 'status', 'ok');
const msg = buf.toString().split('\x00');
const d = device;
if (msg[0] === '/xinfo') {
if (msg[7].length > 0) {
d.data.name = msg[7];
} else {
d.data.name = msg[6];
}
d.data.ip = msg[5];
d.data.firmware = msg[13];
d.data.model = msg[9];
this.deviceInfoUpdate(d, 'defaultName', d.data.name);
d.send('/lr/mix/fader\x00\x00\x00\x00');
d.send('/lr/mix/on\x00\x00\x00\x00');
for (let i = 0; i <= 32; i++) {
d.send(Buffer.from(`/ch/${i.toString().padStart(2, '0')}/config/name\x00\x00\x00\x00`));
}
d.draw();
} else if (msg[0] === '/meters/0') {
// console.log(msg)
} else if (msg[0].includes('/mix/fader')) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
if (addr[0] === 'ch') {
d.data.channelFaders[channel - 1] = buf.readFloatBE(24);
d.data.channelFadersDB[channel - 1] = convertToDBTheBehringerWay(buf.readFloatBE(24));
} else if (addr[0] === 'lr') {
d.data.stereoFader = buf.readFloatBE(20);
d.data.stereoFaderDB = convertToDBTheBehringerWay(buf.readFloatBE(20));
}
d.draw();
} else if (msg[0].includes('/mix/on')) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
if (addr[0] === 'ch') {
d.data.channelMutes[channel - 1] = buf[23];
} else if (addr[0] === 'lr') {
d.data.stereoMute = buf[19];
}
device.draw();
device.send(`/ch/${addr[1]}/mix/fader\x00\x00\x00\x00`);
} else if (msg[0].includes('/config/name')) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
d.data.channelNames[channel - 1] = msg[4];
d.draw();
d.send(`/ch/${addr[1]}/config/color\x00\x00\x00\x00`);
} else if (msg[0].includes('/config/color')) {
const addr = parseAddress(msg[0]);
const channel = Number(addr[1]);
d.data.channelColors[channel - 1] = buf.readInt8(27);
d.draw();
d.send(`/ch/${addr[1]}/mix/on\x00\x00\x00\x00`);
} else {
// console.log(msg)
}
// console.log(msg)
};
exports.heartbeat = function heartbeat(device) {
device.send('/xremote');
};