/*jshint browser:true, bitwise:false */ /*globals App */ /** * io.js * * Handle communication with MIDI inputs and outputs * Request navigator access to MIDI devices */ (function () { 'use strict'; /** * Wrap around low-level MIDI output * * @param {native: MIDIOutput} Native MIDIOutput to wrap around */ function Output(native) { this.native = native || { send: function () {} }; } /** * List of MIDI channel events */ Output.messages = { noteOff: 0x80, noteOn: 0x90, noteAftertouch: 0xA0, controller: 0xB0, programChange: 0xC0, channelAftertouch: 0xD0, pitchBend: 0xE0 }; /** * List of controller types * (not complete) */ Output.controllers = { modulationWheel: 1, volume: 7, pan: 10, expression: 11, sustainPedal: 64 }; Output.prototype.programChange = function (channel, program, delay) { this.native.send([ Output.messages.programChange + channel, program ], (delay || 0) * 1000); }; Output.prototype.noteOn = function (channel, note, velocity, delay) { this.native.send([ Output.messages.noteOn + channel, note, velocity ], (delay || 0) * 1000); }; Output.prototype.noteOff = function (channel, note, delay) { this.native.send([ Output.messages.noteOff + channel, note, 0 ], (delay || 0) * 1000); }; Output.prototype.noteAftertouch = function (channel, note, amount, delay) { this.native.send([ Output.messages.noteAftertouch + channel, note, amount ], (delay || 0) * 1000); }; Output.prototype.controller = function (channel, type, value, delay) { this.native.send([ Output.messages.controller + channel, type, value ], (delay || 0) * 1000); }; Output.prototype.programChange = function (channel, program, delay) { this.native.send([ Output.messages.programChange + channel, program ], (delay || 0) * 1000); }; Output.prototype.channelAftertouch = function (channel, amount, delay) { this.native.send([ Output.messages.channelAftertouch + channel, amount ], (delay || 0) * 1000); }; Output.prototype.pitchBend = function (channel, value, delay) { var lsb, msb; value += 8192; lsb = value & 127; msb = value >> 7; this.native.send([ Output.messages.pitchBend + channel, lsb, msb ], (delay || 0) * 1000); }; /** * Request MIDI access, select first available output * * @return Promise */ function connect() { var promise; promise = new window.Promise(function (resolve, reject) { var ignoreAlert = "Si vous continuez, " + "aucun son ne sera émis ou reçu, mais vous " + "pourrez utiliser les autres fonctionnalités " + "du logiciel."; // by default, we use a no-op output App.MIDI.output = new Output(); navigator.requestMIDIAccess().then(function (access) { var outputs = access.outputs(), output; if (outputs && outputs.length) { output = new Output(outputs[0]); App.MIDI.output = output; resolve(output); } else { reject(new Error( "Aucun synthétiseur MIDI n'est disponible. Sur " + "systèmes d'exploitation, un synthétiseur " + "est disponible par défaut. S'il ce n'est pas " + "votre cas, il faudra utiliser un logiciel " + "tiers pour synthétiser les sons.

" + ignoreAlert )); } }).catch(function () { reject(new Error( "Impossible d'obtenir un accès aux contrôleurs " + "MIDI, il est possible que votre système ne " + "supporte pas la norme MIDI ou bien que " + "vous ayez refusé l'accès à ces périphériques. " + "

" + ignoreAlert )); }); }); return promise; } App.MIDI.connect = connect; }());