a munch adventure
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.
 
 
 
 

197 рядки
3.9 KiB

  1. let playing = [];
  2. looping = {};
  3. let audioDict = {};
  4. // play some sound
  5. function playSfx(name) {
  6. if (audioDict[name] == undefined) {
  7. console.log(name + " is not loaded yet, dingus");
  8. return;
  9. }
  10. let src = audioContext.createBufferSource();
  11. src.buffer = audioDict[name];
  12. src.connect(audioContext.destination);
  13. playing.push(src);
  14. src.name = name;
  15. src.onended = (event) => src.done = true;
  16. src.start(0);
  17. }
  18. function playLoop(name) {
  19. if (audioDict[name] == undefined) {
  20. console.log(name + " is not loaded yet, dingus");
  21. return;
  22. }
  23. // if already playing, just keep going
  24. if (looping[name] && !looping[name].done) {
  25. console.log(name + " is already looping");
  26. return;
  27. }
  28. let src = audioContext.createBufferSource();
  29. src.buffer = audioDict[name];
  30. src.connect(audioContext.destination);
  31. looping[name] = src;
  32. src.name = name;
  33. src.onended = (event) => src.done = true;
  34. src.loop = true;
  35. src.start(0);
  36. }
  37. function stopSfx(name) {
  38. playing.map(item => {
  39. if (item.name == name)
  40. item.stop();
  41. } );
  42. cleanPlaying();
  43. }
  44. function stopLoop(name) {
  45. if (looping[name]) {
  46. looping[name].stop();
  47. delete looping[name];
  48. }
  49. }
  50. function cleanPlaying() {
  51. playing = playing.filter(item => !item.done);
  52. }
  53. // asynchronously load an audio file
  54. function loadAudio(name, flush=false) {
  55. // do we already have the audio?
  56. if (audioDict[name] && !flush) {
  57. return;
  58. }
  59. // is the audio already stored locally?
  60. if (!flush) {
  61. checkCache(
  62. "audio",
  63. name,
  64. (data) => parseAudioData(name, data),
  65. () => loadRemoteAudio(name)
  66. );
  67. } else {
  68. loadRemoteAudio(name);
  69. }
  70. }
  71. function cacheAndParse(name, data) {
  72. storeCache("audio", name, data.slice(0));
  73. parseAudioData(name, data);
  74. }
  75. function parseAudioData(name, data) {
  76. console.log(data);
  77. audioContext.decodeAudioData(data, function(buffer) {
  78. audioDict[name] = buffer;
  79. }, function(e){ console.log("Error with decoding audio data" + e.err);});
  80. }
  81. function loadRemoteAudio(name) {
  82. let xhr = new XMLHttpRequest();
  83. xhr.open("GET", audioBaseUrl + name, true);
  84. xhr.responseType = "arraybuffer";
  85. xhr.onload = (xhr) => {
  86. if (xhr.status == 200)
  87. cacheAndParse(name, xhr.data);
  88. else
  89. console.log("Couldn't load " + name);
  90. }
  91. xhr.onerror = (xhr) => console.log("Couldn't load " + name);
  92. xhr.send();
  93. }
  94. // check if the content is cached
  95. function checkCache(type, name, hit, miss) {
  96. const req = window.indexedDB.open("cache", 1);
  97. req.onsuccess = () => {
  98. const db = req.result;
  99. const tx = db.transaction([type], "readonly");
  100. const audio = tx.objectStore(type);
  101. const read = audio.get(name);
  102. read.onsuccess = (event) => {
  103. const res = event.target.result;
  104. if (res) {
  105. console.log("cache hit on " + name);
  106. hit(res.content);
  107. } else {
  108. console.log("cache miss on " + name);
  109. miss();
  110. }
  111. }
  112. tx.oncomplete = () => {
  113. db.close();
  114. }
  115. }
  116. }
  117. function initAudio() {
  118. audioContext = new (window.AudioContext || window.webkitAudioContext)();
  119. console.log("Initialized audio context");
  120. console.log(audioContext);
  121. }
  122. // caching stuff here
  123. function storeCache(type, name, blob) {
  124. const req = window.indexedDB.open("cache", 1);
  125. req.onsuccess = () => {
  126. const db = req.result;
  127. const tx = db.transaction([type], "readwrite");
  128. const audio = tx.objectStore(type);
  129. const update = audio.put({
  130. name: name,
  131. content: blob
  132. });
  133. tx.oncomplete = () => {
  134. db.close();
  135. }
  136. }
  137. }
  138. // if the indexedDB table doesn't exist at all, make it
  139. function createCache() {
  140. let idb = window.indexedDB;
  141. let req = idb.open("cache", 1);
  142. req.onupgradeneeded = event => {
  143. const db = event.target.result;
  144. const audio = db.createObjectStore("audio", { keyPath: "name" });
  145. }
  146. req.onerror = event => {
  147. alert("Couldn't open the database?");
  148. }
  149. }