|  | let audioDict = {};
// play some sound
function playAudio(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);
  src.start(0);
}
// 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 = (xhr) => cacheAndParse(name, xhr.data);
  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?");
  }
}
 |