var LAME_DELAY_START = 2258; var LAME_DELAY_END = 1000; // callback is given a populated song object function loadSong(song, callback) { if(song.buffer) { callback(song); return; } if(song.isLoading) { return; // we're already trying to load this } song.isLoading = true; song.tmpBuf = {}; if(song.buildUp) { loadAudioFile(song, true, callback); } loadAudioFile(song, false, callback); } function loadAudioFile(song, isBuild, callback) { var filename = isBuild ? song.buildUp : song.file; var req = new XMLHttpRequest(); req.open('GET', filename, true); req.responseType = 'arraybuffer'; req.onload = function() { audio.context.decodeAudioData( req.response, function(buffer) { if(isBuild) { song.tmpBuf.build = trimMP3(buffer); } else { song.tmpBuf.loop = trimMP3(buffer); } onSongLoad(song, callback); }, function() { console.log('Error decoding audio "' + filename + '".'); } ); }; req.send(); } function onSongLoad(song, callback) { // if this fails, we need to wait for the other part to load if(song.tmpBuf.loop && (!song.buildUp || song.tmpBuf.build)) { if(song.buildUp) { song.buffer = concatenateAudioBuffers(song.tmpBuf.build, song.tmpBuf.loop); song.loopStart = song.tmpBuf.build.duration; } else { song.buffer = song.tmpBuf.loop; song.loopStart = 0; } song.loopLength = song.buffer.duration - song.loopStart; // free dat memory song.tmpBuf = null; song.isLoading = false; callback(song); } } // because MP3 is bad function trimMP3(buffer) { var ret = audio.context.createBuffer(buffer.numberOfChannels, buffer.length - LAME_DELAY_START - LAME_DELAY_END, buffer.sampleRate); for(var i=0; i