remove midi bridge from repo

master
Michael Deal 2013-01-23 00:39:05 -08:00
parent 808b9c95a7
commit 492819fc5f
7 changed files with 0 additions and 723 deletions

View File

@ -84,7 +84,6 @@ MIDI.Player.setAnimation(function(data) {
<h3>Many thanks to the authors of these libraries;</h3>
* <a href="http://dev.w3.org/html5/spec/Overview.html">&lt;audio&gt;</a>: HTML5 specs
* <a href="https://dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html">WebAudioAPI</a>: W3C proposal by Google
* Java package: <a href="https://github.com/abudaan/midibridge-js">MIDIBridge</a> by <a href="http://abumarkub.net">Daniel van der Meer</a>. Supports MIDI keyboard, and 128 General MIDI instruments.
* Flash package: <a href="http://www.schillmania.com/projects/soundmanager2/">SoundManager2</a> by <a href="http://schillmania.com">Scott Schiller</a>
* <a href="https://github.com/gasman/jasmid">jasmid</a>: Reads MIDI file byte-code, and translats into a Javascript array.
* <a href="http://blog.danguer.com/2011/10/24/base64-binary-decoding-in-javascript/">base642binary.js</a>: Cleans up XML base64-requests for Web Audio API.

View File

@ -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

View File

@ -1,83 +0,0 @@
<!doctype html>
<html xmlns="http://www.w3.org/1999/xhtml">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="Cache-Control" Content="no-cache">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<script type="text/javascript" src="lib/MidiBridge.js"></script>
<script type="text/javascript">
window.onload = function() {
var jsmidi = parent.jsmidi;
var notes = {};
var events = {};
var startTime = 0;
var eventTimeOn = {};
var eventTimeOff = {};
for (var key in parent.MIDI.noteToKey) {
events[key] = [];
eventTimeOn[key] = 0;
eventTimeOff[key] = 0;
}
parent.writeMIDI = function() {
var tracks = [];
for (var key in events) {
tracks.push(new jsmidi.MidiTrack({ events: events[key] }));
}
var song = jsmidi.MidiWriter({ tracks: tracks });
return "data:audio/mid;base64," + song.b64;
};
midiBridge.init({
connectAllInputsToFirstOutput: true,
data: function(event) {
if (!(event.status == 128 || event.status == 144)) return;
//
var noteName = event.noteName;
var now = (new Date()).getTime();
var id = parseInt(event.data1);
var velocity = parseInt(event.data2);
//
if (event.status == midiBridge.NOTE_ON) {
console.log(noteName, "on");
//
eventTimeOn[id] = now;
//
} else {
console.log(id, noteName, "off")
if (!startTime) startTime = now;
if (!eventTimeOn[id]) eventTimeOn[id] = startTime;
if (!eventTimeOff[id]) eventTimeOff[id] = startTime;
//
var begin = now - eventTimeOff[id];
var end = now - eventTimeOn[id];
var duration = Math.max(0, begin - end);
//
var note = {
duration: duration,
channel: 0,
pitch: id,
volume: velocity
};
//
events[id].push(jsmidi.MidiEvent.noteOn(note));
note.duration = end;
console.log('begin', begin, 'end', end, begin-end);
events[id].push(jsmidi.MidiEvent.noteOff(note));
//
eventTimeOff[id] = now;
}
},
ready: function() {
if (typeof(MIDI) === "undefined") var MIDI = {};
MIDI.Plugin = midiBridge;
if (parent.MIDI && parent.MIDI.Java) {
parent.MIDI.Java.confirm(MIDI.Plugin);
}
}
});
};
</script>
<body></body>
</html>

Binary file not shown.

View File

@ -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 += '<object tabindex="0" id="midibridge-applet" type="application/x-java-applet" height="1" width="1">';
html += '<param name="codebase" value="' + javaDir + '/" />';
html += '<param name="archive" value="midiapplet.jar" />';
html += '<param name="code" value="net.abumarkub.midi.applet.MidiApplet" />';
html += '<param name="scriptable" value="true" />';
html += '<param name="minJavaVersion" value="1.5" />';
//html += 'Your browser needs the Java plugin to use the midibridge. You can download it <a href="http://www.java.com/en/" target="blank" title="abumarkub midibridge download java" rel="abumarkub midibridge download java">here</a>';
html += '</object>';
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);

View File

@ -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 <applet>
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
*/

View File

@ -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...");