Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Web Launchpad - Chelajs

Web Launchpad - Chelajs

Talk I gave at December's 15 Chela.js. It's about how I use Web Audio API + Web MIDI API + a Novation Launchpad to be a Web Madeon.

Orlando Del Aguila

December 02, 2015
Tweet

More Decks by Orlando Del Aguila

Other Decks in Programming

Transcript

  1. 20 _initMidi: function () { 21 navigator.requestMIDIAccess({ 22 sysex: false

    23 }).then(this._onMidiSuccessHandler); 24 }, 25 26 _onMidiMessageHandler: function _onMidiMessageHandler(message) { 27 console.log(message.data); 28 PubSub.emitEvent('onMidiMessage', [message]); 29 }, 30 31 _onMidiSuccessHandler: function _onMidiSuccessHandler(midi) { 32 var inputs = midi.inputs.values(); 33 // loop over all available inputs and listen for any MIDI input 34 for (var input = inputs.next(); input && !input.done; input = inputs.next()) { 35 // each time there is a midi message call the onMIDIMessage function 36 input.value.onmidimessage = this._onMidiMessageHandler; 37 }
  2. 20 _initMidi: function () { 21 navigator.requestMIDIAccess({ 22 sysex: false

    23 }).then(this._onMidiSuccessHandler); 24 }, 25 26 _onMidiMessageHandler: 27 28 PubSub.emitEvent( 29 }, 30 31 _onMidiSuccessHandler: 32 33 // loop over all available inputs and listen for any MIDI input 34 inputs.next()) { 35 // each time there is a midi message call the onMIDIMessage function 36 input.value.onmidimessage 37 }
  3. 31 _onMidiSuccessHandler: function _onMidiSuccessHandler(midi) { 32 var inputs = midi.inputs.values();

    33 // loop over all available inputs and listen for any MIDI input 34 for (var input = inputs.next(); input && !input.done; input = inputs.next()) { 35 // each time there is a midi message call the onMIDIMessage function 36 input.value.onmidimessage = this._onMidiMessageHandler; 37 } 20 _initMidi: 21 navigator.requestMIDIAccess({ 22 23 }).then( 24 }, 25 26 _onMidiMessageHandler: 27 28 PubSub.emitEvent( 29 }, 30
  4. 20 _initMidi: 21 navigator.requestMIDIAccess({ 22 23 }).then( 24 }, 25

    30 31 _onMidiSuccessHandler: 32 33 // loop over all available inputs and listen for any MIDI input 34 inputs.next()) { 35 // each time there is a midi message call the onMIDIMessage function 36 input.value.onmidimessage 37 } 26 _onMidiMessageHandler: function _onMidiMessageHandler(message) { 27 console.log(message.data); 28 PubSub.emitEvent('onMidiMessage', [message]); 29 },
  5. 1 (function () { 2 var SamplePlayer = function SamplePlayer(config)

    { 3 this.init(config); 4 }; 5 6 SamplePlayer.prototype = Object.create(Base); 7 8 Object.assign(SamplePlayer.prototype, { 9 events: { 10 'onMidiMessage': '_onMidiMessageHandler', 11 'samplePackChange': '_loadSamples' 12 }, 13 samplePackName: null, 14 samples: null, 15 buffers: null, 16 17 init: function init(config) { 18 this._bindAll(); 19 this.samples = {}; 20 this.buffers = {}; 21 this.audioContext = new AudioContext(); 22 this._loadSamples(SamplePackStore.activeSamplePack); 23 this._listenEvents(); 24 }, 25
  6. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 21 this.audioContext = new AudioContext();
  7. 1 (function () { 2 var SamplePackStore = window.SamplePackStore =

    Object.create({}); 3 4 Object.assign(SamplePackStore, { 5 samplePacks: {}, 6 samplePacksData: {}, 7 activeSamplePack: null, 8 set: function set(key) { 9 if (this.samplePacks[key]) { 10 this.activeSamplePack = this.samplePacks[key]; 11 PubSub.emitEvent('samplePackChange', [{name: key, data: this.activeSamplePack}]); 12 } 13 } 14 }); 15 16 SamplePackStore.samplePacks.firstOfTheYear = { 17 48: '/samples/firstyear/kick1.wav', 18 49: '/samples/firstyear/freeze1.wav', 19 50: '/samples/firstyear/freeze2.wav', 20 51: '/samples/firstyear/freeze3.wav', 21 33: '/samples/firstyear/freeze4.wav', 22 34: '/samples/firstyear/freeze5.wav', 23 35: '/samples/firstyear/freeze6.wav', 24 17: '/samples/firstyear/freeze7.wav', 25 18: '/samples/firstyear/freeze8.wav', 26 19: '/samples/firstyear/freeze9.wav', 27 2: '/samples/firstyear/freeze10.wav',
  8. 1 (function () { 2 var SamplePlayer = function SamplePlayer(config)

    { 3 this.init(config); 4 }; 5 6 SamplePlayer.prototype = Object.create(Base); 7 8 Object.assign(SamplePlayer.prototype, { 9 events: { 10 'onMidiMessage': '_onMidiMessageHandler', 11 'samplePackChange': '_loadSamples' 12 }, 13 samplePackName: null, 14 samples: null, 15 buffers: null, 16 17 init: function init(config) { 18 this._bindAll(); 19 this.samples = {}; 20 this.buffers = {}; 21 this.audioContext = new AudioContext(); 22 this._loadSamples(SamplePackStore.activeSamplePack); 23 this._listenEvents(); 24 }, 25 26 _loadSamples: function _loadSamples(samplePack) { 27 var samplePlayer = this; 28 var name = this.samplePackName = samplePack.name; 29 var data = samplePack.data;
  9. 1 2 3 4 5 6 7 8 9 10

    11 12 13 14 15 16 17 18 19 20 21 23 24 25 26 27 28 29 22 this._loadSamples(SamplePackStore.activeSamplePack);
  10. 26 _loadSamples: function _loadSamples(samplePack) { 27 var samplePlayer = this;

    28 var name = this.samplePackName = samplePack.name; 29 var data = samplePack.data; 30 var urls = []; 31 32 if (this.samples[name]) { 33 return this.samples[name]; 34 } 35 36 this.samples[name] = {}; 37 this.buffers[name] = {}; 38 39 Object.keys(data).forEach(function (key) { 40 var url = data[key]; 41 urls.push(url); 42 }); 43 44 new BufferLoader(this.audioContext, urls, function (bufferList) { 45 var keys = Object.keys(data); 46 47 keys.forEach(function (key, index) { 48 var buffer = bufferList[index]; 49 50 // Store the buffer to use it later 51 samplePlayer.buffers[name][key] = buffer; 52 }); 53 }).load(); 54 },
  11. 1 _onMidiMessageHandler: function _onMidiMessageHandler(message) { 2 var data = message.data;

    3 4 var key = data[1]; 5 var command = data[2]; 6 7 var samplePackName = this.samplePackName; 8 9 if (command === 127) { 10 var buffer = this.buffers[samplePackName][key]; 11 12 if (buffer) { 13 var sample = this._createNode(buffer, this.loop); 14 this.samples[samplePackName][key] = sample; 15 16 sample.start(0); 17 } 18 19 this._ledOn(key, 'green', true); 20 } else { 21 var sample = this.samples[samplePackName][key]; 22 23 sample && sample.stop(0); 24 25 this._ledOff(key); 26 } 27 },
  12. 81 82 _createNode: function (buffer) { 83 var node =

    this.audioContext.createBufferSource(); 84 node.buffer = buffer; 85 node.connect(this.audioContext.destination); 86 87 return node; 88 }, 89 90 _ledOn: function _ledOn(key, color, full) { 91 PubSub.emitEvent('ledOn', [key, color, full]); 92 }, 93 94 _ledOff: function _ledOff(key) { 95 PubSub.emitEvent('ledOff', [key]); 96 } 97 }); 98 99 window.SamplePlayer = SamplePlayer; 100 }());
  13. QA

  14. %