8a417d6c58ce — Vesa Norilo 3 years ago
AudioWorkletProcessor no longer swallows reactive activations (broke midi stream)
M resources/public/audioworklet.js +1 -1
@@ 39,5 39,5 @@ splitBlock(block,bytes);else block.isFre
 allocationsByAddress[address];assert(allocatedBlock,"Allocation should be registered");DebugLog("Freeing "+allocatedBlock);releaseBlock(allocatedBlock);delete allocationsByAddress[address]}var allocator={allocate:allocate,free:free,toString:function(){var s="[Blocks]\n";for(var b=sentinel.next;b!=sentinel;b=b.next)s+=b+"\n";return s},"_vnr_malloc":function(bytes){var addr=this.allocate(bytes);DebugLog("*** After Allocation ("+addr+", "+bytes+") ***"+this);return addr},"_vnr_free":function(ptr){this.free(ptr);
 DebugLog("*** After Free ("+ptr+")***\n"+this)},"_vnr_memset":function(ptr,byte,size){DebugLog("memset "+ptr+","+byte+","+size);var h8=this["HEAP8"];for(var i=0;i<size;++i)h8[i+ptr]=byte},"wasmMemory":NativeHeap};CreateHeapArrays(allocator);return allocator}var NativeImage=new Allocator(NativeHeap);var JiT=Kronos.WorkletCompiler();registerProcessor("WasmProcessor",class extends AudioWorkletProcessor{constructor(options){super(options);this.initialize(options["processorOptions"])}initialize(opts){const $jscomp$this=
 this;this.env={"print":function(pipe,data){this.port.postMessage({"pr":[pipe,data]})}.bind(this),"gfx":function(pipe,data){this.port.postMessage({"gfx":[pipe,data]})}.bind(this),"defer":function(){}};console.log(opts);this.dirtyParams={};this.last=0;this.keepAlive=true;this.didPrint=currentTime;JiT.Instantiate(opts,this.env,sampleRate).then(function(inst){$jscomp$this.processor=inst["Build"];$jscomp$this.port.onmessage=$jscomp$this.recv.bind($jscomp$this);$jscomp$this.port.postMessage({"ready":true})}).catch(function(error){DebugErr(error);
-$jscomp$this.port.postMessage({"error":error})})}recv(event){var d=event.data;if(d["setp"]){this.dirtyParams[d["setp"]]=d["val"];return}else if(d["destroy"]){if(this.processor){this.processor.Destroy();delete this.processor;this.keepAlive=false}this.port.close();return}else if(d["slow"]!=undefined){this.processor.SetSlowMode(d["slow"]);return}console.error(d)}process(inputs,outputs,parameters){if(this.processor){for(var p in this.dirtyParams){const setter=this.processor.SetParam[p];if(setter)setter(this.dirtyParams[p])}this.dirtyParams=
+$jscomp$this.port.postMessage({"error":error})})}recv(event){var d=event.data;if(d["setp"]){this.processor.SetParam[d["setp"]](d["val"]);return}else if(d["destroy"]){if(this.processor){this.processor.Destroy();delete this.processor;this.keepAlive=false}this.port.close();return}else if(d["slow"]!=undefined){this.processor.SetSlowMode(d["slow"]);return}console.error(d)}process(inputs,outputs,parameters){if(this.processor){for(var p in this.dirtyParams){const setter=this.processor.SetParam[p];if(setter)setter(this.dirtyParams[p])}this.dirtyParams=
 {};if(this.processor.BufferSwitch){this.processor.BufferSwitch(inputs[0],outputs[0],outputs[0][0].length);if(this.processor["AudioIO"]["Outs"]<2)for(var i=1;i<outputs[0].length;++i)outputs[0][i].set(outputs[0][0])}if(this.env.pendingPrint){this.didPrint=currentTime;this.port.postMessage({"batch":this.env.pendingPrint});this.env.pendingPrint={}}}return this.keepAlive}})}catch(ex){console.error(ex)};
  No newline at end of file

          
M resources/public/wasm/kronos.data +75 -14
@@ 2317,9 2317,9 @@ Package MIDI {
 
 	Pack(status a b) {
 		;; Compose MIDI event from `status` byte and two parameter bytes `a` and `b`.
-		Make(Event BitShiftLeft(Coerce(0i status) & 0xff 16i)
-				   BitShiftLeft(Coerce(0i b)      & 0xff 8i)
-				   BitShiftLeft(Coerce(0i a)      & 0xff))
+		Make(Event BitShiftLeft(Coerce(0i status) & 0xff 16i) |
+				   BitShiftLeft(Coerce(0i a)      & 0x7f 8i)  |
+				   (Coerce(0i b) & 0x7f))
 	}
 
 	Note->Freq(note-num A4) {

          
@@ 2327,6 2327,12 @@ Package MIDI {
 		A4 * Math:Pow(2 (note-num - 69) / 12)
 	}
 
+	Package Status {
+		Note-On = 0x90
+		Note-Off = 0x80
+		Cc = 0xb0
+	}
+
 	MIDI->Freq(midi-event A4) {
 
 		;; Convert MIDI event stream to the frequency of the most recent note-on event

          
@@ 2338,7 2344,69 @@ Package MIDI {
 
 		Control:Sample-and-Hold(
 			Note->Freq(a A4) 
-			(b > 0i & s == 0x90))
+			Note-On?(midi-event))
+	}
+
+	Note-On?(midi-event) {
+
+		;; Returns true integer bitmask when `midi-event` is a note on event.
+
+		s = Status(midi-event)
+		b = B(midi-event)
+
+		s == 0x90 & b > 0i
+	}
+
+	Note-Off?(midi-event) {
+
+		;; Returns true integer bitmask when `midi-event` is a note off event
+
+		s = Status(midi-event)
+		b = B(midi-event)
+
+		s == 0x80 | (s == 0x90 & b == 0i)
+	}
+
+	Cc?(midi-event) {
+
+		;; Returns true integer bitmask when `midi-event` is a continuous controller
+
+		Status(midi-event) == Status:Cc
+	}
+
+	Cc?(cc midi-event) #[Extend] {
+
+		;; Returns true integer bitmask when `midi-event` is the continuous controller number `cc`.
+
+		Status(midi-event) == Status:Cc & A(midi-event) == Coerce(Int32 cc)
+	}
+
+	Count-Held-Notes(midi-event) {
+
+		;; Count the number of held keys within a stream of MIDI notes.
+		s = Status(midi-event)
+		b = B(midi-event)
+
+
+		count = Max(0i z-1(0i count) 
+					+ (Note-On?(midi-event) & 1i) 
+					- (Note-Off?(midi-event) & 1i))
+
+		count
+	}
+
+	Filter(midi-event pred-fn transform-fn) {
+
+		;; For midi-events that match the predicate function `pred-fn`, apply `transform-fn`
+		;; to the tuple of status/channel and two MIDI data bytes.
+		;; For example, you can map Continuous Controller 1 to 2 like this:
+		;; `Filter(midi-stream Curry(Cc? 1) (s _ b) => (s 2 b))`
+
+		(s a b) = MIDI:Unpack(midi-event)
+
+		Algorithm:Choose(pred-fn(midi-event)
+						 MIDI:Pack(transform-fn(s a b))
+						 midi-event)
 	}
 
 	MIDI->Gate(midi-event) {

          
@@ 2347,16 2415,9 @@ Package MIDI {
 		;; by comparing count of note-ons and note-offs. Outputs 0 when no notes are 
 		;; detected.
 
-		s = Status(midi-event)
-		b = B(midi-event)
-
-		note-on = s == 0x90 & b > 0i
-		note-off = s == 0x80 | (s == 0x90 & b == 0i)
-
-		count = z-1(count) + (note-on & 1i) - (note-off & 1i)
-
-		(count > 0i) & 1
-	}
+		Count-Held-Notes(midi-event) > 0 & 1 
+	}
+
 }
 Import Algorithm
 

          
M resources/public/wasm/kronos.js +1 -1
@@ 13,7 13,7 @@ var/** @type {{
   dataFileDownloads: Object,
   preloadResults: Object
 }}
- */Module;if(!Module)/** @suppress{checkTypes}*/Module=typeof NativeCompiler !== 'undefined' ? NativeCompiler : {};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(function(){var loadPackage=function(metadata){var PACKAGE_PATH;if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}else{throw"using preloaded data can only be done on a web page or in a web worker"}var PACKAGE_NAME="bin/kronos.data";var REMOTE_PACKAGE_BASE="kronos.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];var PACKAGE_UUID=metadata["package_uuid"];function fetchRemotePackage(packageName,packageSize,callback,errback){var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"]("Downloading data... ("+loaded+"/"+total+")")}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||(xhr.status==0&&xhr.response)){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}},handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","library",true,true);Module["FS_createPath"]("/library","deprecated",true,true);Module["FS_createPath"]("/library","experimental",true,true);Module["FS_createPath"]("/library","shim",true,true);Module["FS_createPath"]("/library","tests",true,true);/** @constructor */function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"]("fp "+this.name)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"]("fp "+that.name);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i<files.length;++i){new DataRequest(files[i]["start"],files[i]["end"],files[i]["audio"]).open("GET",files[i]["filename"])}function processPackageData(arrayBuffer){assert(arrayBuffer,"Loading data file failed.");assert(arrayBuffer instanceof ArrayBuffer,"bad input to processPackageData");var byteArray=new Uint8Array(arrayBuffer);DataRequest.prototype.byteArray=byteArray;var files=metadata["files"];for(var i=0;i<files.length;++i){DataRequest.prototype.requests[files[i].filename].onload()}Module["removeRunDependency"]("datafile_bin/kronos.data")}Module["addRunDependency"]("datafile_bin/kronos.data");if(!Module.preloadResults)Module.preloadResults={};Module.preloadResults[PACKAGE_NAME]={fromCache:false};if(fetched){processPackageData(fetched);fetched=null}else{fetchedCallback=processPackageData}}if(Module["calledRun"]){runWithFS()}else{if(!Module["preRun"])Module["preRun"]=[];Module["preRun"].push(runWithFS)}};loadPackage({"files":[{"filename":"/library/Algorithm.k","start":0,"end":8844,"audio":0},{"filename":"/library/Approx.k","start":8844,"end":13500,"audio":0},{"filename":"/library/Block-Diagram.k","start":13500,"end":14887,"audio":0},{"filename":"/library/Closure.k","start":14887,"end":15397,"audio":0},{"filename":"/library/Coerce.k","start":15397,"end":16951,"audio":0},{"filename":"/library/Comp.k","start":16951,"end":17518,"audio":0},{"filename":"/library/Complex.k","start":17518,"end":21604,"audio":0},{"filename":"/library/Control.k","start":21604,"end":24117,"audio":0},{"filename":"/library/Cycle.k","start":24117,"end":24903,"audio":0},{"filename":"/library/Delay.k","start":24903,"end":29539,"audio":0},{"filename":"/library/Envelope.k","start":29539,"end":33046,"audio":0},{"filename":"/library/Exception.k","start":33046,"end":33714,"audio":0},{"filename":"/library/Filter.k","start":33714,"end":39457,"audio":0},{"filename":"/library/Function.k","start":39457,"end":42406,"audio":0},{"filename":"/library/Gen.k","start":42406,"end":50841,"audio":0},{"filename":"/library/Graphics.k","start":50841,"end":53322,"audio":0},{"filename":"/library/IO.k","start":53322,"end":56106,"audio":0},{"filename":"/library/Implicit-Coerce.k","start":56106,"end":57618,"audio":0},{"filename":"/library/Interval.k","start":57618,"end":59776,"audio":0},{"filename":"/library/MIDI.k","start":59776,"end":61668,"audio":0},{"filename":"/library/Math.k","start":61668,"end":64515,"audio":0},{"filename":"/library/Prelude.k","start":64515,"end":65855,"audio":0},{"filename":"/library/Reflection.k","start":65855,"end":70114,"audio":0},{"filename":"/library/Sort.k","start":70114,"end":71440,"audio":0},{"filename":"/library/VM.k","start":71440,"end":81072,"audio":0},{"filename":"/library/Vector.k","start":81072,"end":87985,"audio":0},{"filename":"/library/Widget.k","start":87985,"end":91106,"audio":0},{"filename":"/library/binaryen.k","start":91106,"end":91371,"audio":0},{"filename":"/library/main.k","start":91371,"end":91575,"audio":0},{"filename":"/library/module.json","start":91575,"end":92156,"audio":0},{"filename":"/library/tests.json","start":92156,"end":100561,"audio":0},{"filename":"/library/deprecated/Actions.k","start":100561,"end":103236,"audio":0},{"filename":"/library/deprecated/Cepstrum.k","start":103236,"end":104872,"audio":0},{"filename":"/library/deprecated/Control.k","start":104872,"end":105062,"audio":0},{"filename":"/library/deprecated/Dictionary.k","start":105062,"end":105752,"audio":0},{"filename":"/library/deprecated/FFT.k","start":105752,"end":107486,"audio":0},{"filename":"/library/deprecated/Filter.k","start":107486,"end":110187,"audio":0},{"filename":"/library/deprecated/Interpolation.k","start":110187,"end":112147,"audio":0},{"filename":"/library/deprecated/Library.k","start":112147,"end":113703,"audio":0},{"filename":"/library/deprecated/Linear-Algebra.k","start":113703,"end":115687,"audio":0},{"filename":"/library/deprecated/MIDI.k","start":115687,"end":116483,"audio":0},{"filename":"/library/deprecated/Mutable-Array.k","start":116483,"end":117279,"audio":0},{"filename":"/library/deprecated/Mutable.k","start":117279,"end":119083,"audio":0},{"filename":"/library/deprecated/Sequencer.k","start":119083,"end":119621,"audio":0},{"filename":"/library/deprecated/Sound-File.k","start":119621,"end":121357,"audio":0},{"filename":"/library/deprecated/Trace.k","start":121357,"end":122088,"audio":0},{"filename":"/library/deprecated/Widget.k","start":122088,"end":125209,"audio":0},{"filename":"/library/deprecated/deprecatedGen.k","start":125209,"end":129660,"audio":0},{"filename":"/library/experimental/Dynamic.k","start":129660,"end":131016,"audio":0},{"filename":"/library/experimental/Hiccup.k","start":131016,"end":136063,"audio":0},{"filename":"/library/experimental/Lazy.k","start":136063,"end":138496,"audio":0},{"filename":"/library/experimental/Parallel.k","start":138496,"end":140124,"audio":0},{"filename":"/library/experimental/Type-Lookup.k","start":140124,"end":140741,"audio":0},{"filename":"/library/experimental/Vectorization.k","start":140741,"end":142639,"audio":0},{"filename":"/library/shim/Vector.k","start":142639,"end":143274,"audio":0},{"filename":"/library/tests/ADSR-Envelope.json","start":143274,"end":143508,"audio":0},{"filename":"/library/tests/ADSR-Envelope.k","start":143508,"end":146247,"audio":0},{"filename":"/library/tests/Additive-Synthesis.json","start":146247,"end":147060,"audio":0},{"filename":"/library/tests/Additive-Synthesis.k","start":147060,"end":150420,"audio":0},{"filename":"/library/tests/Algorithm.k","start":150420,"end":152414,"audio":0},{"filename":"/library/tests/Alignment.k","start":152414,"end":152801,"audio":0},{"filename":"/library/tests/Approx.k","start":152801,"end":153559,"audio":0},{"filename":"/library/tests/AudioFile.k","start":153559,"end":154022,"audio":0},{"filename":"/library/tests/BDA.k","start":154022,"end":154834,"audio":0},{"filename":"/library/tests/Basics.json","start":154834,"end":156325,"audio":0},{"filename":"/library/tests/Basics.k","start":156325,"end":159303,"audio":0},{"filename":"/library/tests/CMJ.k","start":159303,"end":169526,"audio":0},{"filename":"/library/tests/Coerce.k","start":169526,"end":170695,"audio":0},{"filename":"/library/tests/Compile-Time-Computation.json","start":170695,"end":171142,"audio":0},{"filename":"/library/tests/Compile-Time-Computation.k","start":171142,"end":172885,"audio":0},{"filename":"/library/tests/Complex.k","start":172885,"end":172899,"audio":0},{"filename":"/library/tests/Core.k","start":172899,"end":173665,"audio":0},{"filename":"/library/tests/DPW.json","start":173665,"end":174163,"audio":0},{"filename":"/library/tests/DPW.k","start":174163,"end":175945,"audio":0},{"filename":"/library/tests/Envelope.k","start":175945,"end":176246,"audio":0},{"filename":"/library/tests/Extending-Functions.json","start":176246,"end":176543,"audio":0},{"filename":"/library/tests/Extending-Functions.k","start":176543,"end":179210,"audio":0},{"filename":"/library/tests/Filter.k","start":179210,"end":182143,"audio":0},{"filename":"/library/tests/Gen.k","start":182143,"end":183395,"audio":0},{"filename":"/library/tests/Gradual-Types.json","start":183395,"end":184868,"audio":0},{"filename":"/library/tests/Gradual-Types.k","start":184868,"end":189638,"audio":0},{"filename":"/library/tests/Granular-Synthesis.json","start":189638,"end":190403,"audio":0},{"filename":"/library/tests/Granular-Synthesis.k","start":190403,"end":196261,"audio":0},{"filename":"/library/tests/Infix.k","start":196261,"end":196428,"audio":0},{"filename":"/library/tests/Math.k","start":196428,"end":196653,"audio":0},{"filename":"/library/tests/Multichannel.k","start":196653,"end":198138,"audio":0},{"filename":"/library/tests/Osc.k","start":198138,"end":200533,"audio":0},{"filename":"/library/tests/Polymorphism.json","start":200533,"end":201764,"audio":0},{"filename":"/library/tests/Polymorphism.k","start":201764,"end":205793,"audio":0},{"filename":"/library/tests/Precedence.k","start":205793,"end":205900,"audio":0},{"filename":"/library/tests/Reactive.k","start":205900,"end":207138,"audio":0},{"filename":"/library/tests/Simple-Waveforms.json","start":207138,"end":207349,"audio":0},{"filename":"/library/tests/Simple-Waveforms.k","start":207349,"end":208235,"audio":0},{"filename":"/library/tests/Sort.k","start":208235,"end":208533,"audio":0},{"filename":"/library/tests/StreamOut.k","start":208533,"end":208717,"audio":0},{"filename":"/library/tests/String.k","start":208717,"end":209423,"audio":0},{"filename":"/library/tests/Syntax.json","start":209423,"end":210193,"audio":0},{"filename":"/library/tests/Syntax.k","start":210193,"end":211908,"audio":0},{"filename":"/library/tests/Thesis.k","start":211908,"end":221767,"audio":0},{"filename":"/library/tests/UnionTypes.k","start":221767,"end":221767,"audio":0},{"filename":"/library/tests/Vector.k","start":221767,"end":223195,"audio":0},{"filename":"/library/tests/VoiceAllocator.k","start":223195,"end":226109,"audio":0},{"filename":"/library/tests/WikiGeometricWaves.k","start":226109,"end":226970,"audio":0},{"filename":"/library/tests/WikiReverb.k","start":226970,"end":226970,"audio":0},{"filename":"/library/tests/WikiSynthesis.k","start":226970,"end":229258,"audio":0}],"remote_package_size":229258,"package_uuid":"d0d54251-c6bf-46c4-8536-2f26336fe0c5"})})();var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console=/** @type{!Console} */({});console.log=/** @type{!function(this:Console, ...*): undefined} */(print);console.warn=console.error=/** @type{!function(this:Console, ...*): undefined} */(typeof printErr!=="undefined"?printErr:print)}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response))}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||(xhr.status==0&&xhr.response)){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;/** @type {function(*, string=)} */function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;/**
+ */Module;if(!Module)/** @suppress{checkTypes}*/Module=typeof NativeCompiler !== 'undefined' ? NativeCompiler : {};var readyPromiseResolve,readyPromiseReject;Module["ready"]=new Promise(function(resolve,reject){readyPromiseResolve=resolve;readyPromiseReject=reject});if(!Module.expectedDataFileDownloads){Module.expectedDataFileDownloads=0}Module.expectedDataFileDownloads++;(function(){var loadPackage=function(metadata){var PACKAGE_PATH;if(typeof window==="object"){PACKAGE_PATH=window["encodeURIComponent"](window.location.pathname.toString().substring(0,window.location.pathname.toString().lastIndexOf("/"))+"/")}else if(typeof location!=="undefined"){PACKAGE_PATH=encodeURIComponent(location.pathname.toString().substring(0,location.pathname.toString().lastIndexOf("/"))+"/")}else{throw"using preloaded data can only be done on a web page or in a web worker"}var PACKAGE_NAME="bin/kronos.data";var REMOTE_PACKAGE_BASE="kronos.data";if(typeof Module["locateFilePackage"]==="function"&&!Module["locateFile"]){Module["locateFile"]=Module["locateFilePackage"];err("warning: you defined Module.locateFilePackage, that has been renamed to Module.locateFile (using your locateFilePackage for now)")}var REMOTE_PACKAGE_NAME=Module["locateFile"]?Module["locateFile"](REMOTE_PACKAGE_BASE,""):REMOTE_PACKAGE_BASE;var REMOTE_PACKAGE_SIZE=metadata["remote_package_size"];var PACKAGE_UUID=metadata["package_uuid"];function fetchRemotePackage(packageName,packageSize,callback,errback){var xhr=new XMLHttpRequest;xhr.open("GET",packageName,true);xhr.responseType="arraybuffer";xhr.onprogress=function(event){var url=packageName;var size=packageSize;if(event.total)size=event.total;if(event.loaded){if(!xhr.addedTotal){xhr.addedTotal=true;if(!Module.dataFileDownloads)Module.dataFileDownloads={};Module.dataFileDownloads[url]={loaded:event.loaded,total:size}}else{Module.dataFileDownloads[url].loaded=event.loaded}var total=0;var loaded=0;var num=0;for(var download in Module.dataFileDownloads){var data=Module.dataFileDownloads[download];total+=data.total;loaded+=data.loaded;num++}total=Math.ceil(total*Module.expectedDataFileDownloads/num);if(Module["setStatus"])Module["setStatus"]("Downloading data... ("+loaded+"/"+total+")")}else if(!Module.dataFileDownloads){if(Module["setStatus"])Module["setStatus"]("Downloading data...")}};xhr.onerror=function(event){throw new Error("NetworkError for: "+packageName)};xhr.onload=function(event){if(xhr.status==200||xhr.status==304||xhr.status==206||(xhr.status==0&&xhr.response)){var packageData=xhr.response;callback(packageData)}else{throw new Error(xhr.statusText+" : "+xhr.responseURL)}};xhr.send(null)}function handleError(error){console.error("package error:",error)}var fetchedCallback=null;var fetched=Module["getPreloadedPackage"]?Module["getPreloadedPackage"](REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE):null;if(!fetched)fetchRemotePackage(REMOTE_PACKAGE_NAME,REMOTE_PACKAGE_SIZE,function(data){if(fetchedCallback){fetchedCallback(data);fetchedCallback=null}else{fetched=data}},handleError);function runWithFS(){function assert(check,msg){if(!check)throw msg+(new Error).stack}Module["FS_createPath"]("/","library",true,true);Module["FS_createPath"]("/library","deprecated",true,true);Module["FS_createPath"]("/library","experimental",true,true);Module["FS_createPath"]("/library","shim",true,true);Module["FS_createPath"]("/library","tests",true,true);/** @constructor */function DataRequest(start,end,audio){this.start=start;this.end=end;this.audio=audio}DataRequest.prototype={requests:{},open:function(mode,name){this.name=name;this.requests[name]=this;Module["addRunDependency"]("fp "+this.name)},send:function(){},onload:function(){var byteArray=this.byteArray.subarray(this.start,this.end);this.finish(byteArray)},finish:function(byteArray){var that=this;Module["FS_createDataFile"](this.name,null,byteArray,true,true,true);Module["removeRunDependency"]("fp "+that.name);this.requests[this.name]=null}};var files=metadata["files"];for(var i=0;i<files.length;++i){new DataRequest(files[i]["start"],files[i]["end"],files[i]["audio"]).open("GET",files[i]["filename"])}function processPackageData(arrayBuffer){assert(arrayBuffer,"Loading data file failed.");assert(arrayBuffer instanceof ArrayBuffer,"bad input to processPackageData");var byteArray=new Uint8Array(arrayBuffer);DataRequest.prototype.byteArray=byteArray;var files=metadata["files"];for(var i=0;i<files.length;++i){DataRequest.prototype.requests[files[i].filename].onload()}Module["removeRunDependency"]("datafile_bin/kronos.data")}Module["addRunDependency"]("datafile_bin/kronos.data");if(!Module.preloadResults)Module.preloadResults={};Module.preloadResults[PACKAGE_NAME]={fromCache:false};if(fetched){processPackageData(fetched);fetched=null}else{fetchedCallback=processPackageData}}if(Module["calledRun"]){runWithFS()}else{if(!Module["preRun"])Module["preRun"]=[];Module["preRun"].push(runWithFS)}};loadPackage({"files":[{"filename":"/library/Algorithm.k","start":0,"end":8844,"audio":0},{"filename":"/library/Approx.k","start":8844,"end":13500,"audio":0},{"filename":"/library/Block-Diagram.k","start":13500,"end":14887,"audio":0},{"filename":"/library/Closure.k","start":14887,"end":15397,"audio":0},{"filename":"/library/Coerce.k","start":15397,"end":16951,"audio":0},{"filename":"/library/Comp.k","start":16951,"end":17518,"audio":0},{"filename":"/library/Complex.k","start":17518,"end":21604,"audio":0},{"filename":"/library/Control.k","start":21604,"end":24117,"audio":0},{"filename":"/library/Cycle.k","start":24117,"end":24903,"audio":0},{"filename":"/library/Delay.k","start":24903,"end":29539,"audio":0},{"filename":"/library/Envelope.k","start":29539,"end":33046,"audio":0},{"filename":"/library/Exception.k","start":33046,"end":33714,"audio":0},{"filename":"/library/Filter.k","start":33714,"end":39457,"audio":0},{"filename":"/library/Function.k","start":39457,"end":42406,"audio":0},{"filename":"/library/Gen.k","start":42406,"end":50841,"audio":0},{"filename":"/library/Graphics.k","start":50841,"end":53322,"audio":0},{"filename":"/library/IO.k","start":53322,"end":56106,"audio":0},{"filename":"/library/Implicit-Coerce.k","start":56106,"end":57618,"audio":0},{"filename":"/library/Interval.k","start":57618,"end":59776,"audio":0},{"filename":"/library/MIDI.k","start":59776,"end":63043,"audio":0},{"filename":"/library/Math.k","start":63043,"end":65890,"audio":0},{"filename":"/library/Prelude.k","start":65890,"end":67230,"audio":0},{"filename":"/library/Reflection.k","start":67230,"end":71489,"audio":0},{"filename":"/library/Sort.k","start":71489,"end":72815,"audio":0},{"filename":"/library/VM.k","start":72815,"end":82447,"audio":0},{"filename":"/library/Vector.k","start":82447,"end":89360,"audio":0},{"filename":"/library/Widget.k","start":89360,"end":92481,"audio":0},{"filename":"/library/binaryen.k","start":92481,"end":92746,"audio":0},{"filename":"/library/main.k","start":92746,"end":92950,"audio":0},{"filename":"/library/module.json","start":92950,"end":93531,"audio":0},{"filename":"/library/tests.json","start":93531,"end":101936,"audio":0},{"filename":"/library/deprecated/Actions.k","start":101936,"end":104611,"audio":0},{"filename":"/library/deprecated/Cepstrum.k","start":104611,"end":106247,"audio":0},{"filename":"/library/deprecated/Control.k","start":106247,"end":106437,"audio":0},{"filename":"/library/deprecated/Dictionary.k","start":106437,"end":107127,"audio":0},{"filename":"/library/deprecated/FFT.k","start":107127,"end":108861,"audio":0},{"filename":"/library/deprecated/Filter.k","start":108861,"end":111562,"audio":0},{"filename":"/library/deprecated/Interpolation.k","start":111562,"end":113522,"audio":0},{"filename":"/library/deprecated/Library.k","start":113522,"end":115078,"audio":0},{"filename":"/library/deprecated/Linear-Algebra.k","start":115078,"end":117062,"audio":0},{"filename":"/library/deprecated/MIDI.k","start":117062,"end":117858,"audio":0},{"filename":"/library/deprecated/Mutable-Array.k","start":117858,"end":118654,"audio":0},{"filename":"/library/deprecated/Mutable.k","start":118654,"end":120458,"audio":0},{"filename":"/library/deprecated/Sequencer.k","start":120458,"end":120996,"audio":0},{"filename":"/library/deprecated/Sound-File.k","start":120996,"end":122732,"audio":0},{"filename":"/library/deprecated/Trace.k","start":122732,"end":123463,"audio":0},{"filename":"/library/deprecated/Widget.k","start":123463,"end":126584,"audio":0},{"filename":"/library/deprecated/deprecatedGen.k","start":126584,"end":131035,"audio":0},{"filename":"/library/experimental/Dynamic.k","start":131035,"end":132391,"audio":0},{"filename":"/library/experimental/Hiccup.k","start":132391,"end":137438,"audio":0},{"filename":"/library/experimental/Lazy.k","start":137438,"end":139871,"audio":0},{"filename":"/library/experimental/Parallel.k","start":139871,"end":141499,"audio":0},{"filename":"/library/experimental/Type-Lookup.k","start":141499,"end":142116,"audio":0},{"filename":"/library/experimental/Vectorization.k","start":142116,"end":144014,"audio":0},{"filename":"/library/shim/Vector.k","start":144014,"end":144649,"audio":0},{"filename":"/library/tests/ADSR-Envelope.json","start":144649,"end":144883,"audio":0},{"filename":"/library/tests/ADSR-Envelope.k","start":144883,"end":147622,"audio":0},{"filename":"/library/tests/Additive-Synthesis.json","start":147622,"end":148435,"audio":0},{"filename":"/library/tests/Additive-Synthesis.k","start":148435,"end":151795,"audio":0},{"filename":"/library/tests/Algorithm.k","start":151795,"end":153789,"audio":0},{"filename":"/library/tests/Alignment.k","start":153789,"end":154176,"audio":0},{"filename":"/library/tests/Approx.k","start":154176,"end":154934,"audio":0},{"filename":"/library/tests/AudioFile.k","start":154934,"end":155397,"audio":0},{"filename":"/library/tests/BDA.k","start":155397,"end":156209,"audio":0},{"filename":"/library/tests/Basics.json","start":156209,"end":157700,"audio":0},{"filename":"/library/tests/Basics.k","start":157700,"end":160678,"audio":0},{"filename":"/library/tests/CMJ.k","start":160678,"end":170901,"audio":0},{"filename":"/library/tests/Coerce.k","start":170901,"end":172070,"audio":0},{"filename":"/library/tests/Compile-Time-Computation.json","start":172070,"end":172517,"audio":0},{"filename":"/library/tests/Compile-Time-Computation.k","start":172517,"end":174260,"audio":0},{"filename":"/library/tests/Complex.k","start":174260,"end":174274,"audio":0},{"filename":"/library/tests/Core.k","start":174274,"end":175040,"audio":0},{"filename":"/library/tests/DPW.json","start":175040,"end":175538,"audio":0},{"filename":"/library/tests/DPW.k","start":175538,"end":177320,"audio":0},{"filename":"/library/tests/Envelope.k","start":177320,"end":177621,"audio":0},{"filename":"/library/tests/Extending-Functions.json","start":177621,"end":177918,"audio":0},{"filename":"/library/tests/Extending-Functions.k","start":177918,"end":180585,"audio":0},{"filename":"/library/tests/Filter.k","start":180585,"end":183518,"audio":0},{"filename":"/library/tests/Gen.k","start":183518,"end":184770,"audio":0},{"filename":"/library/tests/Gradual-Types.json","start":184770,"end":186243,"audio":0},{"filename":"/library/tests/Gradual-Types.k","start":186243,"end":191013,"audio":0},{"filename":"/library/tests/Granular-Synthesis.json","start":191013,"end":191778,"audio":0},{"filename":"/library/tests/Granular-Synthesis.k","start":191778,"end":197636,"audio":0},{"filename":"/library/tests/Infix.k","start":197636,"end":197803,"audio":0},{"filename":"/library/tests/Math.k","start":197803,"end":198028,"audio":0},{"filename":"/library/tests/Multichannel.k","start":198028,"end":199513,"audio":0},{"filename":"/library/tests/Osc.k","start":199513,"end":201908,"audio":0},{"filename":"/library/tests/Polymorphism.json","start":201908,"end":203139,"audio":0},{"filename":"/library/tests/Polymorphism.k","start":203139,"end":207168,"audio":0},{"filename":"/library/tests/Precedence.k","start":207168,"end":207275,"audio":0},{"filename":"/library/tests/Reactive.k","start":207275,"end":208513,"audio":0},{"filename":"/library/tests/Simple-Waveforms.json","start":208513,"end":208724,"audio":0},{"filename":"/library/tests/Simple-Waveforms.k","start":208724,"end":209610,"audio":0},{"filename":"/library/tests/Sort.k","start":209610,"end":209908,"audio":0},{"filename":"/library/tests/StreamOut.k","start":209908,"end":210092,"audio":0},{"filename":"/library/tests/String.k","start":210092,"end":210798,"audio":0},{"filename":"/library/tests/Syntax.json","start":210798,"end":211568,"audio":0},{"filename":"/library/tests/Syntax.k","start":211568,"end":213283,"audio":0},{"filename":"/library/tests/Thesis.k","start":213283,"end":223142,"audio":0},{"filename":"/library/tests/UnionTypes.k","start":223142,"end":223142,"audio":0},{"filename":"/library/tests/Vector.k","start":223142,"end":224570,"audio":0},{"filename":"/library/tests/VoiceAllocator.k","start":224570,"end":227484,"audio":0},{"filename":"/library/tests/WikiGeometricWaves.k","start":227484,"end":228345,"audio":0},{"filename":"/library/tests/WikiReverb.k","start":228345,"end":228345,"audio":0},{"filename":"/library/tests/WikiSynthesis.k","start":228345,"end":230633,"audio":0}],"remote_package_size":230633,"package_uuid":"f721bd40-318b-4a80-94d8-3ad757c3de31"})})();var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_IS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;var nodeFS;var nodePath;if(ENVIRONMENT_IS_NODE){if(ENVIRONMENT_IS_WORKER){scriptDirectory=require("path").dirname(scriptDirectory)+"/"}else{scriptDirectory=__dirname+"/"}read_=function shell_read(filename,binary){if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);return nodeFS["readFileSync"](filename,binary?null:"utf8")};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console=/** @type{!Console} */({});console.log=/** @type{!function(this:Console, ...*): undefined} */(print);console.warn=console.error=/** @type{!function(this:Console, ...*): undefined} */(typeof printErr!=="undefined"?printErr:print)}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(typeof document!=="undefined"&&document.currentScript){scriptDirectory=document.currentScript.src}if(_scriptDir){scriptDirectory=_scriptDir}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}{read_=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(/** @type{!ArrayBuffer} */(xhr.response))}}readAsync=function(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function(){if(xhr.status==200||(xhr.status==0&&xhr.response)){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)}}setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];var STACK_ALIGN=16;function alignMemory(size,factor){if(!factor)factor=STACK_ALIGN;return Math.ceil(size/factor)*factor}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime=Module["noExitRuntime"]||true;if(typeof WebAssembly!=="object"){abort("no native wasm support detected")}var wasmMemory;var ABORT=false;var EXITSTATUS;/** @type {function(*, string=)} */function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}var UTF8Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf8"):undefined;/**
  * @param {number} idx
  * @param {number=} maxBytesToRead
  * @return {string}

          
M resources/public/wasm/kronos.wasm +0 -0

        
M src/js/AudioWorkletProcessor.js +2 -1
@@ 279,7 279,8 @@ registerProcessor("WasmProcessor", class
 	recv(event) {
 		var d = event.data;
 		if (d["setp"]) {
-			this.dirtyParams[d["setp"]] = d["val"];
+			this.processor.SetParam[d["setp"]](d["val"]);
+//			this.dirtyParams[d["setp"]] = d["val"];
 			return;
 		} else if (d["destroy"]) {
 			if (this.processor) {

          
M src/js/KronosClass.js +1 -0
@@ 298,6 298,7 @@ var GlobalPauseMode = false;
 			if (setter || ticker) {
 				if (type === "%i") {
 					inst["SetParam"][method] = (function(data) {
+						console.log(method, data);
 						this.InBuf.I32(1)[0] = data;
 						setter && setter(this.InBuf.ptr);
 						ticker && ticker(this.InstancePtr, this.OutBuf.ptr, 1);

          
M src/veneer/kronos/rpc.cljs +1 -1
@@ 119,7 119,7 @@ 
        :status :idle
        :send incoming
        :response {}
-       :notify (chan)
+       :notify (chan 32)
        :status-fn status-fn
        :id-counter 1
        })

          
M src/veneer/midi.cljs +2 -1
@@ 13,7 13,7 @@ 
 (defonce monitor& (atom 0))
 
 (defn recv [data]
-  (when (= 3 (.-length data))
+  (if (= 3 (.-length data))
     (let [[a b c] (array-seq data)          
           kind (bit-and a 0xf0)
           evt24 

          
@@ 23,6 23,7 @@ 
               (bit-shift-left b 8) c))]
       (when evt24 
         (reset! monitor& evt24)
+        (println a b c)
         (rpc/default "set" {"/midi" evt24})))))
 
 

          
M src/veneer/patcher/expr.cljs +1 -1
@@ 177,7 177,7 @@ 
     :on-key-down 
     (fn [evt]
       (let [n (-> evt .-which keycode->note)]
-        (when n 
+        (when (and n (-> evt .-repeat not)) 
           (midi/recv (clj->js [0x90 n 0x64])))))
     :on-key-up 
     (fn [evt]