Files
2023-06-23 03:23:10 -04:00

200 lines
5.5 KiB
JavaScript

exports.config = {
defaultName: 'X32 Mixer',
connectionType: 'osc-udp',
remotePort: 10023,
mayChangePorts: false,
heartbeatInterval: 9000,
heartbeatTimeout: 11000,
searchOptions: {
type: 'UDPsocket',
searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]),
devicePort: 10023,
listenPort: 0,
validateResponse(msg, info) {
return msg.toString().includes('/xinfo');
},
},
};
exports.ready = function ready(_device) {
const device = _device;
device.data = new Console();
device.send('/xinfo');
device.send('/batchsubscribe', [
{ type: 's', value: '/ch/meters' },
{ type: 's', value: '/meters/0' },
{ type: 'i', value: 0 },
{ type: 'i', value: 0 },
{ type: 'i', value: 1 },
]);
device.send('/batchsubscribe', [
{ type: 's', value: '/main/meters' },
{ type: 's', value: '/meters/2' },
{ type: 'i', value: 0 },
{ type: 'i', value: 0 },
{ type: 'i', value: 1 },
]);
};
function parseAddress(msg) {
const addr = msg.split('/');
addr.shift();
return addr;
}
exports.data = function data(_device, oscData) {
this.deviceInfoUpdate(_device, 'status', 'ok');
const device = _device;
if (oscData.address === '/xinfo') {
device.data.info.name = oscData.args[1];
device.data.info.ip = oscData.args[0];
device.data.info.firmware = oscData.args[3];
device.data.info.model = oscData.args[2];
this.deviceInfoUpdate(_device, 'defaultName', device.data.info.name);
device.send('/main/st/config/name');
for (let i = 0; i <= 32; i++) {
device.send(`/ch/${i.toString().padStart(2, '0')}/config/name`);
}
device.draw();
} else if (oscData.address.includes('/ch/meters')) {
const buf = Buffer.from(oscData.args[0]);
let offset = 4; // skip first 4 bytes they are the length bytes
for (let i = 0; i < 70; i++) {
if (i >= 0 && i < 32) {
// These are channel meters
device.data.inputs.channels[i].meter = Console.getBehringerDB(buf.readFloatLE(offset));
}
offset += 4;
}
device.draw();
} else if (oscData.address.includes('/main/meters')) {
const buf = Buffer.from(oscData.args[0]);
let offset = 4; // skip first 4 bytes they are the length bytes
for (let i = 0; i < 49; i++) {
if (i === 22) {
// STEREO LEFT METER
device.data.main.stereo.meter[0] = Console.getBehringerDB(buf.readFloatLE(offset));
} else if (i === 23) {
// STEREO RIGHT METER
device.data.main.stereo.meter[1] = Console.getBehringerDB(buf.readFloatLE(offset));
}
offset += 4;
}
} else if (oscData.address.includes('/mix/fader')) {
const addr = parseAddress(oscData.address);
if (addr[0] === 'ch') {
const channel = Number(addr[1]);
device.data.inputs.channels[channel - 1].fader = oscData.args[0];
device.data.inputs.channels[channel - 1].faderDB = Console.getBehringerDB(oscData.args[0]);
} else if (addr[0] === 'main') {
device.data.main.stereo.fader = oscData.args[0];
device.data.main.stereo.faderDB = Console.getBehringerDB(oscData.args[0]);
}
device.draw();
} else if (oscData.address.includes('/mix/on')) {
const addr = parseAddress(oscData.address);
if (addr[0] === 'ch') {
const channel = Number(addr[1]);
device.data.inputs.channels[channel - 1].mute = oscData.args[0];
device.send(`/ch/${addr[1]}/mix/fader`);
} else if (addr[0] === 'main') {
device.data.main.stereo.mute = oscData.args[0];
device.send(`/main/${addr[1]}/mix/fader`);
}
device.draw();
} else if (oscData.address.includes('/config/name')) {
const addr = parseAddress(oscData.address);
if (addr[0] === 'main') {
if (addr[1] === 'st') {
device.data.main.stereo.name = oscData.args[0];
if (device.data.main.stereo.name === '') {
device.data.main.stereo.name = 'LR';
}
device.send(`/main/${addr[1]}/config/color`);
}
} else if (addr[0] === 'ch') {
const channel = Number(addr[1]);
device.data.inputs.channels[channel - 1].name = oscData.args[0];
device.send(`/ch/${addr[1]}/config/color`);
}
device.draw();
} else if (oscData.address.includes('/config/color')) {
const addr = parseAddress(oscData.address);
if (addr[0] === 'main') {
device.data.main.stereo.color = oscData.args[0];
device.send(`/main/${addr[1]}/mix/on`);
} else if (addr[0] === 'ch') {
const channel = Number(addr[1]);
device.data.inputs.channels[channel - 1].color = oscData.args[0];
device.send(`/ch/${addr[1]}/mix/on`);
}
device.draw();
}
};
exports.heartbeat = function heartbeat(device) {
device.send('/xremote');
device.send('/renew', [{ type: 's', value: '/ch/meters' }]);
device.send('/renew', [{ type: 's', value: '/main/meters' }]);
};
class Console {
constructor() {
this.inputs = {
channels: new Array(32).fill(0).map(() => ({
fader: 0,
faderDB: 0,
mute: 0,
name: 'end',
color: undefined,
meter: -90,
})),
};
this.main = {
stereo: {
fader: 0,
faderDB: 0,
mute: 0,
name: 'LR',
color: 7,
meter: new Array(2).fill(-90),
},
};
this.info = {
name: '',
ip: '',
firmware: '',
model: '',
};
}
static getBehringerDB(level) {
const f = level;
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;
}
}