diff --git a/index.html b/index.html index dd66216..babc551 100644 --- a/index.html +++ b/index.html @@ -28,7 +28,6 @@ - @@ -44,6 +43,7 @@ + diff --git a/src/js/bufferedloop.js b/src/js/bufferedloop.js new file mode 100644 index 0000000..5caa669 --- /dev/null +++ b/src/js/bufferedloop.js @@ -0,0 +1,83 @@ +// thx to @LoveEevee for this - https://github.com/LoveEevee + +class BufferedLoop{ + constructor(bgm1,bgm2){ + this.context=new AudioContext() + this.buffers=[] + this.sources=new Set() + this.bufferedTime=0 + this.iteration=0 + this.bgm1=bgm1 + this.bgm2=bgm2 + this.loadSound(bgm1.url,0) + this.loadSound(bgm2.url,1) + } + loadSound(url,number){ + var self=this + var request=new XMLHttpRequest() + request.open("GET",url) + request.responseType="arraybuffer" + request.onload=function(){ + self.context.decodeAudioData(request.response,function(buffer){ + self.buffers[number]=buffer + self.setLoaded() + }) + } + request.send() + } + setLoaded(){ + if(this.buffers[0]&&this.buffers[1]){ + this.loaded=true + if(this.loadCallback){ + this.loadCallback() + delete this.loadCallback + } + } + } + playSound(buffer,time,duration){ + var self=this + var source=this.context.createBufferSource() + source.buffer=buffer + source.connect(this.context.destination) + source.start(time) + this.bufferedTime=time+duration + this.sources.add(source) + console.log(this.sources) + setTimeout(function(){ + self.sources.delete(source) + },duration*1000) + } + addLoop(){ + if(this.context.currentTime>this.bufferedTime-1){ + this.playSound( + this.buffers[1], + this.start+this.bgm1.duration+this.bgm2.duration*this.iteration, + this.bgm2.duration + ) + this.iteration++ + } + } + play(){ + var self=this + if(!this.loaded){ + this.loadCallback=this.play + return + } + this.start=this.context.currentTime+0.1 + this.playSound( + this.buffers[0], + this.start, + this.bgm1.duration + ) + self.addLoop() + self.interval=setInterval(function(){ + self.addLoop() + },100) + } + pause(){ + clearInterval(this.interval) + this.sources.forEach(function(source){ + source.stop(0) + }) + } +} \ No newline at end of file diff --git a/src/js/lib/SeamlessLoop.js b/src/js/lib/SeamlessLoop.js deleted file mode 100644 index a423b5a..0000000 --- a/src/js/lib/SeamlessLoop.js +++ /dev/null @@ -1,201 +0,0 @@ -/** - * SeamlessLoop.js 2.0 - Reproduces seamless loops on HTML5/Javascript - * https://github.com/Hivenfour/SeamlessLoop - * - * Copyright (c) 2012 Main Software, - * Written by DarĂ­o Tejedor Rico. Contact mail: hivenfour@gmail.com - * The source code is freely distributable under the terms of LGPL license. - * License details at http://www.gnu.org/licenses/lgpl-3.0.txt - * - * USAGE: - * - Create the Seamlessloop object - * var loop = new SeamlessLoop(); - * - * - Add as many sounds as you will use, providing duration in miliseconds - * (sounds must be pre-loaded if you want to update the loop without gaps) - * loop.addUri(uri, length, "sound1"); - * loop.addUri(uri, length, "sound2"); - * ... - * - * - Establish your callback function that will be called when all sounds are pre-loaded - * loop.callback(soundsLoaded); - * - * - Start reproducing the seamless loop: - * function soundsLoaded() { - * var n = 1; - * loop.start("sound" + n); - * }; - * - * - Update the looping sound, you can do this - * synchronously (waiting the loop to finish) - * or asynchronously (change sound immediately): - * n++; - * loop.update("sound" + n, false); - * - * - Modify the seamless loop volume: - * loop.volume(0.5); - * loop.volume(loop.volume() + 0.1); - * - * - Stop the seamless loop: - * loop.stop(); - */ - -function SeamlessLoop() { - this.is = { - ff: Boolean(!(window.mozInnerScreenX == null) && /firefox/.test( navigator.userAgent.toLowerCase() )), - ie: Boolean(document.all && !window.opera), - opera: Boolean(window.opera), - chrome: Boolean(window.chrome), - safari: Boolean(!window.chrome && /safari/.test( navigator.userAgent.toLowerCase() ) && window.getComputedStyle && !window.globalStorage && !window.opera) - }; - console.debug("ff: " + this.is.ff); - console.debug("ie: " + this.is.ie); - console.debug("opera: " + this.is.opera); - console.debug("chrome: " + this.is.chrome); - console.debug("safari: " + this.is.safari); - this._total = 0; - this._load = 0; - this.cb_loaded; - this.cb_loaded_flag = new Boolean(); - this.timeout; - this.playDelay = -30; - this.stopDelay = 30; - if(this.is.chrome) this.playDelay = -25; - if(this.is.chrome) this.stopDelay = 25; - if(this.is.ff) this.playDelay = -25; - if(this.is.ff) this.stopDelay = 85; - if(this.is.opera) this.playDelay = 5; - if(this.is.opera) this.stopDelay = 0; - console.debug(this.playDelay + ", " + this.stopDelay); - this.next = 1; - this.audios = new Array(); - this.actual = new Array(); - this.dropOld = new Boolean(); - this.old; - this._volume = 1; - - var t = this; - this._eventCanplaythrough = function(audBool) { - if(audBool == false) { - audBool = true; - t._load++; - if(t._load == t._total) { - t.loaded = true; - if(t.cb_loaded_flag == true) { - t.cb_loaded(); - t.cb_loaded_flag = false; - } - } - } - }; - - this._eventPlaying = function(audMute) { - setTimeout(function() { - audMute.pause(); - try { - audMute.currentTime = 0; - } catch (e){console.debug(e.message);}; - }, t.stopDelay); - - if(t.dropOld == true) { - setTimeout(function() { - if(t.old.paused == false) { - t.old.pause(); - try { - t.old.currentTime = 0; - } catch (e){console.debug(e.message);}; - } - }, t.stopDelay); - t.dropOld = false; - } - }; - - this._eventEnded = function(aud) { - aud.volume = this._volume; - }; - - this.doLoop = function() { - var key = (this.next == 1 ? "_1" : "_2"); - var antikey = (this.next == 1 ? "_2" : "_1"); - - var t = this; - this.timeout = setTimeout(function() {t.doLoop();}, this.actual._length + this.playDelay); - - if(this.is.opera) this.actual[antikey].pause(); - - this.actual[key].play(); - this.next *= -1; - }; - - this.isLoaded = function() { - return Boolean(this._load == this._total); - }; -} - -SeamlessLoop.prototype.start = function(id) { - if(id != "") { - this.actual = this.audios[id]; - } - this.doLoop(); -}; - -SeamlessLoop.prototype.volume = function(vol) { - if(typeof vol != "undefined") { - this.actual._1.volume = vol; - this.actual._2.volume = vol; - this._volume = vol; - } - - return vol; -}; - -SeamlessLoop.prototype.stop = function() { - clearTimeout(this.timeout); - this.actual._1.currentTime = 0; - this.actual._1.pause(); - this.actual._2.currentTime = 0; - this.actual._2.pause(); -}; - -SeamlessLoop.prototype.callback = function(cb_loaded) { - this.cb_loaded = cb_loaded; - if(this.isLoaded() == true) cb_loaded(); - else this.cb_loaded_flag = true; -}; - -SeamlessLoop.prototype.update = function(id, sync) { - //var key = (this.next == 1 ? "_1" : "_2"); - var antikey = (this.next == 1 ? "_2" : "_1"); - - this.old = this.actual[antikey]; - this.actual = this.audios[id]; - if(sync == false) { - if(this.old.paused == false) { - this.dropOld = true; - if(this.is.opera) this.old.pause(); - } - clearTimeout(this.timeout); - this.doLoop(); - } -}; - -SeamlessLoop.prototype.addUri = function(uri, length, id) { - this.audios[id] = new Array(); - this.audios[id]._length = length; - var t = this; - this.audios[id]._1_isLoaded = new Boolean(); - this.audios[id]._2_isLoaded = new Boolean(); - this.audios[id]._1 = new Audio(uri); - this.audios[id]._2 = new Audio(uri); - this._total++; - this.audios[id]._1.addEventListener("canplaythrough", function() {t._eventCanplaythrough(t.audios[id]._1_isLoaded);}); - this.audios[id]._2.addEventListener("canplaythrough", function() {t._eventCanplaythrough(t.audios[id]._2_isLoaded);}); - this.audios[id]._1.addEventListener("playing", function() {t._eventPlaying(t.audios[id]._2);}); - this.audios[id]._2.addEventListener("playing", function() {t._eventPlaying(t.audios[id]._1);}); - this.audios[id]._1.addEventListener("ended", function() {t._eventEnded(t.audios[id]._1);}); - this.audios[id]._2.addEventListener("ended", function() {t._eventEnded(t.audios[id]._2);}); - this.audios[id]._1.load(); - this.audios[id]._2.load(); - this.audios[id]._1.volume = this._volume; - this.audios[id]._2.volume = this._volume; -}; diff --git a/src/js/scoresheet.js b/src/js/scoresheet.js index ddbc247..c8a6015 100644 --- a/src/js/scoresheet.js +++ b/src/js/scoresheet.js @@ -82,13 +82,13 @@ function Scoresheet(controller, score){ $("#song-select").click(function(){ assets.sounds["don"].play(); - bgmloop2.stop(); + bgm.stop(); controller.songSelection(); }); $("#replay").click(function(){ assets.sounds["don"].play(); - bgmloop2.stop(); + bgm.stop(); controller.restartSong(); }); @@ -98,14 +98,11 @@ function Scoresheet(controller, score){ assets.sounds["results"].play(); - console.log('init scoresheet bgm'); - bgmloop2 = new SeamlessLoop(); - bgmloop2.addUri('/assets/audio/bgm_result.ogg', 870, "bgm_result"); - bgmloop2.addUri('/assets/audio/bgm_result_loop.ogg', 16860, "bgm_result_loop"); - bgmloop2.callback(function(){ - bgmloop2.start('bgm_result'); - bgmloop2.update('bgm_result_loop'); - }); + bgm = new BufferedLoop( + {url: '/assets/audio/bgm_result.ogg', duration: 0.847}, + {url: '/assets/audio/bgm_result_loop.ogg', duration: 16.842} + ); + bgm.play(); diff --git a/src/js/songselect.js b/src/js/songselect.js index 9aa4788..8674d60 100644 --- a/src/js/songselect.js +++ b/src/js/songselect.js @@ -25,9 +25,8 @@ function SongSelect(){ _selectedSong.title = $(this).parent().closest('.song').find('.song-title').html(); _selectedSong.folder = songID+" "+_selectedSong.title; - bgmloop.stop(); + bgm.pause(); new loadSong(_selectedSong); - }); $(".song").hover(function(){ @@ -87,16 +86,13 @@ function SongSelect(){ }); } - - this.createCode = function(){ - bgmloop = new SeamlessLoop(); - bgmloop.addUri('/assets/audio/bgm_songsel.ogg', 1450, "bgm_songsel"); - bgmloop.addUri('/assets/audio/bgm_songsel_loop.ogg', 2085, "bgm_songsel_loop"); - bgmloop.callback(function(){ - bgmloop.start('bgm_songsel'); - bgmloop.update('bgm_songsel_loop') - }); + this.createCode = function(){ + bgm = new BufferedLoop( + {url: '/assets/audio/bgm_songsel.ogg', duration: 1.442}, + {url: '/assets/audio/bgm_songsel_loop.ogg', duration: 2.064} + ); + bgm.play(); setTimeout(function(){ assets.sounds["song-select"].play(); @@ -109,8 +105,6 @@ function SongSelect(){ var songID = titleSplit[0]; var songTitle = songDir.substr(songID.length+1, songDir.length-(songID.length+1)); - - _code += "
"+songTitle+'
'; _code += "