2012-02-16 05:46:03 +01:00
/ *
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2013-01-27 07:44:14 +01:00
MIDI . Plugin : 0.3 . 2 : 2013 / 01 / 26
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2013-01-12 03:05:42 +01:00
https : //github.com/mudcube/MIDI.js
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2013-01-25 18:33:47 +01:00
Inspired by javax . sound . midi ( albeit a super simple version ) :
http : //docs.oracle.com/javase/6/docs/api/javax/sound/midi/package-summary.html
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Technologies :
2013-01-27 07:44:14 +01:00
MIDI . WebMIDI
MIDI . WebAudio
2013-01-25 08:50:08 +01:00
MIDI . Flash
2013-01-27 07:44:14 +01:00
MIDI . AudioTag
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2013-01-25 08:50:08 +01:00
Helpers :
MIDI . GeneralMIDI
MIDI . channels
MIDI . keyToNote
MIDI . noteToKey
2012-02-16 05:46:03 +01:00
* /
if ( typeof ( MIDI ) === "undefined" ) var MIDI = { } ;
( function ( ) { "use strict" ;
2013-01-26 07:00:09 +01:00
var setPlugin = function ( root ) {
2013-01-27 05:45:41 +01:00
MIDI . api = root . api ;
2013-01-26 07:00:09 +01:00
MIDI . setVolume = root . setVolume ;
MIDI . programChange = root . programChange ;
MIDI . noteOn = root . noteOn ;
MIDI . noteOff = root . noteOff ;
MIDI . chordOn = root . chordOn ;
MIDI . chordOff = root . chordOff ;
MIDI . stopAllNotes = root . stopAllNotes ;
MIDI . getInput = root . getInput ;
MIDI . getOutputs = root . getOutputs ;
} ;
2013-01-25 08:50:08 +01:00
/ *
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
Web MIDI API - Native Soundbank
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
https : //dvcs.w3.org/hg/audio/raw-file/tip/midi/specification.html
2013-01-26 06:31:02 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2013-01-25 08:50:08 +01:00
* /
( function ( ) {
var plugin = null ;
var output = null ;
var channels = [ ] ;
2013-01-26 07:00:09 +01:00
var root = MIDI . WebMIDI = {
2013-01-27 05:45:41 +01:00
api : "webmidi"
2013-01-26 07:00:09 +01:00
} ;
2013-01-25 09:11:41 +01:00
root . setVolume = function ( channel , volume ) { // set channel volume
output . send ( [ 0xB0 + channel , 0x07 , volume ] ) ;
2013-01-25 08:50:08 +01:00
} ;
2013-01-25 09:11:41 +01:00
root . programChange = function ( channel , program ) { // change channel instrument
output . send ( [ 0xC0 + channel , program ] ) ;
2013-01-25 08:50:08 +01:00
} ;
2013-01-25 09:11:41 +01:00
root . noteOn = function ( channel , note , velocity , delay ) {
2013-01-25 08:50:08 +01:00
output . send ( [ 0x90 + channel , note , velocity ] , delay * 1000 ) ;
} ;
2013-01-25 09:11:41 +01:00
root . noteOff = function ( channel , note , delay ) {
2013-01-26 07:00:09 +01:00
output . send ( [ 0x80 + channel , note , 0 ] , delay * 1000 ) ;
2013-01-25 08:50:08 +01:00
} ;
2013-01-25 09:11:41 +01:00
root . chordOn = function ( channel , chord , velocity , delay ) {
2013-01-25 08:50:08 +01:00
for ( var n = 0 ; n < chord . length ; n ++ ) {
var note = chord [ n ] ;
output . send ( [ 0x90 + channel , note , velocity ] , delay * 1000 ) ;
}
} ;
2013-01-25 09:11:41 +01:00
root . chordOff = function ( channel , chord , delay ) {
2013-01-25 08:50:08 +01:00
for ( var n = 0 ; n < chord . length ; n ++ ) {
var note = chord [ n ] ;
2013-01-26 07:00:09 +01:00
output . send ( [ 0x80 + channel , note , 0 ] , delay * 1000 ) ;
2013-01-25 08:50:08 +01:00
}
} ;
2013-01-25 09:11:41 +01:00
root . stopAllNotes = function ( ) {
2013-01-25 08:50:08 +01:00
for ( var channel = 0 ; channel < 16 ; channel ++ ) {
output . send ( [ 0xB0 + channel , 0x7B , 0 ] ) ;
}
} ;
2013-01-25 09:11:41 +01:00
root . getInput = function ( ) {
2013-01-25 08:50:08 +01:00
return plugin . getInputs ( ) ;
} ;
2013-01-25 09:11:41 +01:00
root . getOutputs = function ( ) {
2013-01-25 08:50:08 +01:00
return plugin . getOutputs ( ) ;
} ;
2013-01-25 09:11:41 +01:00
2013-01-27 05:45:41 +01:00
root . connect = function ( conf ) {
2013-01-26 07:00:09 +01:00
setPlugin ( root ) ;
2013-01-25 09:11:41 +01:00
navigator . requestMIDIAccess ( function ( access ) {
plugin = access ;
output = plugin . getOutput ( 0 ) ;
2013-01-27 05:45:41 +01:00
if ( conf . callback ) conf . callback ( ) ;
} , function ( err ) { // well at least we tried!
if ( window . webkitAudioContext ) { // Chrome
conf . api = "webaudio" ;
} else if ( window . Audio ) { // Firefox
conf . api = "audiotag" ;
} else { // Internet Explorer
conf . api = "flash" ;
}
MIDI . loadPlugin ( conf ) ;
2013-01-25 09:11:41 +01:00
} ) ;
} ;
2013-01-25 08:50:08 +01:00
} ) ( ) ;
2012-02-16 05:46:03 +01:00
/ *
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
Web Audio API - OGG or MPEG Soundbank
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
https : //dvcs.w3.org/hg/audio/raw-file/tip/webaudio/specification.html
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
* /
if ( window . AudioContext || window . webkitAudioContext ) ( function ( ) {
var AudioContext = window . AudioContext || window . webkitAudioContext ;
2013-01-27 07:44:14 +01:00
var root = MIDI . WebAudio = {
2013-01-27 05:45:41 +01:00
api : "webaudio"
2013-01-26 07:00:09 +01:00
} ;
2012-02-16 05:46:03 +01:00
var ctx ;
var sources = { } ;
2013-01-26 07:00:09 +01:00
var masterVolume = 127 ;
2012-02-16 05:46:03 +01:00
var audioBuffers = { } ;
2012-11-21 10:57:54 +01:00
var audioLoader = function ( instrument , urlList , index , bufferList , callback ) {
var synth = MIDI . GeneralMIDI . byName [ instrument ] ;
var instrumentId = synth . number ;
2012-02-16 05:46:03 +01:00
var url = urlList [ index ] ;
2012-11-21 10:57:54 +01:00
var base64 = MIDI . Soundfont [ instrument ] [ url ] . split ( "," ) [ 1 ] ;
2012-02-16 05:46:03 +01:00
var buffer = Base64Binary . decodeArrayBuffer ( base64 ) ;
ctx . decodeAudioData ( buffer , function ( buffer ) {
2012-11-21 10:57:54 +01:00
var msg = url ;
while ( msg . length < 3 ) msg += " " ;
2013-01-12 03:05:42 +01:00
if ( typeof ( MIDI . loader ) !== "undefined" ) {
MIDI . loader . update ( null , synth . instrument + "<br>Processing: " + ( index / 87 * 100 >> 0 ) + "%<br>" + msg ) ;
2012-02-16 05:46:03 +01:00
}
buffer . id = url ;
bufferList [ index ] = buffer ;
//
if ( bufferList . length === urlList . length ) {
while ( bufferList . length ) {
buffer = bufferList . pop ( ) ;
2012-11-21 10:57:54 +01:00
if ( ! buffer ) continue ;
2012-02-16 05:46:03 +01:00
var nodeId = MIDI . keyToNote [ buffer . id ] ;
2012-11-21 10:57:54 +01:00
audioBuffers [ instrumentId + "" + nodeId ] = buffer ;
2012-02-16 05:46:03 +01:00
}
2012-11-21 10:57:54 +01:00
callback ( instrument ) ;
2012-02-16 05:46:03 +01:00
}
} ) ;
} ;
2013-01-26 07:00:09 +01:00
root . setVolume = function ( channel , volume ) {
masterVolume = volume ;
2012-02-16 05:46:03 +01:00
} ;
2012-11-21 10:57:54 +01:00
root . programChange = function ( channel , program ) {
MIDI . channels [ channel ] . instrument = program ;
2012-02-16 05:46:03 +01:00
} ;
root . noteOn = function ( channel , note , velocity , delay ) {
/// check whether the note exists
2012-11-21 10:57:54 +01:00
if ( ! MIDI . channels [ channel ] ) return ;
var instrument = MIDI . channels [ channel ] . instrument ;
if ( ! audioBuffers [ instrument + "" + note ] ) return ;
2012-02-16 05:46:03 +01:00
/// convert relative delay to absolute delay
if ( delay < ctx . currentTime ) delay += ctx . currentTime ;
/// crate audio buffer
var source = ctx . createBufferSource ( ) ;
sources [ channel + "" + note ] = source ;
2012-11-21 10:57:54 +01:00
source . buffer = audioBuffers [ instrument + "" + note ] ;
2012-02-16 05:46:03 +01:00
source . connect ( ctx . destination ) ;
2012-11-21 08:11:18 +01:00
///
2012-02-16 05:46:03 +01:00
var gainNode = ctx . createGainNode ( ) ;
2013-01-26 07:00:09 +01:00
var value = ( velocity / 127 ) * ( masterVolume / 127 ) * 2 - 1 ;
2012-02-16 05:46:03 +01:00
gainNode . connect ( ctx . destination ) ;
2013-01-21 19:10:44 +01:00
gainNode . gain . value = Math . max ( - 1 , value ) ;
2012-02-16 05:46:03 +01:00
source . connect ( gainNode ) ;
source . noteOn ( delay || 0 ) ;
return source ;
} ;
root . noteOff = function ( channel , note , delay ) {
2012-11-21 08:11:18 +01:00
delay = delay || 0 ;
2013-01-25 18:33:47 +01:00
if ( delay < ctx . currentTime ) delay += ctx . currentTime ;
2012-11-21 10:57:54 +01:00
var source = sources [ channel + "" + note ] ;
2012-11-21 04:19:25 +01:00
if ( ! source ) return ;
2013-01-25 18:50:14 +01:00
// @Miranet: "the values of 0.2 and 0.3 could ofcourse be used as
2013-01-25 18:33:47 +01:00
// a 'release' parameter for ADSR like time settings."
2013-01-26 07:00:09 +01:00
// add { "metadata": { release: 0.3 } } to soundfont files
2012-11-21 04:19:25 +01:00
source . gain . linearRampToValueAtTime ( 1 , delay ) ;
2013-01-25 18:50:14 +01:00
source . gain . linearRampToValueAtTime ( 0 , delay + 0.2 ) ;
source . noteOff ( delay + 0.3 ) ;
2012-11-21 04:19:25 +01:00
return source ;
2012-02-16 05:46:03 +01:00
} ;
2013-01-25 09:11:41 +01:00
root . chordOn = function ( channel , chord , velocity , delay ) {
var ret = { } , note ;
for ( var n = 0 , length = chord . length ; n < length ; n ++ ) {
ret [ note = chord [ n ] ] = root . noteOn ( channel , note , velocity , delay ) ;
}
return ret ;
} ;
2012-02-16 05:46:03 +01:00
root . chordOff = function ( channel , chord , delay ) {
2012-11-21 10:57:54 +01:00
var ret = { } , note ;
for ( var n = 0 , length = chord . length ; n < length ; n ++ ) {
ret [ note = chord [ n ] ] = root . noteOff ( channel , note , delay ) ;
}
return ret ;
2012-02-16 05:46:03 +01:00
} ;
2013-01-27 05:45:41 +01:00
root . connect = function ( conf ) {
2013-01-26 07:00:09 +01:00
setPlugin ( root ) ;
2012-02-16 05:46:03 +01:00
//
MIDI . Player . ctx = ctx = new AudioContext ( ) ;
///
var urlList = [ ] ;
var keyToNote = MIDI . keyToNote ;
for ( var key in keyToNote ) urlList . push ( key ) ;
var bufferList = [ ] ;
2012-11-21 10:57:54 +01:00
var pending = { } ;
var oncomplete = function ( instrument ) {
delete pending [ instrument ] ;
for ( var key in pending ) break ;
2013-01-27 05:45:41 +01:00
if ( ! key ) conf . callback ( ) ;
2012-11-21 10:57:54 +01:00
} ;
for ( var instrument in MIDI . Soundfont ) {
pending [ instrument ] = true ;
for ( var i = 0 ; i < urlList . length ; i ++ ) {
audioLoader ( instrument , urlList , i , bufferList , oncomplete ) ;
}
2012-02-16 05:46:03 +01:00
}
} ;
} ) ( ) ;
/ *
2013-01-26 06:31:02 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-11-21 10:57:54 +01:00
AudioTag < audio > - OGG or MPEG Soundbank
2013-01-26 06:31:02 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
http : //dev.w3.org/html5/spec/Overview.html#the-audio-element
2013-01-26 06:31:02 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
* /
if ( window . Audio ) ( function ( ) {
2013-01-26 07:00:09 +01:00
var root = MIDI . AudioTag = {
2013-01-27 05:45:41 +01:00
api : "audiotag"
2013-01-26 07:00:09 +01:00
} ;
2012-02-16 05:46:03 +01:00
var note2id = { } ;
2013-01-28 21:27:53 +01:00
var volume = 127 ; // floating point
2012-02-16 05:46:03 +01:00
var channel _nid = - 1 ; // current channel
var channels = [ ] ; // the audio channels
var notes = { } ; // the piano keys
for ( var nid = 0 ; nid < 12 ; nid ++ ) {
channels [ nid ] = new Audio ( ) ;
}
2012-11-21 10:57:54 +01:00
var playChannel = function ( channel , note ) {
if ( ! MIDI . channels [ channel ] ) return ;
var instrument = MIDI . channels [ channel ] . instrument ;
var id = MIDI . GeneralMIDI . byId [ instrument ] . id ;
var note = notes [ note ] ;
2012-02-16 05:46:03 +01:00
if ( ! note ) return ;
var nid = ( channel _nid + 1 ) % channels . length ;
var time = ( new Date ( ) ) . getTime ( ) ;
var audio = channels [ nid ] ;
2012-11-21 10:57:54 +01:00
audio . src = MIDI . Soundfont [ id ] [ note . id ] ;
2013-01-28 21:27:53 +01:00
audio . volume = volume / 127 ;
2012-02-16 05:46:03 +01:00
audio . play ( ) ;
channel _nid = nid ;
} ;
2012-11-21 10:57:54 +01:00
root . programChange = function ( channel , program ) {
MIDI . channels [ channel ] . instrument = program ;
2012-02-16 05:46:03 +01:00
} ;
2012-11-21 10:57:54 +01:00
2013-01-26 07:00:09 +01:00
root . setVolume = function ( channel , n ) {
volume = n ; //- should be channel specific volume
2012-02-16 05:46:03 +01:00
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . noteOn = function ( channel , note , velocity , delay ) {
var id = note2id [ note ] ;
if ( ! notes [ id ] ) return ;
if ( delay ) {
2013-01-26 00:33:50 +01:00
return window . setTimeout ( function ( ) {
2012-11-21 10:57:54 +01:00
playChannel ( channel , id ) ;
2012-02-16 05:46:03 +01:00
} , delay * 1000 ) ;
} else {
2012-11-21 10:57:54 +01:00
playChannel ( channel , id ) ;
2012-02-16 05:46:03 +01:00
}
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . noteOff = function ( channel , note , delay ) {
2013-01-26 06:31:02 +01:00
setTimeout ( function ( ) {
channels [ channel ] . pause ( ) ;
} , delay * 1000 )
2012-02-16 05:46:03 +01:00
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . chordOn = function ( channel , chord , velocity , delay ) {
2013-01-26 06:31:02 +01:00
for ( var idx = 0 ; idx < chord . length ; idx ++ ) {
var n = chord [ idx ] ;
2012-02-16 05:46:03 +01:00
var id = note2id [ n ] ;
if ( ! notes [ id ] ) continue ;
2013-01-26 06:31:02 +01:00
if ( delay ) {
return window . setTimeout ( function ( ) {
playChannel ( channel , id ) ;
} , delay * 1000 ) ;
} else {
playChannel ( channel , id ) ;
}
2012-02-16 05:46:03 +01:00
}
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . chordOff = function ( channel , chord , delay ) {
2013-01-26 06:31:02 +01:00
for ( var idx = 0 ; idx < chord . length ; idx ++ ) {
var n = chord [ idx ] ;
var id = note2id [ n ] ;
if ( ! notes [ id ] ) continue ;
if ( delay ) {
return window . setTimeout ( function ( ) {
channels [ channel ] . pause ( ) ;
} , delay * 1000 ) ;
} else {
channels [ channel ] . pause ( ) ;
}
}
2012-02-16 05:46:03 +01:00
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . stopAllNotes = function ( ) {
for ( var nid = 0 , length = channels . length ; nid < length ; nid ++ ) {
channels [ nid ] . pause ( ) ;
}
} ;
2013-01-26 06:31:02 +01:00
2013-01-27 05:45:41 +01:00
root . connect = function ( conf ) {
2012-02-16 05:46:03 +01:00
var loading = { } ;
for ( var key in MIDI . keyToNote ) {
note2id [ MIDI . keyToNote [ key ] ] = key ;
notes [ key ] = {
id : key
} ;
}
2013-01-26 07:00:09 +01:00
setPlugin ( root ) ;
2012-11-21 10:57:54 +01:00
///
2013-01-27 05:45:41 +01:00
if ( conf . callback ) conf . callback ( ) ;
2012-02-16 05:46:03 +01:00
} ;
} ) ( ) ;
/ *
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
Flash - MP3 Soundbank
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
http : //www.schillmania.com/projects/soundmanager2/
2012-11-21 10:57:54 +01:00
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
2012-02-16 05:46:03 +01:00
* /
( function ( ) {
2013-01-26 07:00:09 +01:00
var root = MIDI . Flash = {
2013-01-27 05:45:41 +01:00
api : "flash"
2013-01-26 07:00:09 +01:00
} ;
2012-02-16 05:46:03 +01:00
var noteReverse = { } ;
var notes = { } ;
2012-11-21 10:57:54 +01:00
root . programChange = function ( channel , program ) {
MIDI . channels [ channel ] . instrument = program ;
2012-02-16 05:46:03 +01:00
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . setVolume = function ( channel , note ) {
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . noteOn = function ( channel , note , velocity , delay ) {
2012-11-21 10:57:54 +01:00
if ( ! MIDI . channels [ channel ] ) return ;
var instrument = MIDI . channels [ channel ] . instrument ;
var id = MIDI . GeneralMIDI . byId [ instrument ] . number ;
note = id + "" + noteReverse [ note ] ;
if ( ! notes [ note ] ) return ;
2012-02-16 05:46:03 +01:00
if ( delay ) {
2013-01-26 00:33:50 +01:00
return window . setTimeout ( function ( ) {
2012-11-21 10:57:54 +01:00
notes [ note ] . play ( { volume : velocity * 2 } ) ;
2012-02-16 05:46:03 +01:00
} , delay * 1000 ) ;
} else {
2012-11-21 10:57:54 +01:00
notes [ note ] . play ( { volume : velocity * 2 } ) ;
2012-02-16 05:46:03 +01:00
}
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . noteOff = function ( channel , note , delay ) {
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . chordOn = function ( channel , chord , velocity , delay ) {
2012-11-21 10:57:54 +01:00
if ( ! MIDI . channels [ channel ] ) return ;
var instrument = MIDI . channels [ channel ] . instrument ;
var id = MIDI . GeneralMIDI . byId [ instrument ] . number ;
2012-02-16 05:46:03 +01:00
for ( var key in chord ) {
var n = chord [ key ] ;
2012-11-21 10:57:54 +01:00
var note = id + "" + noteReverse [ n ] ;
if ( notes [ note ] ) {
notes [ note ] . play ( { volume : velocity * 2 } ) ;
2012-02-16 05:46:03 +01:00
}
}
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . chordOff = function ( channel , chord , delay ) {
} ;
2012-11-21 10:57:54 +01:00
2012-02-16 05:46:03 +01:00
root . stopAllNotes = function ( ) {
} ;
2012-11-21 10:57:54 +01:00
2013-01-27 05:45:41 +01:00
root . connect = function ( conf ) {
2012-02-16 05:46:03 +01:00
soundManager . flashVersion = 9 ;
soundManager . useHTML5Audio = true ;
2012-04-14 06:59:48 +02:00
soundManager . url = '../inc/SoundManager2/swf/' ;
2012-02-16 05:46:03 +01:00
soundManager . useHighPerformance = true ;
soundManager . wmode = 'transparent' ;
soundManager . flashPollingInterval = 1 ;
soundManager . debugMode = false ;
soundManager . onload = function ( ) {
2012-11-21 10:57:54 +01:00
var createBuffer = function ( instrument , id , onload ) {
var synth = MIDI . GeneralMIDI . byName [ instrument ] ;
var instrumentId = synth . number ;
notes [ instrumentId + "" + id ] = soundManager . createSound ( {
2012-02-16 05:46:03 +01:00
id : id ,
2013-01-12 03:05:42 +01:00
url : MIDI . soundfontUrl + instrument + "-mp3/" + id + ".mp3" ,
2012-02-16 05:46:03 +01:00
multiShot : true ,
autoLoad : true ,
onload : onload
2012-11-21 10:57:54 +01:00
} ) ;
} ;
for ( var instrument in MIDI . Soundfont ) {
var loaded = [ ] ;
var onload = function ( ) {
loaded . push ( this . sID ) ;
2013-01-12 03:05:42 +01:00
if ( typeof ( MIDI . loader ) === "undefined" ) return ;
MIDI . loader . update ( null , "Processing: " + this . sID ) ;
2012-11-21 10:57:54 +01:00
} ;
for ( var i = 0 ; i < 88 ; i ++ ) {
var id = noteReverse [ i + 21 ] ;
createBuffer ( instrument , id , onload ) ;
}
2012-02-16 05:46:03 +01:00
}
2012-11-21 10:57:54 +01:00
///
2013-01-26 07:00:09 +01:00
setPlugin ( root ) ;
2012-02-16 05:46:03 +01:00
//
var interval = window . setInterval ( function ( ) {
2012-04-14 06:59:48 +02:00
if ( loaded . length !== 88 ) return ;
2012-02-16 05:46:03 +01:00
window . clearInterval ( interval ) ;
2013-01-27 05:45:41 +01:00
if ( conf . callback ) conf . callback ( ) ;
2012-02-16 05:46:03 +01:00
} , 25 ) ;
} ;
soundManager . onerror = function ( ) {
} ;
for ( var key in MIDI . keyToNote ) {
noteReverse [ MIDI . keyToNote [ key ] ] = key ;
}
} ;
} ) ( ) ;
/ *
helper functions
* /
// instrument-tracker
2012-11-21 10:57:54 +01:00
MIDI . GeneralMIDI = ( function ( arr ) {
var clean = function ( v ) {
return v . replace ( /[^a-z0-9 ]/gi , "" ) . replace ( /[ ]/g , "_" ) . toLowerCase ( ) ;
} ;
var ret = {
byName : { } ,
byId : { } ,
byCategory : { }
} ;
2012-02-16 05:46:03 +01:00
for ( var key in arr ) {
var list = arr [ key ] ;
for ( var n = 0 , length = list . length ; n < length ; n ++ ) {
var instrument = list [ n ] ;
if ( ! instrument ) continue ;
var num = parseInt ( instrument . substr ( 0 , instrument . indexOf ( " " ) ) , 10 ) ;
instrument = instrument . replace ( num + " " , "" ) ;
2012-11-21 10:57:54 +01:00
ret . byId [ -- num ] =
ret . byName [ clean ( instrument ) ] =
ret . byCategory [ clean ( key ) ] = {
id : clean ( instrument ) ,
2012-02-16 05:46:03 +01:00
instrument : instrument ,
number : num ,
category : key
} ;
}
}
2012-11-21 10:57:54 +01:00
return ret ;
2012-02-16 05:46:03 +01:00
} ) ( {
'Piano' : [ '1 Acoustic Grand Piano' , '2 Bright Acoustic Piano' , '3 Electric Grand Piano' , '4 Honky-tonk Piano' , '5 Electric Piano 1' , '6 Electric Piano 2' , '7 Harpsichord' , '8 Clavinet' ] ,
'Chromatic Percussion' : [ '9 Celesta' , '10 Glockenspiel' , '11 Music Box' , '12 Vibraphone' , '13 Marimba' , '14 Xylophone' , '15 Tubular Bells' , '16 Dulcimer' ] ,
'Organ' : [ '17 Drawbar Organ' , '18 Percussive Organ' , '19 Rock Organ' , '20 Church Organ' , '21 Reed Organ' , '22 Accordion' , '23 Harmonica' , '24 Tango Accordion' ] ,
'Guitar' : [ '25 Acoustic Guitar (nylon)' , '26 Acoustic Guitar (steel)' , '27 Electric Guitar (jazz)' , '28 Electric Guitar (clean)' , '29 Electric Guitar (muted)' , '30 Overdriven Guitar' , '31 Distortion Guitar' , '32 Guitar Harmonics' ] ,
'Bass' : [ '33 Acoustic Bass' , '34 Electric Bass (finger)' , '35 Electric Bass (pick)' , '36 Fretless Bass' , '37 Slap Bass 1' , '38 Slap Bass 2' , '39 Synth Bass 1' , '40 Synth Bass 2' ] ,
'Strings' : [ '41 Violin' , '42 Viola' , '43 Cello' , '44 Contrabass' , '45 Tremolo Strings' , '46 Pizzicato Strings' , '47 Orchestral Harp' , '48 Timpani' ] ,
'Ensemble' : [ '49 String Ensemble 1' , '50 String Ensemble 2' , '51 Synth Strings 1' , '52 Synth Strings 2' , '53 Choir Aahs' , '54 Voice Oohs' , '55 Synth Choir' , '56 Orchestra Hit' ] ,
'Brass' : [ '57 Trumpet' , '58 Trombone' , '59 Tuba' , '60 Muted Trumpet' , '61 French Horn' , '62 Brass Section' , '63 Synth Brass 1' , '64 Synth Brass 2' ] ,
'Reed' : [ '65 Soprano Sax' , '66 Alto Sax' , '67 Tenor Sax' , '68 Baritone Sax' , '69 Oboe' , '70 English Horn' , '71 Bassoon' , '72 Clarinet' ] ,
'Pipe' : [ '73 Piccolo' , '74 Flute' , '75 Recorder' , '76 Pan Flute' , '77 Blown Bottle' , '78 Shakuhachi' , '79 Whistle' , '80 Ocarina' ] ,
'Synth Lead' : [ '81 Lead 1 (square)' , '82 Lead 2 (sawtooth)' , '83 Lead 3 (calliope)' , '84 Lead 4 (chiff)' , '85 Lead 5 (charang)' , '86 Lead 6 (voice)' , '87 Lead 7 (fifths)' , '88 Lead 8 (bass + lead)' ] ,
'Synth Pad' : [ '89 Pad 1 (new age)' , '90 Pad 2 (warm)' , '91 Pad 3 (polysynth)' , '92 Pad 4 (choir)' , '93 Pad 5 (bowed)' , '94 Pad 6 (metallic)' , '95 Pad 7 (halo)' , '96 Pad 8 (sweep)' ] ,
'Synth Effects' : [ '97 FX 1 (rain)' , '98 FX 2 (soundtrack)' , '99 FX 3 (crystal)' , '100 FX 4 (atmosphere)' , '101 FX 5 (brightness)' , '102 FX 6 (goblins)' , '103 FX 7 (echoes)' , '104 FX 8 (sci-fi)' ] ,
'Ethnic' : [ '105 Sitar' , '106 Banjo' , '107 Shamisen' , '108 Koto' , '109 Kalimba' , '110 Bagpipe' , '111 Fiddle' , '112 Shanai' ] ,
'Percussive' : [ '113 Tinkle Bell' , '114 Agogo' , '115 Steel Drums' , '116 Woodblock' , '117 Taiko Drum' , '118 Melodic Tom' , '119 Synth Drum' ] ,
'Sound effects' : [ '120 Reverse Cymbal' , '121 Guitar Fret Noise' , '122 Breath Noise' , '123 Seashore' , '124 Bird Tweet' , '125 Telephone Ring' , '126 Helicopter' , '127 Applause' , '128 Gunshot' ]
} ) ;
// channel-tracker
MIDI . channels = ( function ( ) { // 0 - 15 channels
var channels = { } ;
for ( var n = 0 ; n < 16 ; n ++ ) {
channels [ n ] = { // default values
instrument : 0 ,
// Acoustic Grand Piano
mute : false ,
mono : false ,
omni : false ,
solo : false
} ;
}
return channels ;
} ) ( ) ;
2012-11-21 10:57:54 +01:00
//
MIDI . pianoKeyOffset = 21 ;
2012-02-16 05:46:03 +01:00
// note conversions
MIDI . keyToNote = { } ; // C8 == 108
MIDI . noteToKey = { } ; // 108 == C8
( function ( ) {
var A0 = 0x15 ; // first note
var C8 = 0x6C ; // last note
var number2key = [ "C" , "Db" , "D" , "Eb" , "E" , "F" , "Gb" , "G" , "Ab" , "A" , "Bb" , "B" ] ;
for ( var n = A0 ; n <= C8 ; n ++ ) {
var octave = ( n - 12 ) / 12 >> 0 ;
var name = number2key [ n % 12 ] + octave ;
MIDI . keyToNote [ name ] = n ;
MIDI . noteToKey [ n ] = name ;
}
} ) ( ) ;
2012-11-21 10:57:54 +01:00
} ) ( ) ;