mirror of
https://github.com/stagehacks/Cue-View.git
synced 2026-07-26 09:18:39 +00:00
193 lines
6.5 KiB
JavaScript
193 lines
6.5 KiB
JavaScript
const _ = require('lodash');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
exports.config = {
|
|
defaultName: 'DiGiCo SD',
|
|
connectionType: 'osc-udp',
|
|
remotePort: 8000,
|
|
localPort: 8001,
|
|
mayChangePorts: true,
|
|
heartbeatInterval: 2000,
|
|
heartbeatTimeout: 11000,
|
|
searchOptions: {
|
|
type: 'UDPsocket',
|
|
// send "/Console/Name/?" this is what the iPad sends to check connection
|
|
searchBuffer: Buffer.from([
|
|
0x2f, 0x43, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x2f, 0x4e, 0x61, 0x6d, 0x65, 0x2f, 0x3f, 0x00, 0x2c, 0x00, 0x00,
|
|
0x00,
|
|
]),
|
|
devicePort: 8000,
|
|
listenPort: 9000,
|
|
validateResponse(msg, info) {
|
|
console.log(msg);
|
|
console.log(msg.toString());
|
|
return msg.toString().includes('/Console');
|
|
},
|
|
},
|
|
};
|
|
|
|
exports.ready = function ready(_device) {
|
|
const device = _device;
|
|
device.data = new DiGiCo();
|
|
|
|
device.send('/Console/Name/?');
|
|
device.send('/Console/Session/Filename/?');
|
|
device.send('/Console/Channels/?');
|
|
device.send('/Snapshots/Current_Snapshot/?');
|
|
device.send('/Meters/clear');
|
|
};
|
|
exports.data = function data(_device, oscData) {
|
|
const device = _device;
|
|
this.deviceInfoUpdate(device, 'status', 'ok');
|
|
|
|
const properties = oscData.address.split('/');
|
|
properties.shift();
|
|
|
|
if (properties[0] !== 'Meters') {
|
|
setObjectProperty(device.data, properties, oscData.args);
|
|
// console.log(properties);
|
|
}
|
|
|
|
if (properties[0] === 'Console' && properties[1] === 'Control_Groups') {
|
|
for (let i = 1; i <= device.data.Console.Control_Groups; i++) {
|
|
device.send(`/Control_Groups/${i}/?`);
|
|
}
|
|
device.draw();
|
|
} else if (properties[0] === 'Console' && properties[1] === 'Input_Channels') {
|
|
for (let i = 1; i <= device.data.Console.Input_Channels; i++) {
|
|
device.send(`/Input_Channels/${i}/Channel_Input/name/?`);
|
|
device.send(`/Input_Channels/${i}/mute/?`);
|
|
device.send(`/Input_Channels/${i}/solo/?`);
|
|
device.send(`/Input_Channels/${i}/fader/?`);
|
|
device.send(`/Meters/request/1${i}`, [
|
|
{ type: 's', value: `/Input_Channels/${i}/Channel_Input/post_meter/left` },
|
|
]);
|
|
}
|
|
device.draw();
|
|
} else if (properties[0] === 'Console' && properties[1] === 'Group_Outputs') {
|
|
for (let i = 1; i <= device.data.Console.Group_Outputs; i++) {
|
|
device.send(`/Group_Outputs/${i}/mute/?`);
|
|
device.send(`/Group_Outputs/${i}/solo/?`);
|
|
device.send(`/Group_Outputs/${i}/fader/?`);
|
|
device.send(`/Group_Outputs/${i}/Buss_Trim/name/?`);
|
|
device.send(`/Meters/request/3${i}`, [{ type: 's', value: `/Group_Outputs/${i}/fader_meter/left` }]);
|
|
}
|
|
device.draw();
|
|
} else if (properties[0] === 'Console' && properties[1] === 'Aux_Outputs') {
|
|
for (let i = 1; i <= device.data.Console.Aux_Outputs; i++) {
|
|
device.send(`/Aux_Outputs/${i}/mute/?`);
|
|
device.send(`/Aux_Outputs/${i}/solo/?`);
|
|
device.send(`/Aux_Outputs/${i}/fader/?`);
|
|
device.send(`/Aux_Outputs/${i}/Buss_Trim/name/?`);
|
|
device.send(`/Meters/request/4${i}`, [{ type: 's', value: `/Aux_Outputs/${i}/fader_meter/left` }]);
|
|
}
|
|
device.draw();
|
|
} else if (properties[0] === 'Console' && properties[1] === 'Name') {
|
|
this.deviceInfoUpdate(device, 'defaultName', device.data.Console.Name);
|
|
} else if (['Control_Groups', 'Input_Channels', 'Group_Outputs', 'Aux_Outputs'].includes(properties[0])) {
|
|
device.update('fader', {
|
|
type: properties[0],
|
|
channel: properties[1],
|
|
});
|
|
} else if (properties[0] === 'Snapshots') {
|
|
device.update('updateSnapshot', {
|
|
snapshots: device.data.Snapshots,
|
|
});
|
|
} else if (properties[0] === 'Meters' && properties[1] === 'values') {
|
|
for (let i = 0; i < oscData.args.length; i += 2) {
|
|
const channelType = oscData.args[i].toString()[0];
|
|
const channelNumber = oscData.args[i].toString().substring(1);
|
|
const meterValue = BigInt(oscData.args[i + 1]) / -40000n + 100n;
|
|
|
|
if (channelType === '1' && device.data.Input_Channels[channelNumber]) {
|
|
device.data.Input_Channels[channelNumber].meter = meterValue;
|
|
device.update('fader', {
|
|
type: 'Input_Channels',
|
|
channel: channelNumber,
|
|
});
|
|
} else if (channelType === '3' && device.data.Group_Outputs[channelNumber]) {
|
|
device.data.Group_Outputs[channelNumber].meter = meterValue;
|
|
device.update('fader', {
|
|
type: 'Group_Outputs',
|
|
channel: channelNumber,
|
|
});
|
|
} else if (channelType === '4' && device.data.Aux_Outputs[channelNumber]) {
|
|
device.data.Aux_Outputs[channelNumber].meter = meterValue;
|
|
device.update('fader', {
|
|
type: 'Aux_Outputs',
|
|
channel: channelNumber,
|
|
});
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
exports.heartbeat = function heartbeat(device) {
|
|
device.send('/Console/Name/?');
|
|
console.log(device.data);
|
|
|
|
// Need to do a /Meters/clear when quitting Cue View or closing the View
|
|
};
|
|
|
|
class DiGiCo {
|
|
constructor() {
|
|
this.Console = {};
|
|
this.Input_Channels = {};
|
|
this.Aux_Outputs = {};
|
|
this.Control_Groups = {};
|
|
this.Group_Outputs = {};
|
|
this.Matrix_Outputs = {};
|
|
this.Layout = {};
|
|
}
|
|
}
|
|
|
|
/*
|
|
This function takes somethings like this /Console/Session/Filename with a osc args like ['session.ses']
|
|
and turns it into a nested object like. An easy way to set properties converting OSC paths to properties
|
|
{
|
|
Console: {
|
|
Session: {
|
|
Filename: 'session.ses'
|
|
}
|
|
}
|
|
}
|
|
|
|
*/
|
|
function setObjectProperty(_object, _properties, value) {
|
|
let object = _object;
|
|
const properties = _properties;
|
|
|
|
for (let i = 0; i < properties.length - 1; i++) {
|
|
const property = properties[i];
|
|
if (object[property] === undefined) {
|
|
object[property] = {};
|
|
}
|
|
object = object[property];
|
|
}
|
|
const property = properties[properties.length - 1];
|
|
if (Array.isArray(value)) {
|
|
// if this is an array of length one just set the property to the contents so ['string'] becomes 'string'
|
|
if (value.length === 1) {
|
|
object[property] = value[0];
|
|
return;
|
|
}
|
|
}
|
|
object[property] = value;
|
|
}
|
|
|
|
const faderTemplate = _.template(fs.readFileSync(path.join(__dirname, `/fader.ejs`)));
|
|
exports.update = function update(device, doc, updateType, data) {
|
|
if (updateType === 'fader') {
|
|
const $elem = doc.getElementById(`${data.type}-${data.channel}`);
|
|
$elem.outerHTML = faderTemplate({
|
|
type: data.type,
|
|
fader: device.data[data.type][data.channel],
|
|
index: data.channel,
|
|
});
|
|
} else if (updateType === 'snapshot') {
|
|
const $elem = doc.getElementById(`snapshot`);
|
|
$elem.textContent = `${data.snapshots.Current_Snapshot}`;
|
|
}
|
|
};
|