diff --git a/README.md b/README.md index 766be1b..b31633b 100644 --- a/README.md +++ b/README.md @@ -84,7 +84,6 @@ MIDI.Player.setAnimation(function(data) {

Many thanks to the authors of these libraries;

* <audio>: HTML5 specs * WebAudioAPI: W3C proposal by Google -* Java package: MIDIBridge by Daniel van der Meer. Supports MIDI keyboard, and 128 General MIDI instruments. * Flash package: SoundManager2 by Scott Schiller * jasmid: Reads MIDI file byte-code, and translats into a Javascript array. * base642binary.js: Cleans up XML base64-requests for Web Audio API. \ No newline at end of file diff --git a/inc/midibridge/README b/inc/midibridge/README deleted file mode 100644 index 7a71651..0000000 --- a/inc/midibridge/README +++ /dev/null @@ -1,39 +0,0 @@ -The midibridge is a Javascript API for interacting with the midi devices on your computer. - -It provides methods for detecting the midi devices and for connecting these devices with each other. - -The midibridge itself is considered a midi device as well, so it can be connected to the detected devices. - -The midibridge can generate and send midi events to midi output devices, and receive midi events from midi input devices. - -The midibridge can also filter and alter midi events. - -Recording and playing back midi events with a sequencer will be added in later versions. - -A midi output device is a physical output port on your computer, a virtual output port or a software synthesizer. It can also be a sequencer, a file or a function. - -A midi input device is a physical or virtual input port, a sequencer, a file or a function. - -A midi device can be both in- and output. The midibridge itself for instance is both in- and output because it can send and receive midi events. - -The actual interaction with the midi devices on your computer is done by a Java applet. The midibridge automatically adds the applet to your webpage. - -The midibridge has no visual parts, it is 'headless' code. You could say the midibridge enables you to write a 'front-end' on top of the applet. - -Midi Devices -> Java Applet -> Javascript Midibridge API -> a GUI in Javascript, Flash, SVG, C# (Silverlight) - -Because the midibridge is written in native Javascript, you can use it conflict-free with any Javascript framework. - - -The only files you need to get started are: - -/lib/midibridge-0.5.1.min.js -/java/midiapplet.jar - - -/lib/MidiBridge.js is the non-minified version of /lib/midibridge-0.5.1.min.js - -The other files and notably the files in the /js folder are code snippets that i have used in the quick start guide and the documentation on my blogpost, see: - -http://www.abumarkub.net/abublog/?p=399 - diff --git a/inc/midibridge/index.html b/inc/midibridge/index.html deleted file mode 100644 index 0808ae1..0000000 --- a/inc/midibridge/index.html +++ /dev/null @@ -1,83 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/inc/midibridge/java/midiapplet.jar b/inc/midibridge/java/midiapplet.jar deleted file mode 100644 index ea4e6e9..0000000 Binary files a/inc/midibridge/java/midiapplet.jar and /dev/null differ diff --git a/inc/midibridge/lib/MidiBridge.js b/inc/midibridge/lib/MidiBridge.js deleted file mode 100644 index fe9f8e2..0000000 --- a/inc/midibridge/lib/MidiBridge.js +++ /dev/null @@ -1,502 +0,0 @@ -/** - * This version is supported by all browsers that support native JSON parsing: - * - Firefox 3.5+ - * - Chrome 4.0+ - * - Safari 4.0+ - * - Opera 10.5+ - * - Internet Explorer 8.0+ - * - * If you want this version to work with other browsers, you can use the JSON parsing methods of your favorite Javascript - * framework (e.g. jQuery, Dojo, YUI, Mootools, etc.) - * - * Note for IE8 users: if you include MidiBridge.js (or preferably the minified version of it: midibridge-0.5.min.js) in your html, - * the method addEventListener will be added to the window object. In fact this method is just a wrapper around the attachEvent method, - * see code at the bottom of this file. - */ - -(function() { - var midiBridge = { - NOTE_OFF : 0x80, //128 - NOTE_ON : 0x90, //144 - POLY_PRESSURE : 0xA0, //160 - CONTROL_CHANGE : 0xB0, //176 - PROGRAM_CHANGE : 0xC0, //192 - CHANNEL_PRESSURE : 0xD0, //208 - PITCH_BEND : 0xE0, //224 - SYSTEM_EXCLUSIVE : 0xF0, //240 - NOTE_NAMES_SHARP : "sharp", - NOTE_NAMES_FLAT : "flat", - NOTE_NAMES_SOUNDFONT : "soundfont", - NOTE_NAMES_ENHARMONIC_SHARP : "enh-sharp", - NOTE_NAMES_ENHARMONIC_FLAT : "enh-flat" - - }; - //human readable representation of status byte midi data - var status = []; - status[0x80] = "NOTE OFF"; - status[0x90] = "NOTE ON"; - status[0xA0] = "POLY PRESSURE"; - status[0xB0] = "CONTROL CHANGE"; - status[0xC0] = "PROGRAM CHANGE"; - status[0xD0] = "CHANNEL PRESSURE"; - status[0xE0] = "PITCH BEND"; - status[0xF0] = "SYSTEM EXCLUSIVE"; - //notenames in different modi - var noteNames = { - "sharp" : ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"], - "flat" : ["C", "Dâ™­", "D", "Eâ™­", "E", "F", "Gâ™­", "G", "Aâ™­", "A", "Bâ™­", "B"], - "soundfont" : ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"], - "enh-sharp" : ["B#", "C#", "C##", "D#", "D##", "E#", "F#", "F##", "G#", "G##", "A#", "A##"], - "enh-flat" : ["Dâ™­â™­", "Dâ™­", "Eâ™­â™­", "Eâ™­", "Fâ™­", "Gâ™­â™­", "Gâ™­", "Aâ™­â™­", "Aâ™­", "Bâ™­", "Bâ™­", "Câ™­"] - } - //variable that holds a reference to the JSON parser method of your liking, defaults to native JSON parsing - var parseJSON = JSON.parse; - //method that gets called when midi note events arrive from the applet - var ondata = null; - var onerror = null; - var onready = null; - //the applet object - var applet = null; - var connectAllInputs = false; - var connectFirstInput = false; - var connectFirstOutput = false; - var connectAllInputsToFirstOutput = true; - var javaDir = "java"; - var devices = {}; - midiBridge.version = "0.5.1"; - midiBridge.ready = false; - midiBridge.noteNameModus = midiBridge.NOTE_NAMES_SHARP; - - /** - * static method called to initialize the MidiBridge - * possible arguments: - * 1) callback [function] callback when midi data has arrived - * 2) config object - * - ready : [function] callback when midibridge is ready/initialized - * - error : [function] callback in case of an error - * - data : [function] callback when midi data has arrived - * - connectAllInputs : [true,false] all found midi input devices get connected automatically - * - connectFirstInput : [true,false] the first found midi input device gets connected automatically - * - connectFirstOutput : [true,false] the first found midi output device gets connected automatically - * - connectAllInputsToFirstOutput : [true,false] all found midi input devices will be automatically connected to the first found midi output device - * - javaDir : [string] the folder where you store the midiapplet.jar on your webserver, defaults to "java" - */ - midiBridge.init = function(arg) { - - //var args = Array.prototype.slice.call(arguments); - if( typeof arg === "function") { - ondata = arg; - } else if( typeof arg === "object") { - var config = arg; - connectAllInputs = config.connectAllInputs; - connectFirstInput = config.connectFirstInput; - connectFirstOutput = config.connectFirstOutput; - connectAllInputsToFirstOutput = config.connectAllInputsToFirstOutput; - ondata = config.data; - onready = config.ready; - onerror = config.error; - switch(true) { - case connectAllInputs && connectFirstOutput: - connectAllInputs = false; - connectFirstInput = false; - connectFirstOutput = false; - connectAllInputsToFirstOutput = true; - break; - case connectAllInputsToFirstOutput: - connectAllInputs = false; - connectFirstInput = false; - connectFirstInput = false; - connectFirstOutput = false; - break; - case connectFirstInput: - connectAllInputs = false; - connectAllInputsToFirstOutput = false; - break; - case connectFirstOutput: - connectAllInputs = false; - connectAllInputsToFirstOutput = false; - break; - case connectAllInputs: - connectFirstInput = false; - connectFirstOutput = false; - connectAllInputsToFirstOutput = false; - break; - } - } - - /** - * Very simple java plugin detection - */ - if(!navigator.javaEnabled()) { - if(onerror) { - onerror("no java plugin found; install or enable the java plugin") - } else { - console.log("no java plugin found; install or enable the java plugin"); - } - return; - } - - /** - * If you are using the JSON parse method of your favorite Javascript framework replace the followingn lines by onlu: - * - * loadJava(); - */ - - loadJava(); - - }; - - /** - * static method called by the applet - */ - midiBridge.msgFromJava = function(jsonString) { - var data = parseJSON(jsonString); - var msgId = data.msgId; - //console.log(jsonString); - //console.log(msgId); - switch(msgId) { - case "upgrade-java": - if(onerror) { - onerror("please upgrade your java plugin!") - } else { - console.log("please upgrade your java plugin!"); - } - break; - case "midi-started": - getApplet(); - if(applet) { - devices = data.devices; - midiBridge.ready = true; - if(connectAllInputs) { - midiBridge.connectAllInputs(); - } - if(connectFirstInput) { - midiBridge.connectFirstInput(); - } - if(connectFirstOutput) { - midiBridge.connectFirstOutput(); - } - if(connectAllInputsToFirstOutput) { - midiBridge.connectAllInputsToFirstOutput(); - } - if(onready) { - onready("midibridge started"); - } - } - //console.log("applet:",applet); - break; - case "midi-data": - if(ondata) { - ondata(new MidiMessage(data)); - } - break; - case "error": - if(onerror) { - onerror(data.code); - } - break; - } - }; - - /** - * Send a midi event from javascript to java - * @param status : the midi status byte, e.g. NOTE ON, NOTE OFF, PITCH BEND and so on - * @param channel : the midi channel that this event will be sent to 0 - 15 - * @param data1 : the midi note number - * @param data2 : the second data byte, when the status byte is NOTE ON or NOTE OFF, data2 is the velocity - */ - midiBridge.sendMidiEvent = function(status, channel, data1, data2) { - if(checkIfReady()) { - return parseJSON(applet.processMidiEvent(status, channel, data1, data2)); - } - }; - - /** - * Get the list of all currently connected midi devices - */ - midiBridge.getDevices = function() { - return devices; - }; - - /** - * Refresh the list of all currently connected midi devices - */ - midiBridge.refreshDevices = function() { - if(checkIfReady()) { - return parseJSON(applet.getDevices()); - } - }; - - /** - * Connect all found midi inputs to the midibridge right after the midibridge has been initialized - */ - midiBridge.connectAllInputs = function() { - if(checkIfReady()) { - return parseJSON(applet.connectAllInputs()); - } - }; - - /** - * Connect the first found midi input to the midibridge right after the midibridge has been initialized - */ - midiBridge.connectFirstInput = function() { - if(checkIfReady()) { - return parseJSON(applet.connectFirstInput()); - } - }; - - /** - * Connect the first found midi output to the midibridge right after the midibridge has been initialized - */ - midiBridge.connectFirstOutput = function() { - if(checkIfReady()) { - return parseJSON(applet.connectFirstOutput()); - } - }; - - /** - * Connect the first found midi output to all connected midi inputs right after the midibridge has been initialized - */ - midiBridge.connectAllInputsToFirstOutput = function() { - if(checkIfReady()) { - return parseJSON(applet.connectAllInputsToFirstOutput()); - } - }; - - /** - * Connect midi a midi input to the bridge, and/or a midi input to a midi output - * @param midiInId : [int] id of the midi input that will be connected to the bridge, use the ids as retrieved by getDevices() - * @param midiOutId : [int] optional, the id of the midi output that will be connected to the chosen midi input - * @param filter : [array] an array containing status codes that will *not* be sent from the chosen midi input to the chosen midi output - * e.g. if you supply the array [midiBridge.PITCH_BEND, midiBridge.POLY_PRESSURE], pitch bend and poly pressure midi messages will not be forwarded to the output - */ - midiBridge.addConnection = function(midiInId, midiOutId, filter) { - if(checkIfReady()) { - midiOutId = midiOutId == undefined ? -1 : midiOutId; - filter = filter == undefined ? [] : filter; - return parseJSON(applet.addConnection(midiInId, midiOutId, filter)); - } - }; - - /** - * Remove a midi connection between between an input and the midibridge, and/or the given in- and output - * @param midiIdIn : [int] the midi input - * @param midiIdOut : [int] optional, the midi output - */ - midiBridge.removeConnection = function(midiInId, midiOutId) { - if(checkIfReady()) { - return parseJSON(applet.removeConnection(midiInId, midiOutId)); - } - }; - - /** - * All previously setup midi connections will be disconnected - */ - midiBridge.disconnectAll = function() { - if(checkIfReady()) { - return parseJSON(applet.disconnectAll()); - } - }; - - midiBridge.loadBase64String = function(data){ - return parseJSON(applet.loadBase64String(data)); - } - - midiBridge.playBase64String = function(data){ - return parseJSON(applet.playBase64String(data)); - } - - midiBridge.loadMidiFile = function(url){ - return parseJSON(applet.loadMidiFile(url)); - } - - midiBridge.playMidiFile = function(url){ - return parseJSON(applet.playMidiFile(url)); - } - - midiBridge.startSequencer = function(){ - applet.startSequencer(); - } - - midiBridge.pauseSequencer = function(){ - applet.pauseSequencer(); - } - - midiBridge.stopSequencer = function(){ - applet.stopSequencer(); - } - - midiBridge.closeSequencer = function(){ - applet.closeSequencer(); - } - - midiBridge.getSequencerPosition = function(){ - return applet.getSequencerPosition(); - } - - midiBridge.setSequencerPosition = function(pos){ - applet.setSequencerPosition(pos); - } - - /** - * Check if a midiBridge function is called before initialization - */ - function checkIfReady() { - if(!midiBridge.ready) { - if(onerror) { - onerror("midibridge not ready!"); - } - return "midibridge not ready!"; - } - return true; - } - - /** - * A div with the applet object is added to the body of your html document - */ - function loadJava() { - //console.log("loadJava"); - var javaDiv = document.createElement("div"); - javaDiv.setAttribute("id", "midibridge-java"); - var html = ""; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - html += ''; - //html += 'Your browser needs the Java plugin to use the midibridge. You can download it here'; - html += ''; - javaDiv.innerHTML = html; - document.body.appendChild(javaDiv); - } - - /** - * class MidiMessage is used to wrap the midi note data that arrives from the applet - */ - var MidiMessage = (function()//constructor - { - var _constructor = function(data) { - this.data1 = data.data1; - this.data2 = data.data2; - this.status = data.status; - this.status = this.data2 == 0 && this.status == midiBridge.NOTE_ON ? midiBridge.NOTE_OFF : this.status; - this.channel = data.channel; - this.noteName = midiBridge.getNoteName(this.data1, midiBridge.noteNameModus); - this.statusCode = midiBridge.getStatus(this.status); - this.microsecond = data.microsecond; - this.time = midiBridge.getNiceTime(this.microsecond); - }; - - _constructor.prototype = { - toString : function() { - var s = ""; - s += this.noteName + " " + this.statusCode + " " + this.data1 + " " + this.data2 + " " + this.status; - s += this.microsecond ? this.microsecond + " " + this.time : ""; - //console.log(s); - return s; - }, - toJSONString : function() { - var s; - if(this.microsecond){ - s= "{'notename':" + this.noteName + ", 'status':" + this.status + ", 'data1':" + this.data1 + ", 'data2':" + this.data2 + ", 'microsecond':" + this.microsecond + ", 'time':" + this.time + "}"; - }else{ - s= "{'notename':" + this.noteName + ", 'status':" + this.status + ", 'data1':" + this.data1 + ", 'data2':" + this.data2 + "}"; - } - //console.log(s); - return s; - } - } - - return _constructor; - })(); - - - midiBridge.getNoteName = function(noteNumber, mode) { - - var octave = Math.floor(((noteNumber) / 12) - 1); - var noteName = noteNames[mode][noteNumber % 12]; - return noteName + "" + octave; - }; - - - midiBridge.getNoteNumber = function(noteName, octave) { - var index = -1; - noteName = noteName.toUpperCase(); - for(var key in noteNames) { - var modus = noteNames[key]; - for(var i = 0, max = modus.length; i < max; i++) { - if(modus[i] === noteName) { - index = i; - break; - } - } - } - if(index === -1) { - return "invalid note name"; - } - noteNumber = (12 + index) + (octave * 12); - return noteNumber; - } - - - midiBridge.getStatus = function($statusCode) { - return status[$statusCode]; - }; - - midiBridge.getNiceTime = function(microseconds) - { - //console.log(microseconds); - var r = ""; - - var t = (microseconds / 1000 / 1000) >> 0; - var h = (t / (60 * 60)) >> 0; - var m = ((t % (60 * 60)) / 60) >> 0; - var s = t % (60); - var ms = (((microseconds /1000) - (h * 3600000) - (m * 60000) - (s * 1000)) + 0.5) >> 0; - - //console.log(t,h,m,s,ms); - - r += h > 0 ? h + ":" : ""; - r += h > 0 ? m < 10 ? "0" + m : m : m; - r += ":"; - r += s < 10 ? "0" + s : s; - r += ":"; - r += ms == 0 ? "000" : ms < 10 ? "00" + ms : ms < 100 ? "0" + ms : ms; - - return r; - } - - - function getApplet() { - try { - applet = midiBridge.getObject("midibridge-applet"); - } catch(e) { - //console.log(e) - //Firefox needs more time to initialize the Applet - setTimeout(getApplet, 25); - return; - } - } - - midiBridge.getObject = function(objectName) { - var ua = navigator.userAgent.toLowerCase(); - //console.log(ua); - if(ua.indexOf("msie") !== -1 || ua.indexOf("webkit") !== -1) { - return window[objectName]; - } else { - return document[objectName]; - } - } - - //add addEventListener to IE8 - if(!window.addEventListener) { - window.addEventListener = function($id, $callback, $bubble) { - window.attachEvent('onload', $callback); - } - - } - - window.midiBridge = midiBridge; - -})(window); \ No newline at end of file diff --git a/js/MIDI/Plugin.js b/js/MIDI/Plugin.js index 76a9f92..f44db87 100644 --- a/js/MIDI/Plugin.js +++ b/js/MIDI/Plugin.js @@ -371,98 +371,6 @@ if (window.Audio) (function () { }; })(); -/* - -------------------------------------------- - Java - Native Soundbank - -------------------------------------------- - https://github.com/abudaan/midibridge-js - http://java.sun.com/products/java-media/sound/soundbanks.html - -------------------------------------------- -*/ - -(function () { - var root = MIDI.Java = {}; - root.connect = function (callback) { - // deferred loading of - MIDI.Plugin = false; - if (!window.navigator.javaEnabled()) { - MIDI.Flash.connect(callback); - return; - } - MIDI.Java.callback = callback; - var iframe = document.createElement('iframe'); - iframe.name = 'MIDIFrame'; - iframe.src = 'inc/midibridge/index.html'; - iframe.width = 1; - iframe.height = 1; - document.body.appendChild(iframe); - }; - - root.confirm = function (plugin) { - - MIDI.programChange = function (channel, program) { - plugin.sendMidiEvent(0xC0, channel, program, 0); - }; - - MIDI.setVolume = function (n) { - - }; - - MIDI.noteOn = function (channel, note, velocity, delay) { - if (delay) { - var interval = window.setTimeout(function() { - plugin.sendMidiEvent(0x90, channel, note, velocity); - }, delay * 1000); - return interval; - } else { - plugin.sendMidiEvent(0x90, channel, note, velocity); - } - }; - - MIDI.noteOff = function (channel, note, delay) { - if (delay) { - var interval = window.setTimeout(function() { - plugin.sendMidiEvent(0x80, channel, note, 0); - }, delay * 1000); - return interval; - } else { - plugin.sendMidiEvent(0x80, channel, note, 0); - } - }; - - MIDI.chordOn = function (channel, chord, velocity, delay) { - for (var key in chord) { - var n = chord[key]; - plugin.sendMidiEvent(0x90, channel, n, 100); - } - }; - - MIDI.chordOff = function (channel, chord, delay) { - for (var key in chord) { - var n = chord[key]; - plugin.sendMidiEvent(0x80, channel, n, 100); - } - }; - - MIDI.stopAllNotes = function () { - - }; - - MIDI.getInstruments = function() { - return []; - }; - - if (plugin.ready) { - MIDI.lang = "Java"; - if (MIDI.Java.callback) { - MIDI.Java.callback(); - } - } else { - MIDI.Flash.connect(MIDI.Java.callback); - } - }; -})(); - /* helper functions */ diff --git a/js/MIDI/loadPlugin.js b/js/MIDI/loadPlugin.js index 9dc05ed..8c6194f 100644 --- a/js/MIDI/loadPlugin.js +++ b/js/MIDI/loadPlugin.js @@ -62,12 +62,6 @@ MIDI.loadPlugin = function(conf) { var connect = {}; -connect.java = function(filetype, instruments, callback) { - // works well cross-browser, and fully featured, but has delay when Java machine starts. - if (MIDI.loader) MIDI.loader.message("Java API..."); - MIDI.Java.connect(callback); -}; - connect.flash = function(filetype, instruments, callback) { // fairly quick, but requires loading of individual MP3s (more http requests). if (MIDI.loader) MIDI.loader.message("Flash API...");