websockets und Soundcraft
1. teil
vorbemerkung
Die digitalen mixer der Soundcraft UI-familie werden praktischerweise nicht über eine spezielle app gesteuert, sondern durch aufruf der bedienoberfläche in einem webbrowser. Der mixer übernimmt dabei die funktion eines webservers. Somit braucht man sich keine sorgen darüber zu machen, welches gerät man zur bedienung verwendet bzw. welches betriebssystem in welcher version darauf läuft. Es muss nur einen browser haben und HTML5 beherrschen.
Browser und mixer unterhalten sich dabei über websockets. Da das eine standardisierte kommunikationsmethode ist, kann man auch ohne die eingebaute bedienoberfläche mit dem mixer reden. Viele anleitungen im netz verwenden dazu extra pakete und programme, es geht aber durchaus auch mit reinem Javascript. Die ersten schritte dazu wird diese anleitung zeigen.
html
Also basteln wir vorerst eine einfache webseite, in der unser Javascript laufen wird:
<!doctype html>
<head>
<meta charset="utf-8">
<title>JS-Websockets Soundcraft UI</title>
</head>
<body>
<h1>Websockets für Soundcraft UI in Javascript</h1>
<h2>Kanäle</h2>
<p id="info" style="min-height:10em;">
</p>
<script type="text/javascript">
<script>
</body>
</html>
Diese simple grundgerüst enthält einen absatz info, in dem wir information vom mixer darstellen wollen. Darunter werden wir unser Javascript einfügen.
javascript
Zuerst rufen wir den mixer über seine ip-adresse auf. In diesem beispiel ist es die adresse, die er bekommt, wenn wir das wlan des mixers verwenden. Wer ihn in ein bestehendes netzwerk integriert, muss die adresse entsprechend ändern.
const socket = new WebSocket("ws://10.10.1.1:80");
Danach beginnen wir, auf nachrichten zu reagieren und auch gleich eine zu senden.
z = 0;
socket.onmessage = function(event) {
if (z == 80) {
socket.send("3:::ALIVE");
z = 0;
} else {
z++;
}
}
Wenn der mixer nicht regelmäßig die meldung 3:::ALIVE bekommt, beendet er die verbindung. Man könnte dazu eine zeitbasierte schleife schreiben, hier wird auf 80 empfangene nachrichten gewartet, das funktioniert genauso.
Ans ende hängen wir noch funktionen, um bei fehlern bzw abbruch der verbindung eine meldung in die konsole zu bekommen:
socket.onclose = function(event) {
console.log("Verbindung getrennt.");
};
socket.onerror = function(error) {
if (error.message == undefined && socket.readyState == 3) {
console.log("Keine Verbindung hergestellt.");
}
else {
console.log("[Error] " + error.message);
}
};
Jetzt erweitern wir den anfang des codes und definieren zu beginn instrumente für die ersten vier kanäle, damit unser beispiel ein wenig realistischer wird. Dann bearbeiten wir die empfangenen daten.
var instrumente = ["Klavier", "Mikro 1", "Gitarre", "Mikro 2"];
var channels = [];
socket.onmessage = function(event) {
if (z == 80) {
socket.send("3:::ALIVE");
z = 0;
} else {
z++;
}
received = event.data;
console.log("RECEIVED");
receivedZeilen = received.split(/\r?\n/g);
receivedZeilen.forEach(zeile => {
if (zeile == '2::') {
socket.send(zeile);
}
else if (zeile.search(/SETD\^i\.\d?\.mute/) > -1) {
zeile = zeile.replace('3:::', '');
ints = zeile.match(/\d+/g);
if (ints[0] < 4) {
channels[ints[0]] = ints[1];
kanalstatus = (ints[1] == 0) ? "ein" : "aus";
info = document.getElementById('info');
info.innerHTML += instrumente[ints[0]] + " " + kanalstatus + " - RECEIVED: " + zeile + "<br>";
}
}
});
};
Die empfangenen meldungen werden an den zeilenenden getrennt received.split(/\r?\n/g) und zeile für zeile bearbeitet. Die originale bedienoberfläche des Soundcraft UI beantwortet jede zeile 2::: mit genau derselben meldung (Ping-Pong). Wir bilden das hier nach, obwohl es nicht unbedingt notwendig ist. Wie erwähnt wird die verbindung über 3:::ALIVE aufrecht erhalten.
Für dieses beispiel suchen wir dann in allen anderen zeilen nach den mute-einstellungen für die ersten vier kanäle. Die einstellungen kommen vom mixer in der form SETDi.0.mute.0 Dabei ist i.0 kanal 1 (input) in computerzählweise und mute.0 beschreibt den status der mutetaste. Ist er 0, dann ist sie nicht gedrückt, der kanal ist also aktiv.
Uns interessieren diese beiden zahlen in der meldung. Wir entfernen zuerst den beginn der zeile zeile = zeile.replace('3:::', '');, weil dort auch eine ziffer zu finden ist. Dann ermitteln wir die zahlen ints = zeile.match(/\d+/g); Das array enthält also immer zwei elemente, die kanalnummer und den mutestatus.
Danach können wir für die vier angenommenen kanäle den einstatus ermitteln, der umgekehrt zum mutestatus ist. Daraus wird dann (samt originalmeldung vom mixer) ein eintrag im absatz info ausgeben.
download
Wer dieses beispiel gerne selbst ausprobieren möchte, aber keine lust zum abtippen hat, kann diese datei herunterladen.
ausblick
In einem nächsten teil wollen wir uns anschauen, wie wir diese einstellungen auch ändern können.