logo of blechtrottel.net blechtrottel.net
deutsch

Websockets and Soundcraft

Part 3

Javascript Websockets for Soundcraft UI Mixers

Introduction

The second part of these instructions dealt with controlling the mixer via Javascript. This works well, but we cannot say for sure if all commands were executed by the mixer. The changes in the info field come from the javascript in our page. New information Soundcraft UI only sends when the page reloads and thus establishes a new websocket connection.

To get the updated settings without reloading the page, you have to read http://10.10.1.1/js/initparams.js (10.10.1.1 is the ip address of the mixer when it uses its own wlan, you may have to adjust it.)

Let's write a new function.

function getParams() { dataValue = {}; activeChs = ''; fetch("http://10.10.1.1/js/initparams.js", { cache: 'no-cache', }) .then(initparams => { return(initparams.text()); })

The first lines of this function get the file from the server; the option cache: 'no-cache' makes sure that the file gets downloaded anew every time. After that we return the contents of initparams.js as text.

Out of these we take the part from dataValue= to the closing curly bracket. Both the beginning and an eventual , before that bracket get deleted. The result is turned into our own JSON object named dataValue.

.then(txt => { dV = txt.match(/dataValue.*\}/)[0]; dV = dV.replace('dataValue=', ''); dV = dV.replace(',}', '}'); dataValue = JSON.parse(dV); })

We use a forEach loop to read the mute state for every instrument from dataValue, save it in a text variable named activeChs and print it into our info field.

.then(() => { instruments.forEach((instrument, iid) => { mute = dataValue["i." + iid + ".mute"]; activeChs += mute; mutestate = (mute == '0') ? "on" : "off"; info.innerHTML += "Channel " + (iid*1+1) + ": " + instrument + " " + mutestate + "<br>"; }) })

The last step consists of checking whether the order of the mute settings in activeChs corresponds to that of one of the buttons and, if yes, changing its colour.

.then(() => { if (activeChs == '0011' || activeChs == '1100') { buttons[activeChs.substr(0,1)].classList.add('active'); } });

Our function changeInstruments() from the second part of these instructions can be changed so that, after pressing one of the buttons, it checks and displays the results by calling new function getParams().

function changeInstruments(chls) { info.innerHTML = ''; buttons.forEach(button => { button.classList.remove('active'); }); if (socket.readyState == 1) { chls = chls.match(/\d+/g); instruments.forEach((instrument, iid) => { mute = ((iid == chls[0]-1) || (iid == chls[1]-1)) ? 0 : 1; socket.send('3:::SETD^i.' + iid + '.mute^' + mute); }); getParams(); } else { console.log("No connection to server."); } }

CORS

The file initparams.js lies on a different server than our javascript. This therefore leads to access problems that keep us from downloading and reading it. But for most browsers there is some addon that can be used to make the browser ignore these header settings. Not all of these addons allow you to use your own local file in the format file://websocketsui.html.

In Firefox CORS Everywhere worked good in tests. For Android there is an adapted version named CORS for ME.

Download

If you want to test this code but do not want to write it all yourself, you can download this file.

Part 1 - Part 2 - Part 3