audio.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
  2. function loadSound(url) {
  3. return fetch(url)
  4. .then(response => response.arrayBuffer())
  5. .then(buffer => audioCtx.decodeAudioData(buffer))
  6. .then(audio => new Sound(audio, url));
  7. }
  8. function SFXManager() {
  9. this.soundMap = {}
  10. }
  11. SFXManager.prototype.loadSound = function(name, url) {
  12. var self = this;
  13. return loadSound(url).then(sound => {
  14. self.soundMap[name] = sound;
  15. })
  16. }
  17. SFXManager.prototype.play = function(name) {
  18. this.soundMap[name].play();
  19. }
  20. SFXManager.prototype.unloadSound = function(name) {
  21. delete this.soundMap[name];
  22. }
  23. function Sound(buffer, url) {
  24. this.buffer = buffer;
  25. this.url = url;
  26. this._target = audioCtx.destination;
  27. this._source = null;
  28. this._playStartTime = 0;
  29. this._timeToStartFrom = 0;
  30. this._playing = false;
  31. }
  32. Sound.prototype.setTarget = function(target) {
  33. this._target = target;
  34. if(this._playing) {
  35. this.pause();
  36. this.resume();
  37. }
  38. }
  39. Sound.prototype._start = function(offset) {
  40. this._source = audioCtx.createBufferSource();
  41. this._source.buffer = this.buffer;
  42. this._source.connect(this._target);
  43. this._source.onended = function() {
  44. this._playing = false;
  45. this._timeToStartFrom = 0;
  46. }.bind(this);
  47. this._playStartTime = audioCtx.currentTime;
  48. this._timeToStartFrom = offset;
  49. this._playing = true;
  50. this._source.start(0, this._timeToStartFrom);
  51. }
  52. Sound.prototype.play = function() {
  53. if(this._playing) {
  54. this.pause();
  55. }
  56. this._start(0);
  57. }
  58. Sound.prototype.resume = function() {
  59. this._start(this._timeToStartFrom);
  60. }
  61. Sound.prototype.pause = function() {
  62. // in case the sound has not been played yet
  63. if(this._source == null) return;
  64. this._playing = false;
  65. this._source.onended = null;
  66. this._source.stop();
  67. this._source.disconnect();
  68. var elapsedTime = this._timeToStartFrom + audioCtx.currentTime - this._playStartTime;
  69. this._timeToStartFrom = elapsedTime;
  70. }
  71. var sfxManager = new SFXManager();