1/* 2 ---------------------------------------------------------------------- 3 AudioTag <audio> - OGG or MPEG Soundbank 4 ---------------------------------------------------------------------- 5 http://dev.w3.org/html5/spec/Overview.html#the-audio-element 6 ---------------------------------------------------------------------- 7*/ 8 9(function(root) { 'use strict'; 10 11 window.Audio && (function() { 12 var midi = root.AudioTag = { api: 'audiotag' }; 13 var noteToKey = {}; 14 var volume = 127; // floating point 15 var buffer_nid = -1; // current channel 16 var audioBuffers = []; // the audio channels 17 var notesOn = []; // instrumentId + noteId that is currently playing in each 'channel', for routing noteOff/chordOff calls 18 var notes = {}; // the piano keys 19 for (var nid = 0; nid < 12; nid ++) { 20 audioBuffers[nid] = new Audio(); 21 } 22 23 var playChannel = function(channel, note) { 24 if (!root.channels[channel]) return; 25 var instrument = root.channels[channel].instrument; 26 var instrumentId = root.GM.byId[instrument].id; 27 var note = notes[note]; 28 if (note) { 29 var instrumentNoteId = instrumentId + '' + note.id; 30 var nid = (buffer_nid + 1) % audioBuffers.length; 31 var audio = audioBuffers[nid]; 32 notesOn[ nid ] = instrumentNoteId; 33 if (!root.Soundfont[instrumentId]) { 34 if (root.DEBUG) { 35 console.log('404', instrumentId); 36 } 37 return; 38 } 39 audio.src = root.Soundfont[instrumentId][note.id]; 40 audio.volume = volume / 127; 41 audio.play(); 42 buffer_nid = nid; 43 } 44 }; 45 46 var stopChannel = function(channel, note) { 47 if (!root.channels[channel]) return; 48 var instrument = root.channels[channel].instrument; 49 var instrumentId = root.GM.byId[instrument].id; 50 var note = notes[note]; 51 if (note) { 52 var instrumentNoteId = instrumentId + '' + note.id; 53 for (var i = 0, len = audioBuffers.length; i < len; i++) { 54 var nid = (i + buffer_nid + 1) % len; 55 var cId = notesOn[nid]; 56 if (cId && cId == instrumentNoteId) { 57 audioBuffers[nid].pause(); 58 notesOn[nid] = null; 59 return; 60 } 61 } 62 } 63 }; 64 65 midi.audioBuffers = audioBuffers; 66 midi.send = function(data, delay) { }; 67 midi.setController = function(channel, type, value, delay) { }; 68 midi.setVolume = function(channel, n) { 69 volume = n; //- should be channel specific volume 70 }; 71 72 midi.programChange = function(channel, program) { 73 root.channels[channel].instrument = program; 74 }; 75 76 midi.pitchBend = function(channel, program, delay) { }; 77 78 midi.noteOn = function(channel, note, velocity, delay) { 79 var id = noteToKey[note]; 80 if (!notes[id]) return; 81 if (delay) { 82 return setTimeout(function() { 83 playChannel(channel, id); 84 }, delay * 1000); 85 } else { 86 playChannel(channel, id); 87 } 88 }; 89 90 midi.noteOff = function(channel, note, delay) { 91// var id = noteToKey[note]; 92// if (!notes[id]) return; 93// if (delay) { 94// return setTimeout(function() { 95// stopChannel(channel, id); 96// }, delay * 1000) 97// } else { 98// stopChannel(channel, id); 99// } 100 }; 101 102 midi.chordOn = function(channel, chord, velocity, delay) { 103 for (var idx = 0; idx < chord.length; idx ++) { 104 var n = chord[idx]; 105 var id = noteToKey[n]; 106 if (!notes[id]) continue; 107 if (delay) { 108 return setTimeout(function() { 109 playChannel(channel, id); 110 }, delay * 1000); 111 } else { 112 playChannel(channel, id); 113 } 114 } 115 }; 116 117 midi.chordOff = function(channel, chord, delay) { 118 for (var idx = 0; idx < chord.length; idx ++) { 119 var n = chord[idx]; 120 var id = noteToKey[n]; 121 if (!notes[id]) continue; 122 if (delay) { 123 return setTimeout(function() { 124 stopChannel(channel, id); 125 }, delay * 1000); 126 } else { 127 stopChannel(channel, id); 128 } 129 } 130 }; 131 132 midi.stopAllNotes = function() { 133 for (var nid = 0, length = audioBuffers.length; nid < length; nid++) { 134 audioBuffers[nid].pause(); 135 } 136 }; 137 138 midi.connect = function(opts) { 139 root.setDefaultPlugin(midi); 140 /// 141 for (var key in root.keyToNote) { 142 noteToKey[root.keyToNote[key]] = key; 143 notes[key] = {id: key}; 144 } 145 /// 146 opts.onsuccess && opts.onsuccess(); 147 }; 148 })(); 149 150})(MIDI);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.