UNPKG

gibberwocky

Version:

music sequencing for Live and Max/MSP

295 lines (227 loc) 7.13 kB
<html> <head> <style> html, body { height: 100%; width: 100%; padding: 0px; margin: 0px; color:#000; font-size: 10; overflow:auto; font-family: monospace; } .post { white-space: -moz-pre-wrap; /* Firefox 1.0-2.0 */ white-space: pre-wrap; /* current browsers */ } </style> </head> <body> <b id="play"></b> <b id="bpm"></b> bpm <b id="signature"></b> <b id="bar"></b> <b id="beat"></b> <b id="connection"></b> <div id="send"></div> <div id="post"></div> <script> ///// utils ///// // get url args: var querystring = (function() { var qstr = window.location.search; var query = {}; var a = qstr.substr(1).split('&'); for (var i = 0; i < a.length; i++) { var b = a[i].split('='); query[decodeURIComponent(b[0])] = decodeURIComponent(b[1] || ''); } return query; })(); // debug messaging: function post(msg) { document.getElementById("post").innerHTML += msg + "<br>"; //console.log(msg); } // randoms function random(n) { return Math.floor(Math.random()*n); } function pick(arr) { return arr[random(arr.length)]; } ///// websocket ///// var wsocket; var connected = false; var connectTask; var track = querystring.track || 0; function ws_connect() { if (connected) { if (connectTask != undefined) { clearInterval(connectTask); connectTask = undefined; } } if ('WebSocket' in window) { var host = querystring.host || "localhost"; var port = querystring.port || "8081"; var address = "ws://" + host + ":" + port; document.getElementById("connection").innerHTML = 'connecting to ' + address; wsocket = new WebSocket(address); wsocket.onopen = function(ev) { document.getElementById("connection").innerHTML = 'connected to ' + address; connected = true; // cancel the auto-reconnect task: if (connectTask != undefined) clearInterval(connectTask); connectTask = undefined; // handshake send("get_scene"); }; wsocket.onclose = function(ev) { document.getElementById("connection").innerHTML = 'disconnected from ' + address; connected = false; // set up an auto-reconnect task: if (connectTask != undefined) connectTask = setInterval(ws_connect, 4000); }; wsocket.onmessage = function(ev) { handlemessage(ev.data); }; wsocket.onerror = function(ev) { post("WebSocket error"); }; } else { post("WebSockets are not available in this browser!!!"); } } function send(msg) { if(wsocket != undefined) wsocket.send(msg); document.getElementById("send").innerHTML = msg; } var lom = {}; var gens = []; function handlemessage(msg) { if (msg.charAt(0) == "{") { lom = JSON.parse(msg); post("received object"); console.log(lom); // clear memory: gens = []; // set up the globals: document.getElementById("bar").innerHTML = lom.bar; document.getElementById("beat").innerHTML = lom.bit; document.getElementById("signature").innerHTML = lom.sig; document.getElementById("bpm").innerHTML = lom.bpm; document.getElementById("play").innerHTML = lom.ply; } else { var parts = msg.split(" "); var track = parts[0]; // or search for first device with midi_input == 1 // subsequent devices are effects var device = pick(lom.tracks[track].devices); var cmd = parts[1]; var arg = parts[2]; if (cmd == "seq") { var beat = +arg; // demo: generate notes etc. var notes = [ 60, 62, 64, 65, 67, 71, 72 ]; var msgarr = []; for (var j=0; j<2; j++) { var divs = Math.pow(2, random((j+1)*2)+1); var div = 1/divs; var pitch = pick(notes); var dur = 500*div; for (var i=0; i<divs; i++) { var phase = i*div; var vel = 60 + random(30); // this way works too: //msgarr.push(track + " add " + beat + " " + phase + " note " + pitch + " " + vel + " " + dur); msgarr.push(track + " add " + beat + " " + phase + " duration " + dur); msgarr.push(track + " add " + beat + " " + phase + " velocity " + vel); msgarr.push(track + " add " + beat + " " + phase + " pitch " + pitch); } } var phase = 0; // "set" a parameter: var param = pick(device.parameters); if (param.name != "Device On") { var val; if (param.quantized) { val = param.min + random(param.max - param.min); } else { val = param.min + Math.random() * (param.max - param.min); } msgarr.push(track + " add " + beat + " " + phase + " zet " + param.id + " " + val ); //console.log(param.name, " ", val); } var param = pick(device.parameters); if (param.name != "Device On") { var val = Math.random(); msgarr.push(track + " add " + beat + " " + phase + " set " + param.id + " " + val ); //console.log(param.name, " ", val); } // mute / solo testing: if (random(4) == 0) { if (random(2)) { msgarr.push(track + " add " + beat + " " + phase + " mute " + random(2)); } else { msgarr.push(track + " add " + beat + " " + phase + " solo " + random(2)); } } // gen testing: // unset? if (random(16) < gens.length) { var which = random(gens.length); var id = gens[which]; gens.splice(which, 1); msgarr.push(track + " add " + beat + " " + phase + " ungen " + id); } if (random(16) < gens.length && random(2) == 0) { // set a parameter: var which = random(gens.length); var id = gens[which]; msgarr.push(track + " add " + beat + " " + phase + " genp " + id + " p0 " + random(4)); } else { // add a new mapping: var param = pick(device.parameters); if (param.name != "Device On") { var code = "Param p0(" + random(4) + ");"; code += "out1 = 1 - rate(in1, (p0+1)*" + (1/Math.pow(2, random(4))) + ");"; // wrap the code in quotes: code = '"' + code + '"'; var msg = track + " add " + beat + " " + phase + " gen " + param.id + " " + code; msgarr.push(msg); //console.log (msg); gens.push(param.id); } } send(msgarr.join("~")); } else if (cmd == "bar") { var bar = +arg; document.getElementById("bar").innerHTML = bar; } else if (cmd == "bit") { var beat = +arg; document.getElementById("beat").innerHTML = beat; } else if (cmd == "ply") { var play = +arg; document.getElementById("play").innerHTML = play; } else if (cmd == "sig") { var signature = arg; document.getElementById("signature").innerHTML = signature; } else if (cmd == "bpm") { var bpm = +arg; document.getElementById("bpm").innerHTML = bpm; } else if (cmd == "err") { post("received " + msg); } else if (cmd == "clr") { document.getElementById("post").innerHTML = ""; } else { post("received " + msg); } } } ///// start up ///// ws_connect(); </script> </body> </html>