mirror of
https://github.com/stagehacks/Cue-View.git
synced 2026-08-09 15:53:38 +00:00
Merge pull request #3 from jwetzell/x32-cleanup
Mega Awesome X32 Improvements
This commit is contained in:
+135
-59
@@ -6,7 +6,7 @@ exports.searchOptions = {
|
||||
searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]),
|
||||
devicePort: 10023,
|
||||
listenPort: 0,
|
||||
validateResponse (msg, info) {
|
||||
validateResponse(msg, info) {
|
||||
return msg.toString().indexOf('/xinfo') === 0;
|
||||
},
|
||||
};
|
||||
@@ -14,21 +14,10 @@ exports.defaultPort = 10023;
|
||||
|
||||
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.data.X32 = new Console();
|
||||
|
||||
d.send(Buffer.from('/xinfo'));
|
||||
|
||||
// device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
|
||||
// device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
|
||||
|
||||
// device.send(Buffer.from("/subscribe\x00,si\x00/-stat/solosw/01\x001"));
|
||||
};
|
||||
|
||||
@@ -38,59 +27,75 @@ function parseAddress(msg) {
|
||||
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('\u0000\u0000');
|
||||
|
||||
// replace one or more nulls with new line then split on that
|
||||
const msg = buf.toString().replace(/(\0+)/gm, '\n').split('\n');
|
||||
|
||||
const d = device;
|
||||
|
||||
if (msg[0] === '/xinfo') {
|
||||
this.deviceInfoUpdate(device, 'defaultName', msg[4]);
|
||||
d.data.name = msg[4];
|
||||
d.data.ip = msg[2];
|
||||
d.data.firmware = msg[7];
|
||||
d.data.model = msg[5];
|
||||
d.data.X32.info.name = msg[3];
|
||||
d.data.X32.info.ip = msg[2];
|
||||
d.data.X32.info.firmware = msg[5];
|
||||
d.data.X32.info.model = msg[4];
|
||||
|
||||
d.send(Buffer.from('/lr/mix/fader\u0000\u0000\u0000\u0000'));
|
||||
d.send(Buffer.from('/lr/mix/on\u0000\u0000\u0000\u0000'));
|
||||
this.deviceInfoUpdate(device, 'defaultName', d.data.X32.info.name);
|
||||
|
||||
d.send(Buffer.from('/main/st/config/name\x00\x00\x00\x00'));
|
||||
|
||||
for (let i = 0; i <= 32; i++) {
|
||||
d.send(
|
||||
Buffer.from(
|
||||
`/ch/${i
|
||||
.toString()
|
||||
.padStart(2, '0')}/config/name\u0000\u0000\u0000\u0000`
|
||||
`/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('meters/0')) {
|
||||
let offset = 24;
|
||||
for (let i = 0; i < 70; i++) {
|
||||
if (i >= 0 && i < 32) {
|
||||
// These are channel meters
|
||||
d.data.X32.inputs.channels[i].meter = Console.getBehringerDB(
|
||||
buf.readFloatLE(offset)
|
||||
);
|
||||
}
|
||||
|
||||
offset += 4;
|
||||
}
|
||||
d.draw();
|
||||
} else if (msg[0].includes('meters/2')) {
|
||||
let offset = 24;
|
||||
|
||||
for (let i = 0; i < 49; i++) {
|
||||
if (i === 22) {
|
||||
// STEREO LEFT METER
|
||||
d.data.X32.main.stereo.meter[0] = Console.getBehringerDB(
|
||||
buf.readFloatLE(offset)
|
||||
);
|
||||
} else if (i === 23) {
|
||||
// STEREO RIGHT METER
|
||||
d.data.X32.main.stereo.meter[1] = Console.getBehringerDB(
|
||||
buf.readFloatLE(offset)
|
||||
);
|
||||
}
|
||||
offset += 4;
|
||||
}
|
||||
} else if (msg[0].indexOf('/mix/fader') >= 0) {
|
||||
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(
|
||||
d.data.X32.inputs.channels[channel - 1].fader = buf.readFloatBE(24);
|
||||
d.data.X32.inputs.channels[channel - 1].faderDB = Console.getBehringerDB(
|
||||
buf.readFloatBE(24)
|
||||
);
|
||||
} else if (addr[0] === 'lr') {
|
||||
d.data.stereoFader = buf.readFloatBE(20);
|
||||
d.data.stereoFaderDB = convertToDBTheBehringerWay(
|
||||
buf.readFloatBE(20)
|
||||
} else if (addr[0] === 'main') {
|
||||
d.data.X32.main.stereo.fader = buf.readFloatBE(24);
|
||||
d.data.X32.main.stereo.faderDB = Console.getBehringerDB(
|
||||
buf.readFloatBE(24)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -100,28 +105,40 @@ exports.data = function data(device, buf) {
|
||||
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];
|
||||
d.data.X32.inputs.channels[channel - 1].mute = buf[23];
|
||||
d.send(Buffer.from(`/ch/${addr[1]}/mix/fader\x00\x00\x00\x00`));
|
||||
} else if (addr[0] === 'main') {
|
||||
d.data.X32.main.stereo.mute = buf.slice(-1)[0];
|
||||
d.send(Buffer.from(`/main/${addr[1]}/mix/fader\x00\x00\x00\x00`));
|
||||
}
|
||||
d.draw();
|
||||
d.send(
|
||||
Buffer.from(`/ch/${addr[1]}/mix/fader\u0000\u0000\u0000\u0000`)
|
||||
);
|
||||
} else if (msg[0].indexOf('/config/name') > 0) {
|
||||
const addr = parseAddress(msg[0]);
|
||||
const channel = Number(addr[1]);
|
||||
d.data.channelNames[channel - 1] = msg[2];
|
||||
if (addr[0] === 'main') {
|
||||
if (addr[1] === 'st') {
|
||||
d.data.X32.main.stereo.name = msg[2];
|
||||
if (d.data.X32.main.stereo.name === '') {
|
||||
d.data.X32.main.stereo.name = 'LR';
|
||||
}
|
||||
d.send(Buffer.from(`/main/${addr[1]}/config/color\x00\x00\x00\x00`));
|
||||
}
|
||||
} else if (addr[0] === 'ch') {
|
||||
const channel = Number(addr[1]);
|
||||
d.data.X32.inputs.channels[channel - 1].name = msg[2];
|
||||
d.send(Buffer.from(`/ch/${addr[1]}/config/color\x00\x00\x00\x00`));
|
||||
}
|
||||
d.draw();
|
||||
d.send(
|
||||
Buffer.from(`/ch/${addr[1]}/config/color\u0000\u0000\u0000\u0000`)
|
||||
);
|
||||
} else if (msg[0].indexOf('/config/color') > 0) {
|
||||
const addr = parseAddress(msg[0]);
|
||||
const channel = Number(addr[1]);
|
||||
d.data.channelColors[channel - 1] = buf.readInt8(27);
|
||||
if (addr[0] === 'main') {
|
||||
d.data.X32.main.stereo.color = Buffer.from(msg[2]).readInt8();
|
||||
d.send(Buffer.from(`/main/${addr[1]}/mix/on\x00\x00\x00\x00`));
|
||||
} else if (addr[0] === 'ch') {
|
||||
const channel = Number(addr[1]);
|
||||
d.data.X32.inputs.channels[channel - 1].color = buf.readInt8(27);
|
||||
d.send(Buffer.from(`/ch/${addr[1]}/mix/on\x00\x00\x00\x00`));
|
||||
}
|
||||
d.draw();
|
||||
d.send(Buffer.from(`/ch/${addr[1]}/mix/on\u0000\u0000\u0000\u0000`));
|
||||
} else {
|
||||
// console.log(msg)
|
||||
}
|
||||
@@ -130,4 +147,63 @@ exports.data = function data(device, buf) {
|
||||
|
||||
exports.heartbeat = function heartbeat(device) {
|
||||
device.send(Buffer.from('/xremote'));
|
||||
|
||||
// subscribe to meter groups
|
||||
device.send(
|
||||
Buffer.from(
|
||||
'/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
|
||||
)
|
||||
);
|
||||
device.send(
|
||||
Buffer.from(
|
||||
'/batchsubscribe\x00,ssiii\x00\x00meters/2\x00\x00\x00\x00/meters/2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01'
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,3 +128,29 @@ input[type='range']::-webkit-slider-runnable-track {
|
||||
background: #3b3b3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.infin {
|
||||
font-size: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.meter {
|
||||
height: 3px;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(19, 126, 30, 1) 0%,
|
||||
rgba(255, 238, 30, 1) 85%,
|
||||
rgba(255, 0, 0, 1) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* need to find a way to match the color of this with the table row */
|
||||
.meter-cover {
|
||||
height: 100%;
|
||||
background-color: rgb(22, 23, 25);
|
||||
float: right;
|
||||
}
|
||||
|
||||
table.cv-table tr:nth-child(odd) td div.meter div.meter-cover {
|
||||
background-color: #292929;
|
||||
}
|
||||
|
||||
+23
-11
@@ -13,39 +13,51 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="40px">LR</td>
|
||||
<td width="100px"><div class="color color-8">MAIN OUT</div></td>
|
||||
<td><div class="fader-mute mute-<%=data.stereoMute%>">M</div></td>
|
||||
<td><%- formatAsDB(data.stereoFaderDB) %></td>
|
||||
<td width="100px"><div class="color color-<%= data.X32.main.stereo.color %>"><%- data.X32.main.stereo.name%></div></td>
|
||||
<td><div class="fader-mute mute-<%=data.X32.main.stereo.mute%>">M</div></td>
|
||||
<td><%= formatAsDB(data.X32.main.stereo.faderDB) %></td>
|
||||
<td>
|
||||
<% let style = `style=width:${Math.abs(data.X32.main.stereo.meter[0] - 10)}%`; %>
|
||||
<div class="meter">
|
||||
<div class="meter-cover" <%= style %>></div>
|
||||
</div>
|
||||
<% style = `style=width:${Math.abs(data.X32.main.stereo.meter[1] - 10)}%`; %>
|
||||
<div class="meter">
|
||||
<div class="meter-cover" <%= style %>></div>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value="<%= data.stereoFader*100 %>"
|
||||
value="<%= data.X32.main.stereo.fader*100 %>"
|
||||
disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<% for(var i=0; i<32; i++){ %> <% if(data.channelNames[i]=="end"){break;} %>
|
||||
<% for(var i=0; i<32; i++){ %> <% if(data.X32.inputs.channels[i].name == "end"){break;} %>
|
||||
<tr>
|
||||
<td><%= i+1 %></td>
|
||||
<td>
|
||||
<div class="color color-<%= data.channelColors[i] %>">
|
||||
<%- data.channelNames[i] || i+1 %>
|
||||
<div class="color color-<%= data.X32.inputs.channels[i].color %>">
|
||||
<%- data.X32.inputs.channels[i].name || i+1 %>
|
||||
</div>
|
||||
</td>
|
||||
<td><div class="fader-mute mute-<%=data.channelMutes[i]%>">M</div></td>
|
||||
<td><%- formatAsDB(data.channelFadersDB[i]) %></td>
|
||||
<td><div class="fader-mute mute-<%=data.X32.inputs.channels[i].mute%>">M</div></td>
|
||||
<td><%= formatAsDB(data.X32.inputs.channels[i].faderDB) %></td>
|
||||
<td>
|
||||
<% let style = `style=width:${Math.abs(data.X32.inputs.channels[i].meter - 10)}%`; %>
|
||||
<div class="meter">
|
||||
<div class="meter-cover" <%= style %>></div>
|
||||
</div>
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="100"
|
||||
value="<%= data.channelFaders[i]*100 %>"
|
||||
value="<%= data.X32.inputs.channels[i].fader*100 %>"
|
||||
disabled />
|
||||
</td>
|
||||
</tr>
|
||||
<% } %>
|
||||
</table>
|
||||
|
||||
<% function formatAsDB(val){ if(val==-90){ return "-∞"; } if(val>0){
|
||||
<% function formatAsDB(val){ if(val==-90){ return '-<span class="infin">∞</span>'; } if(val>0){
|
||||
return "+"+val.toFixed(1); } return val.toFixed(1); } %>
|
||||
|
||||
+9
-19
@@ -6,7 +6,7 @@ exports.searchOptions = {
|
||||
searchBuffer: Buffer.from([0x2f, 0x78, 0x69, 0x6e, 0x66, 0x6f]),
|
||||
devicePort: 10024,
|
||||
listenPort: 0,
|
||||
validateResponse (msg, info) {
|
||||
validateResponse(msg, info) {
|
||||
return msg.toString().indexOf('/xinfo') === 0;
|
||||
},
|
||||
};
|
||||
@@ -28,7 +28,6 @@ exports.ready = function ready(device) {
|
||||
|
||||
// device.send(Buffer.from("\x2f\x62\x61\x74\x63\x68\x73\x75\x62\x73\x63\x72\x69\x62\x65\x00\x2c\x73\x73\x69\x69\x69\x00\x00\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x2f\x6d\x65\x74\x65\x72\x73\x2f\x30\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
|
||||
// device.send(Buffer.from("/batchsubscribe\x00,ssiii\x00\x00meters/0\x00\x00\x00\x00/meters/0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"));
|
||||
|
||||
// device.send(Buffer.from("/subscribe\x00,si\x00/-stat/solosw/01\x001"));
|
||||
};
|
||||
|
||||
@@ -53,7 +52,7 @@ function convertToDBTheBehringerWay(f) {
|
||||
|
||||
exports.data = function data(device, buf) {
|
||||
this.deviceInfoUpdate(device, 'status', 'ok');
|
||||
const msg = buf.toString().split('\u0000');
|
||||
const msg = buf.toString().split('\x00');
|
||||
const d = device;
|
||||
|
||||
if (msg[0] === '/xinfo') {
|
||||
@@ -68,20 +67,17 @@ exports.data = function data(device, buf) {
|
||||
d.data.model = msg[9];
|
||||
this.deviceInfoUpdate(d, 'defaultName', d.data.name);
|
||||
|
||||
d.send('/lr/mix/fader\u0000\u0000\u0000\u0000');
|
||||
d.send('/lr/mix/on\u0000\u0000\u0000\u0000');
|
||||
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\u0000\u0000\u0000\u0000`
|
||||
`/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].indexOf('/mix/fader') >= 0) {
|
||||
@@ -95,13 +91,10 @@ exports.data = function data(device, buf) {
|
||||
);
|
||||
} else if (addr[0] === 'lr') {
|
||||
d.data.stereoFader = buf.readFloatBE(20);
|
||||
d.data.stereoFaderDB = convertToDBTheBehringerWay(
|
||||
buf.readFloatBE(20)
|
||||
);
|
||||
d.data.stereoFaderDB = convertToDBTheBehringerWay(buf.readFloatBE(20));
|
||||
}
|
||||
|
||||
d.draw();
|
||||
|
||||
} else if (msg[0].indexOf('/mix/on') >= 0) {
|
||||
const addr = parseAddress(msg[0]);
|
||||
const channel = Number(addr[1]);
|
||||
@@ -112,22 +105,19 @@ exports.data = function data(device, buf) {
|
||||
d.data.stereoMute = buf[19];
|
||||
}
|
||||
device.draw();
|
||||
device.send(`/ch/${addr[1]}/mix/fader\u0000\u0000\u0000\u0000`);
|
||||
|
||||
device.send(`/ch/${addr[1]}/mix/fader\x00\x00\x00\x00`);
|
||||
} else if (msg[0].indexOf('/config/name') > 0) {
|
||||
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\u0000\u0000\u0000\u0000`);
|
||||
|
||||
d.send(`/ch/${addr[1]}/config/color\x00\x00\x00\x00`);
|
||||
} else if (msg[0].indexOf('/config/color') > 0) {
|
||||
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\u0000\u0000\u0000\u0000`);
|
||||
|
||||
d.send(`/ch/${addr[1]}/mix/on\x00\x00\x00\x00`);
|
||||
} else {
|
||||
// console.log(msg)
|
||||
}
|
||||
|
||||
@@ -127,3 +127,8 @@ input[type='range']::-webkit-slider-runnable-track {
|
||||
background: #3b3b3b;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.infin{
|
||||
font-size: 20px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<td width="40px">LR</td>
|
||||
<td width="100px"><div class="color color-8">MAIN OUT</div></td>
|
||||
<td><div class="fader-mute mute-<%=data.stereoMute%>">M</div></td>
|
||||
<td><%- formatAsDB(data.stereoFaderDB) %></td>
|
||||
<td><%= formatAsDB(data.stereoFaderDB) %></td>
|
||||
<td>
|
||||
<input
|
||||
type="range"
|
||||
@@ -34,7 +34,7 @@
|
||||
</div>
|
||||
</td>
|
||||
<td><div class="fader-mute mute-<%=data.channelMutes[i]%>">M</div></td>
|
||||
<td><%- formatAsDB(data.channelFadersDB[i]) %></td>
|
||||
<td><%= formatAsDB(data.channelFadersDB[i]) %></td>
|
||||
<td>
|
||||
<input
|
||||
type="range"
|
||||
@@ -47,5 +47,5 @@
|
||||
<% } %>
|
||||
</table>
|
||||
|
||||
<% function formatAsDB(val){ if(val==-90){ return "-∞"; } if(val>0){
|
||||
<% function formatAsDB(val){ if(val==-90){ return '-<span class="infin">∞</span>'; } if(val>0){
|
||||
return "+"+val.toFixed(1); } return val.toFixed(1); } %>
|
||||
|
||||
Reference in New Issue
Block a user