let playing = []; let looping = {}; const audioBaseUrl = "https://chemicalcrux.org/satiate/media/audio/"; let audioDict = {}; // play some sound function playSfx(name) { if (audioDict[name] == undefined) { console.log(name + " is not loaded yet, dingus"); return; } let src = audioContext.createBufferSource(); src.buffer = audioDict[name]; src.connect(audioContext.destination); playing.push(src); src.name = name; src.onended = (event) => src.done = true; src.start(0); } function playLoop(name) { if (audioDict[name] == undefined) { console.log(name + " is not loaded yet, dingus"); return; } // if already playing, just keep going if (looping[name] && !looping[name].done) { console.log(name + " is already looping"); return; } let src = audioContext.createBufferSource(); src.buffer = audioDict[name]; src.connect(audioContext.destination); looping[name] = src; src.name = name; src.onended = (event) => src.done = true; src.loop = true; src.start(0); } function stopSfx(name) { playing.map(item => { if (item.name == name) item.stop(); } ); cleanPlaying(); } function stopLoop(name) { if (looping[name]) { looping[name].stop(); delete looping[name]; } } function cleanPlaying() { playing = playing.filter(item => !item.done); } // asynchronously load an audio file function loadAudio(name, flush=false) { // do we already have the audio? if (audioDict[name] && !flush) { return; } // is the audio already stored locally? if (!flush) { checkCache( "audio", name, (data) => parseAudioData(name, data), () => loadRemoteAudio(name) ); } else { loadRemoteAudio(name); } } function cacheAndParse(name, data) { storeCache("audio", name, data.slice(0)); parseAudioData(name, data); } function parseAudioData(name, data) { console.log(data); audioContext.decodeAudioData(data, function(buffer) { audioDict[name] = buffer; }, function(e){ console.log("Error with decoding audio data" + e.err);}); } function loadRemoteAudio(name) { let xhr = new XMLHttpRequest(); xhr.open("GET", audioBaseUrl + name, true); xhr.responseType = "arraybuffer"; xhr.onload = (res) => { if (xhr.status == 200) cacheAndParse(name, xhr.response); else console.log("Couldn't load " + name); } xhr.onerror = (xhr) => console.log("Couldn't load " + name); xhr.send(); } // check if the content is cached function checkCache(type, name, hit, miss) { const req = window.indexedDB.open("cache", 1); req.onsuccess = () => { const db = req.result; const tx = db.transaction([type], "readonly"); const audio = tx.objectStore(type); const read = audio.get(name); read.onsuccess = (event) => { const res = event.target.result; if (res) { console.log("cache hit on " + name); hit(res.content); } else { console.log("cache miss on " + name); miss(); } } tx.oncomplete = () => { db.close(); } } } function initAudio() { audioContext = new (window.AudioContext || window.webkitAudioContext)(); console.log("Initialized audio context"); console.log(audioContext); } // caching stuff here function storeCache(type, name, blob) { const req = window.indexedDB.open("cache", 1); req.onsuccess = () => { const db = req.result; const tx = db.transaction([type], "readwrite"); const audio = tx.objectStore(type); const update = audio.put({ name: name, content: blob }); tx.oncomplete = () => { db.close(); } } } // if the indexedDB table doesn't exist at all, make it function createCache() { let idb = window.indexedDB; let req = idb.open("cache", 1); req.onupgradeneeded = event => { const db = event.target.result; const audio = db.createObjectStore("audio", { keyPath: "name" }); } req.onerror = event => { alert("Couldn't open the database?"); } }