summaryrefslogtreecommitdiff
path: root/share/web_surfaces/shared
diff options
context:
space:
mode:
authorLuciano Iam <lucianito@gmail.com>2020-04-14 09:53:25 +0200
committerRobin Gareus <robin@gareus.org>2020-04-17 20:15:10 +0200
commit2ba8dab95e10596ac88539a74e47024836138019 (patch)
tree77e96abf8eee3767804476a1f0fa4df655effc23 /share/web_surfaces/shared
parentb9674115b7d3780164ed30e4151984de78b904e7 (diff)
WebSockets: update JS client and demo
avoid hardcoded node name strings in mixer-demo improve mixer-demo design split ardour.js client into control and metadata mixins rename JS client class Ardour to ArdourClient JS client improve mixin implementation JS client improve manifest parser NO-OP whitespace and comments NO-OP update websurface manifest versions add Ardour icon in mixer-demo improve mixer-demo scrolling on touch screens
Diffstat (limited to 'share/web_surfaces/shared')
-rw-r--r--share/web_surfaces/shared/ardour.js102
-rw-r--r--share/web_surfaces/shared/callback.js2
-rw-r--r--share/web_surfaces/shared/control.js73
-rw-r--r--share/web_surfaces/shared/metadata.js51
4 files changed, 146 insertions, 82 deletions
diff --git a/share/web_surfaces/shared/ardour.js b/share/web_surfaces/shared/ardour.js
index 77e6bf49b9..a7e6978ba2 100644
--- a/share/web_surfaces/shared/ardour.js
+++ b/share/web_surfaces/shared/ardour.js
@@ -16,10 +16,14 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-import { ANode, Message } from './message.js';
+import { MetadataMixin } from './metadata.js';
+import { ControlMixin } from './control.js';
+import { Message } from './message.js';
import { MessageChannel } from './channel.js';
-export class Ardour {
+// See *Mixin for the available APIs
+
+class BaseArdourClient {
constructor () {
this._callbacks = [];
@@ -56,90 +60,11 @@ export class Ardour {
this._channel.send(msg);
}
- // Surface metadata API over HTTP
-
- async getAvailableSurfaces () {
- const response = await fetch('/surfaces.json');
-
- if (response.status == 200) {
- return await response.json();
- } else {
- throw this._fetchResponseStatusError(response.status);
- }
- }
-
- async getSurfaceManifest () {
- const response = await fetch('manifest.xml');
-
- if (response.status == 200) {
- const xmlText = await response.text();
- const xmlDoc = new DOMParser().parseFromString(xmlText, 'text/xml');
- return {
- name: xmlDoc.getElementsByTagName('Name')[0].getAttribute('value'),
- description: xmlDoc.getElementsByTagName('Description')[0].getAttribute('value'),
- version: xmlDoc.getElementsByTagName('Version')[0].getAttribute('value')
- }
- } else {
- throw this._fetchResponseStatusError(response.status);
- }
- }
-
- // Surface control API over WebSockets
- // clients need to call open() before calling these methods
-
- async getTempo () {
- return (await this._sendAndReceive(ANode.TEMPO))[0];
- }
-
- async getStripGain (stripId) {
- return (await this._sendAndReceive(ANode.STRIP_GAIN, [stripId]))[0];
- }
-
- async getStripPan (stripId) {
- return (await this._sendAndReceive(ANode.STRIP_PAN, [stripId]))[0];
- }
-
- async getStripMute (stripId) {
- return (await this._sendAndReceive(ANode.STRIP_MUTE, [stripId]))[0];
- }
-
- async getStripPluginEnable (stripId, pluginId) {
- return (await this._sendAndReceive(ANode.STRIP_PLUGIN_ENABLE, [stripId, pluginId]))[0];
- }
-
- async getStripPluginParamValue (stripId, pluginId, paramId) {
- return (await this._sendAndReceive(ANode.STRIP_PLUGIN_PARAM_VALUE, [stripId, pluginId, paramId]))[0];
- }
-
- setTempo (bpm) {
- this._send(ANode.TEMPO, [], [bpm]);
- }
-
- setStripGain (stripId, db) {
- this._send(ANode.STRIP_GAIN, [stripId], [db]);
- }
-
- setStripPan (stripId, value) {
- this._send(ANode.STRIP_PAN, [stripId], [value]);
- }
-
- setStripMute (stripId, value) {
- this._send(ANode.STRIP_MUTE, [stripId], [value]);
- }
-
- setStripPluginEnable (stripId, pluginId, value) {
- this._send(ANode.STRIP_PLUGIN_ENABLE, [stripId, pluginId], [value]);
- }
-
- setStripPluginParamValue (stripId, pluginId, paramId, value) {
- this._send(ANode.STRIP_PLUGIN_PARAM_VALUE, [stripId, pluginId, paramId], [value]);
- }
-
// Private methods
_send (node, addr, val) {
const msg = new Message(node, addr, val);
- this._channel.send(msg);
+ this.send(msg);
return msg;
}
@@ -178,3 +103,16 @@ export class Ardour {
}
}
+
+export class ArdourClient extends mixin(BaseArdourClient, ControlMixin, MetadataMixin) {}
+
+function mixin (dstClass, ...classes) {
+ for (const srcClass of classes) {
+ for (const methName of Object.getOwnPropertyNames(srcClass.prototype)) {
+ if (methName != 'constructor') {
+ dstClass.prototype[methName] = srcClass.prototype[methName];
+ }
+ }
+ }
+ return dstClass;
+}
diff --git a/share/web_surfaces/shared/callback.js b/share/web_surfaces/shared/callback.js
index 1328f49ffb..a510b118cf 100644
--- a/share/web_surfaces/shared/callback.js
+++ b/share/web_surfaces/shared/callback.js
@@ -16,6 +16,8 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+ // Example empty callback
+
export class ArdourCallback {
onTempo (bpm) {}
diff --git a/share/web_surfaces/shared/control.js b/share/web_surfaces/shared/control.js
new file mode 100644
index 0000000000..19116bf4c7
--- /dev/null
+++ b/share/web_surfaces/shared/control.js
@@ -0,0 +1,73 @@
+/*
+ * Copyright © 2020 Luciano Iam <lucianito@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+import { ANode } from './message.js';
+
+// Surface control API over WebSockets
+
+export class ControlMixin {
+
+ async getTempo () {
+ return (await this._sendAndReceive(ANode.TEMPO))[0];
+ }
+
+ async getStripGain (stripId) {
+ return (await this._sendAndReceive(ANode.STRIP_GAIN, [stripId]))[0];
+ }
+
+ async getStripPan (stripId) {
+ return (await this._sendAndReceive(ANode.STRIP_PAN, [stripId]))[0];
+ }
+
+ async getStripMute (stripId) {
+ return (await this._sendAndReceive(ANode.STRIP_MUTE, [stripId]))[0];
+ }
+
+ async getStripPluginEnable (stripId, pluginId) {
+ return (await this._sendAndReceive(ANode.STRIP_PLUGIN_ENABLE, [stripId, pluginId]))[0];
+ }
+
+ async getStripPluginParamValue (stripId, pluginId, paramId) {
+ return (await this._sendAndReceive(ANode.STRIP_PLUGIN_PARAM_VALUE, [stripId, pluginId, paramId]))[0];
+ }
+
+ setTempo (bpm) {
+ this._send(ANode.TEMPO, [], [bpm]);
+ }
+
+ setStripGain (stripId, db) {
+ this._send(ANode.STRIP_GAIN, [stripId], [db]);
+ }
+
+ setStripPan (stripId, value) {
+ this._send(ANode.STRIP_PAN, [stripId], [value]);
+ }
+
+ setStripMute (stripId, value) {
+ this._send(ANode.STRIP_MUTE, [stripId], [value]);
+ }
+
+ setStripPluginEnable (stripId, pluginId, value) {
+ this._send(ANode.STRIP_PLUGIN_ENABLE, [stripId, pluginId], [value]);
+ }
+
+ setStripPluginParamValue (stripId, pluginId, paramId, value) {
+ this._send(ANode.STRIP_PLUGIN_PARAM_VALUE, [stripId, pluginId, paramId], [value]);
+ }
+
+}
diff --git a/share/web_surfaces/shared/metadata.js b/share/web_surfaces/shared/metadata.js
new file mode 100644
index 0000000000..888476c681
--- /dev/null
+++ b/share/web_surfaces/shared/metadata.js
@@ -0,0 +1,51 @@
+/*
+ * Copyright © 2020 Luciano Iam <lucianito@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+// Surface metadata API over HTTP
+
+export class MetadataMixin {
+
+ async getAvailableSurfaces () {
+ const response = await fetch('/surfaces.json');
+
+ if (response.status == 200) {
+ return await response.json();
+ } else {
+ throw this._fetchResponseStatusError(response.status);
+ }
+ }
+
+ async getSurfaceManifest () {
+ const response = await fetch('manifest.xml');
+
+ if (response.status == 200) {
+ const manifest = {};
+ const xmlText = await response.text();
+ const xmlDoc = new DOMParser().parseFromString(xmlText, 'text/xml');
+
+ for (const child of xmlDoc.children[0].children) {
+ manifest[child.tagName.toLowerCase()] = child.getAttribute('value');
+ }
+
+ return manifest;
+ } else {
+ throw this._fetchResponseStatusError(response.status);
+ }
+ }
+
+}