launchpad-mini-browser
Version:
This is a browser port from https://www.npmjs.com/package/launchpad-mini Usage is the same, but no disconnect function. ``` const pad = new Launchpad(); await pad.connect(); ``` You may have to allow the webpage to access midi-devices.
1 lines • 4.14 kB
JavaScript
(function(a){const c=function(){const a=Array(80).fill(0).map((a,b)=>[b%9,(b-b%9)/9]).map(a=>(a.id=Symbol(),a)),b=a.filter(a=>8>a[0]&&8>a[1]),c=a.filter(a=>8===a[1]),d=a.filter(a=>8===a[0]),e=new Map;a.forEach(a=>e.set(a.id,a));return{All:a,Grid:b,Automap:c,Scene:d,byId:a=>e.get(a),byXy:(b,c)=>a[9*c+b]}}(),d=function(){"use strict";class a{constructor(a,b,c,d){return this._level=a,this._clear=b,this._copy=c,this._name=d,this}get off(){return this.level(0)}get low(){return this.level(1)}get medium(){return this.level(2)}get full(){return this.level(3)}level(b){return new a(Math.min(3,Math.max(0,Math.round(b))),this._clear,this._copy,this._name)}get clear(){return new a(this._level,!0,this._copy,this._name)}get copy(){return new a(this._level,this._clear,!0,this._name)}get code(){let a=this._level*("red"===this._name||"amber"===this._name),b=this._level*("green"===this._name||"amber"===this._name);return"yellow"===this._name&&0<this._level&&(a=2,b=3),16*b+8*this._clear+4*this._copy+1*a}}const b=new a(3,!1,!1,"red"),c=new a(3,!1,!1,"green"),d=new a(3,!1,!1,"amber"),e=new a(3,!1,!1,"yellow"),f=new a(3,!1,!1,"off");return{Color:a,red:b,green:c,amber:d,yellow:e,off:f}}();class e{constructor(){this.___eventHandlers={}}on(a,b){this.___eventHandlers[a]||(this.___eventHandlers[a]=[]),this.___eventHandlers[a].push(b)}emit(a,b){if(this.___eventHandlers[a])for(let c of this.___eventHandlers[a])c(b)}}class f extends e{constructor(){super(),this._buttons=c.All.map(a=>({x:a[0],y:a[1],id:a.id})).map(a=>(a.cmd=8<=a.y?176:144,a.key=8<=a.y?104+a.x:16*a.y+a.x,a)),this._writeBuffer=0,this._displayBuffer=0,this._flashing=!1,this.red=d.red,this.green=d.green,this.amber=d.amber,this.yellow=d.yellow,this.off=d.off}async connect(){const a=await navigator.requestMIDIAccess(),b=a.inputs.values(),c=a.outputs.values();if(this.midiIn=[...b].find(a=>-1!==a.name.indexOf("Launchpad")),this.midiOut=[...c].find(a=>-1!==a.name.indexOf("Launchpad")),!(this.midiIn&&this.midiOut))throw new Error("Launchpad not found.");this.midiIn.onmidimessage=a=>this._processMessage(a.timeStamp,a.data)}reset(a){a=0<a&&3>=a?a+124:0,this.sendRaw([176,0,a])}sendRaw(a){this.midiOut.send(a)}get pressedButtons(){return this._buttons.filter(a=>a.pressed).map(a=>c.byXy(a.x,a.y))}isPressed(a){return this._buttons.some(c=>c.pressed&&c.x===a[0]&&c.y===a[1])}col(a,c){if(0<c.length&&c[0]instanceof Array)return c.forEach(b=>this.col(a,b)),new Promise(a=>setTimeout(a,c.length/20));else{let d=this._button(c);return d&&this.sendRaw([d.cmd,d.key,a.code||a]),Promise.resolve(!!d)}}setColors(a){return a.forEach(a=>this.setSingleButtonColor(a,a[2])),new Promise(b=>setTimeout(b,a.length/20))}setSingleButtonColor(a,c){let d=this._button(a);return d&&this.sendRaw([d.cmd,d.key,c.code||c]),!!d}get writeBuffer(){return this._writeBuffer}get displayBuffer(){return this._displayBuffer}set writeBuffer(a){this.setBuffers({write:a})}set displayBuffer(a){this.setBuffers({display:a,flash:!1})}set flash(a){this.setBuffers({flash:a})}setBuffers(a){a=a||{},this._flashing=or(a.flash,this._flashing),this._writeBuffer=1*or(a.write,this._writeBuffer),this._displayBuffer=1*or(a.display,this._displayBuffer);let b=32+16*or(a.copyToDisplay,0)+8*this._flashing+4*this.writeBuffer+1*this.displayBuffer;this.sendRaw([176,0,b])}multiplexing(a,b){let c,d;a=Math.max(1,Math.min(a||1,16)),b=Math.max(3,Math.min(b||5,18)),9>a?(d=30,c=16*(a-1)+(b-3)):(d=31,c=16*(a-9)+(b-3)),this.sendRaw([176,d,c])}brightness(a){this.multiplexing.apply(this,brightnessSteps.getNumDen(a))}fromMap(a){return Array.prototype.map.call(a,(a,b)=>({x:b%9,y:(b-b%9)/9,c:a})).filter(a=>"x"===a.c).map(a=>c.byXy(a.x,a.y))}fromPattern(a){return a instanceof Array?buttons.decodeStrings(a):buttons.decodeString(a).map(a=>c.byXy(a[0],a[1]))}_button(a){return this._buttons[9*a[1]+a[0]]}_processMessage(a,b){let c,d,e;if(144===b[0])c=b[1]%16,d=(b[1]-c)/16,e=0<b[2];else if(176===b[0])c=b[1]-104,d=8,e=0<b[2];else return void console.log(`Unknown message: ${b} at ${a}`);let f=this._button([c,d]);f.pressed=e,this.emit("key",{x:c,y:d,pressed:e,id:f.id,0:c,1:d,length:2})}}f.Buttons=c,f.Colors=d,a.Launchpad=f})(window);