cacophony 0.2.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/cache.d.ts +0 -1
  2. package/dist/cacophony.cjs.js +2 -0
  3. package/dist/cacophony.cjs.js.map +1 -0
  4. package/dist/cacophony.d.ts +0 -1
  5. package/dist/cacophony.es.js +696 -0
  6. package/dist/cacophony.es.js.map +1 -0
  7. package/dist/cacophony.iife.js +2 -0
  8. package/dist/cacophony.iife.js.map +1 -0
  9. package/dist/cacophony.umd.js +2 -0
  10. package/dist/cacophony.umd.js.map +1 -0
  11. package/dist/index.d.ts +0 -1
  12. package/docs/classes/Cacophony.html +2 -2
  13. package/docs/classes/Group.html +2 -2
  14. package/docs/classes/MicrophonePlayback.html +2 -2
  15. package/docs/classes/MicrophoneStream.html +2 -2
  16. package/docs/classes/Playback.html +2 -2
  17. package/docs/classes/Sound.html +2 -2
  18. package/docs/enums/SoundType.html +2 -2
  19. package/docs/interfaces/BaseSound.html +2 -2
  20. package/docs/types/FadeType.html +1 -1
  21. package/docs/types/LoopCount.html +1 -1
  22. package/docs/types/Orientation.html +1 -1
  23. package/docs/types/Position.html +1 -1
  24. package/package.json +14 -6
  25. package/src/cache.ts +63 -0
  26. package/src/cacophony.test.ts +23 -0
  27. package/{dist/cacophony.js → src/cacophony.ts} +443 -260
  28. package/src/index.ts +1 -0
  29. package/dist/cache.d.ts.map +0 -1
  30. package/dist/cache.js +0 -78
  31. package/dist/cache.js.map +0 -1
  32. package/dist/cacophony.d.ts.map +0 -1
  33. package/dist/cacophony.js.map +0 -1
  34. package/dist/cacophony.test.d.ts +0 -2
  35. package/dist/cacophony.test.d.ts.map +0 -1
  36. package/dist/cacophony.test.js +0 -31
  37. package/dist/cacophony.test.js.map +0 -1
  38. package/dist/index.d.ts.map +0 -1
  39. package/dist/index.js +0 -18
  40. package/dist/index.js.map +0 -1
package/dist/cache.d.ts CHANGED
@@ -6,4 +6,3 @@ export declare class CacheManager {
6
6
  private static fetchAndCacheAudioBuffer;
7
7
  static getAudioBuffer(url: string, context: IAudioContext): Promise<AudioBuffer>;
8
8
  }
9
- //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("standardized-audio-context");class E{static pendingRequests=new Map;static async openCache(){try{return await caches.open("audio-cache")}catch(e){throw console.error("Failed to open cache:",e),e}}static async getAudioBufferFromCache(e,t,i){try{const n=await t.match(e);if(n){const r=await n.arrayBuffer();return i.decodeAudioData(r)}return null}catch(n){throw console.error("Failed to get audio data from cache:",n),n}}static async fetchAndCacheAudioBuffer(e,t,i){try{const n=await fetch(e),r=n.clone();t.put(e,r);const o=await n.arrayBuffer();return i.decodeAudioData(o)}catch(n){throw console.error("Failed to fetch and cache audio data:",n),n}}static async getAudioBuffer(e,t){const i=await this.openCache();let n=this.pendingRequests.get(e);if(n)return n;const r=await this.getAudioBufferFromCache(e,i,t);return r||(n=this.fetchAndCacheAudioBuffer(e,i,t),this.pendingRequests.set(e,n),n)}}var m=(s=>(s.HTML="HTML",s.Streaming="Streaming",s.Buffer="Buffer",s))(m||{});class k{context;globalGainNode;listener;prevVolume=1;finalizationRegistry;constructor(e){this.context=e||new v.AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.finalizationRegistry=new FinalizationRegistry(t=>{t.cleanup()})}async createSound(e,t="Buffer"){if(e instanceof AudioBuffer)return Promise.resolve(new u("",e,this.context,this.globalGainNode,"Buffer"));const i=e;if(t==="HTML"){const n=new Audio;return n.src=i,n.crossOrigin="anonymous",new u(i,void 0,this.context,this.globalGainNode,"HTML")}return E.getAudioBuffer(i,this.context).then(n=>new u(i,n,this.context,this.globalGainNode,t))}async createGroup(e){const t=new f;return e.forEach(i=>t.addSound(i)),t}async createGroupFromUrls(e){const t=new f;return(await Promise.all(e.map(n=>this.createSound(n)))).forEach(n=>t.addSound(n)),t}async createStream(e){return await C(e,this.context),new u(e,void 0,this.context,this.globalGainNode,"Streaming")}createBiquadFilter(e){const t=this.context.createBiquadFilter();return t.type=e,t}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}setGlobalVolume(e){this.globalGainNode.gain.value=e}get volume(){return this.globalGainNode.gain.value}set volume(e){if(this.muted){this.prevVolume=e;return}this.setGlobalVolume(e)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0))}unmute(){this.muted&&this.setGlobalVolume(this.prevVolume)}get muted(){return this.globalGainNode.gain.value===0}set muted(e){e!==this.muted&&(e?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((e,t)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(i=>{const n=new y(this.context);n.play(),e(n)}).catch(i=>{t(i)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(e){const{forward:t,up:i}=e,[n,r,o]=t,[h,c,a]=i;this.listener.forwardX.setValueAtTime(n,this.context.currentTime),this.listener.forwardY.setValueAtTime(r,this.context.currentTime),this.listener.forwardZ.setValueAtTime(o,this.context.currentTime),this.listener.upX.setValueAtTime(h,this.context.currentTime),this.listener.upY.setValueAtTime(c,this.context.currentTime),this.listener.upZ.setValueAtTime(a,this.context.currentTime)}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(e){const[t,i,n]=e;this.listener.upX.setValueAtTime(t,this.context.currentTime),this.listener.upY.setValueAtTime(i,this.context.currentTime),this.listener.upZ.setValueAtTime(n,this.context.currentTime)}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(e){const[t,i,n]=e;this.listener.forwardX.setValueAtTime(t,this.context.currentTime),this.listener.forwardY.setValueAtTime(i,this.context.currentTime),this.listener.forwardZ.setValueAtTime(n,this.context.currentTime)}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(e){const[t,i,n]=e;this.listener.positionX.setValueAtTime(t,this.context.currentTime),this.listener.positionY.setValueAtTime(i,this.context.currentTime),this.listener.positionZ.setValueAtTime(n,this.context.currentTime)}}class l{filters=[];addFilter(e){this.filters.push(e)}removeFilter(e){this.filters=this.filters.filter(t=>t!==e)}applyFilters(e){return this.filters.reduce((t,i)=>(t.connect(i),i),e),this.filters.length>0?this.filters[this.filters.length-1]:e}}class u extends l{constructor(e,t,i,n,r="Buffer"){super(),this.url=e,this.type=r,this.buffer=t,this.context=i,this.globalGainNode=n,this._position=[0,0,0]}buffer;context;playbacks=[];globalGainNode;_position=[0,0,0];_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};loopCount=0;_playbackRate=1;_volume=1;preplay(){let e;if(this.buffer)e=this.context.createBufferSource(),e.buffer=this.buffer;else{const n=new Audio;n.crossOrigin="anonymous",n.src=this.url,n.preload="auto",e=this.context.createMediaElementSource(n)}const t=this.context.createGain();t.connect(this.globalGainNode);const i=new g(e,t,this.context,this.loopCount);return i.volume=this.volume,i.playbackRate=this.playbackRate,this.filters.forEach(n=>i.addFilter(n)),i.threeDOptions=this.threeDOptions,i.position=this.position,this.playbacks.push(i),[i]}play(){const e=this.preplay();return e.forEach(t=>t.play()),e}stop(){this.playbacks.forEach(e=>e.stop())}pause(){"suspend"in this.context&&this.context.suspend()}resume(){"resume"in this.context&&this.context.resume()}seek(e){this.playbacks.forEach(t=>t.seek(e))}set position(e){this._threeDOptions.positionX=e[0],this._threeDOptions.positionY=e[1],this._threeDOptions.positionZ=e[2],this.playbacks.forEach(t=>t.position=e)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}get threeDOptions(){return this._threeDOptions}set threeDOptions(e){this._threeDOptions={...this._threeDOptions,...e},this.playbacks.forEach(t=>t.threeDOptions=this._threeDOptions)}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.playbacks.forEach(t=>t.sourceLoop=!0),this.loopCount)}addFilter(e){super.addFilter(e),this.playbacks.forEach(t=>t.addFilter(e))}removeFilter(e){super.removeFilter(e),this.playbacks.forEach(t=>t.removeFilter(e))}get volume(){return this._volume}set volume(e){this._volume=e,this.playbacks.forEach(t=>t.volume=e)}isPlaying(){return this.playbacks.some(e=>e.isPlaying())}get playbackRate(){return this._playbackRate}set playbackRate(e){this._playbackRate=e,this.playbacks.forEach(t=>t.playbackRate=e)}}class g extends l{context;source;gainNode;panner;loopCount=0;currentLoop=0;buffer;playing=!1;constructor(e,t,i,n=0){super(),this.loopCount=n,this.source=e,"buffer"in e&&e.buffer&&(this.buffer=e.buffer),"mediaElement"in e&&e.mediaElement?e.mediaElement.onended=this.handleLoop.bind(this):"onended"in e&&(e.onended=this.handleLoop.bind(this)),this.gainNode=t,this.context=i,this.panner=i.createPanner(),e.connect(this.panner),this.panner.connect(this.gainNode),this.refreshFilters()}get playbackRate(){if(!this.source)throw new Error("Cannot get playback rate of a sound that has been cleaned up");if("playbackRate"in this.source)return this.source.playbackRate.value;if("mediaElement"in this.source&&this.source.mediaElement)return this.source.mediaElement.playbackRate;throw new Error("Unsupported source type")}set playbackRate(e){if(!this.source)throw new Error("Cannot set playback rate of a sound that has been cleaned up");"playbackRate"in this.source&&(this.source.playbackRate.value=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=e)}handleLoop(){this.buffer?(this.source=this.context.createBufferSource(),this.source.buffer=this.buffer):this.seek(0),this.loopCount==="infinite"||this.currentLoop<this.loopCount?(this.currentLoop++,this.playing&&this.play()):this.playing=!1}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.play():"start"in this.source&&this.source.start&&this.source.start(),this.playing=!0,[this]}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");return{coneInnerAngle:this.panner.coneInnerAngle,coneOuterAngle:this.panner.coneOuterAngle,coneOuterGain:this.panner.coneOuterGain,distanceModel:this.panner.distanceModel,maxDistance:this.panner.maxDistance,channelCount:this.panner.channelCount,channelCountMode:this.panner.channelCountMode,channelInterpretation:this.panner.channelInterpretation,panningModel:this.panner.panningModel,refDistance:this.panner.refDistance,rolloffFactor:this.panner.rolloffFactor,positionX:this.panner.positionX.value,positionY:this.panner.positionY.value,positionZ:this.panner.positionZ.value,orientationX:this.panner.orientationX.value,orientationY:this.panner.orientationY.value,orientationZ:this.panner.orientationZ.value}}set threeDOptions(e){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");this.panner.coneInnerAngle=e.coneInnerAngle||this.panner.coneInnerAngle,this.panner.coneOuterAngle=e.coneOuterAngle||this.panner.coneOuterAngle,this.panner.coneOuterGain=e.coneOuterGain||this.panner.coneOuterGain,this.panner.distanceModel=e.distanceModel||this.panner.distanceModel,this.panner.maxDistance=e.maxDistance||this.panner.maxDistance,this.panner.channelCount=e.channelCount||this.panner.channelCount,this.panner.channelCountMode=e.channelCountMode||this.panner.channelCountMode,this.panner.channelInterpretation=e.channelInterpretation||this.panner.channelInterpretation,this.panner.panningModel=e.panningModel||this.panner.panningModel,this.panner.refDistance=e.refDistance||this.panner.refDistance,this.panner.rolloffFactor=e.rolloffFactor||this.panner.rolloffFactor,this.panner.positionX.value=e.positionX||this.panner.positionX.value,this.panner.positionY.value=e.positionY||this.panner.positionY.value,this.panner.positionZ.value=e.positionZ||this.panner.positionZ.value,this.panner.orientationX.value=e.orientationX||this.panner.orientationX.value,this.panner.orientationY.value=e.orientationY||this.panner.orientationY.value,this.panner.orientationZ.value=e.orientationZ||this.panner.orientationZ.value}seek(e){if(!this.source||!this.buffer||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");const t=this.isPlaying();this.stop(),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.refreshFilters(),this.source.connect(this.panner).connect(this.gainNode),t&&this.source.start(0,e)}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(e){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=e}set sourceLoop(e){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=e)}fadeIn(e,t="linear"){return new Promise(i=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value;const n=1;switch(this.gainNode.gain.value=0,t){case"exponential":this.gainNode.gain.setValueAtTime(.01,this.context.currentTime),this.gainNode.gain.exponentialRampToValueAtTime(n,this.context.currentTime+e);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(n,this.context.currentTime+e);break}setTimeout(()=>{if(!this.gainNode)throw new Error("Cannot fade in a sound that has been cleaned up");this.gainNode.gain.value=n,i()},e*1e3)})}fadeOut(e,t="linear"){return new Promise(i=>{if(!this.gainNode)throw new Error("Cannot fade out a sound that has been cleaned up");switch(this.gainNode.gain.value,t){case"exponential":this.gainNode.gain.exponentialRampToValueAtTime(.01,this.context.currentTime+e);break;case"linear":this.gainNode.gain.linearRampToValueAtTime(0,this.context.currentTime+e)}setTimeout(()=>i(),e*1e3)})}isPlaying(){if(!this.source)throw new Error("Cannot check if a sound is playing that has been cleaned up");return this.playing}cleanup(){this.source&&(this.source.disconnect(),this.source=void 0),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),this.filters.forEach(e=>{e&&e.disconnect()}),this.filters=[]}loop(e){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(this.source instanceof AudioBufferSourceNode)return e===void 0?this.source.loop===!0?"infinite":0:(this.source.loop=!0,this.source.loopEnd=this.source.buffer?.duration||0,this.source.loopStart=0,this.source.loop===!0?"infinite":0);if("mediaElement"in this.source&&this.source.mediaElement){const t=this.source.mediaElement;return e===void 0||(t.loop=!0),t.loop===!0?"infinite":0}throw new Error("Unsupported source type")}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.isPlaying()&&("stop"in this.source&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this.playing=!1)}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");"suspend"in this.source.context&&this.source.context.suspend()}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");"resume"in this.source.context&&this.source.context.resume()}addFilter(e){super.addFilter(e),this.refreshFilters()}removeFilter(e){super.removeFilter(e),this.refreshFilters()}set position(e){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[t,i,n]=e;this.panner.positionX.setValueAtTime(t,this.context.currentTime),this.panner.positionY.setValueAtTime(i,this.context.currentTime),this.panner.positionZ.setValueAtTime(n,this.context.currentTime)}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}}class f{sounds=[];_position=[0,0,0];loopCount=0;seek(e){this.sounds.forEach(t=>t.seek&&t.seek(e))}addSound(e){this.sounds.push(e)}preplay(){return this.sounds.reduce((e,t)=>(t.loop&&t.loop(this.loopCount),e.concat(t.preplay())),[])}play(){return this.preplay().map(e=>(e.play(),e))}isPlaying(){return this.sounds.some(e=>e.isPlaying())}stop(){this.sounds.forEach(e=>e.stop())}pause(){this.sounds.forEach(e=>e.pause())}resume(){this.sounds.forEach(e=>e.resume())}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.sounds.forEach(t=>t.loop&&t.loop(e)),this.loopCount)}addFilter(e){this.sounds.forEach(t=>t.addFilter(e))}removeFilter(e){this.sounds.forEach(t=>t.removeFilter(e))}set position(e){this._position=e,this.sounds.forEach(t=>t.position=this._position)}get position(){return this._position}get volume(){return this.sounds.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.sounds.length}set volume(e){this.sounds.forEach(t=>t.volume=e)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(e){this.sounds.forEach(t=>t.playbackRate=e)}}class b extends l{context;source;gainNode;panner;constructor(e,t,i,n=0){super(),this.source=e,this.gainNode=t,this.context=i,this.panner=i.createPanner(),e.connect(this.panner).connect(this.gainNode),this.refreshFilters()}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(e){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=e}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!0)}addFilter(e){super.addFilter(e),this.refreshFilters()}removeFilter(e){super.removeFilter(e),this.refreshFilters()}set position(e){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[t,i,n]=e;this.panner.positionX.value=t,this.panner.positionY.value=i,this.panner.positionZ.value=n}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.source||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.source;this.source.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(e){}}class y extends l{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(e){super(),this.context=e,this.microphoneGainNode=this.context.createGain()}play(){return this.stream||navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.stream=e,this.streamSource=this.context.createMediaStreamSource(this.stream),this.streamPlayback=new b(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(e=>{console.error("Error initializing microphone stream:",e)}),this.streamPlayback?[this.streamPlayback]:[]}seek(e){}isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(e){this.streamPlayback&&this.streamPlayback.addFilter(e)}removeFilter(e){this.streamPlayback&&this.streamPlayback.removeFilter(e)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(e){this.streamPlayback&&(this.streamPlayback.volume=e)}get position(){return[0,0,0]}set position(e){}loop(e){return 0}get playbackRate(){return 1}set playbackRate(e){}}const x=(s,e)=>{var t=new Uint8Array(s.byteLength+e.byteLength);return t.set(new Uint8Array(s),0),t.set(new Uint8Array(e),s.byteLength),t.buffer};function C(s,e){const t=[];let i=0;fetch(s).then(function(r){if(!r.ok)throw new Error("HTTP error, status = "+r.status);if(!r.body)throw new Error("Missing body");var o=r.body.getReader();let h=new ArrayBuffer(0);function c(){return o.read().then(({value:a,done:w})=>{let p=null;if(a){if(h.byteLength?p=x(h,a.buffer):(h=a.buffer.slice(0,44),p=a.buffer),e.decodeAudioData(p,function(d){t.push(d),t.length&&n()},function(d){console.log("err(decodeAudioData): "+d)}),w){console.log("done");return}c()}})}c()});function n(){for(;t.length;){let r=t.shift();const o=e.createBufferSource();if(!r)return;o.buffer=r,o.connect(e.destination),i==0&&(i=e.currentTime+.02),o.start(i),i+=o.buffer.duration}}}exports.Cacophony=k;exports.Group=f;exports.MicrophonePlayback=b;exports.MicrophoneStream=y;exports.Playback=g;exports.Sound=u;exports.SoundType=m;
2
+ //# sourceMappingURL=cacophony.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cacophony.cjs.js","sources":["../src/cache.ts","../src/cacophony.ts"],"sourcesContent":["import { IAudioContext } from \"standardized-audio-context\";\n\nexport class CacheManager {\n private static pendingRequests = new Map<string, Promise<AudioBuffer>>();\n\n private static async openCache(): Promise<Cache> {\n try {\n return await caches.open('audio-cache');\n } catch (error) {\n console.error('Failed to open cache:', error);\n throw error;\n }\n }\n\n private static async getAudioBufferFromCache(url: string, cache: Cache, context: IAudioContext): Promise<AudioBuffer | null> {\n try {\n const response = await cache.match(url);\n if (response) {\n const arrayBuffer = await response.arrayBuffer();\n return context.decodeAudioData(arrayBuffer);\n }\n return null;\n } catch (error) {\n console.error('Failed to get audio data from cache:', error);\n throw error;\n }\n }\n\n private static async fetchAndCacheAudioBuffer(url: string, cache: Cache, context: IAudioContext): Promise<AudioBuffer> {\n try {\n const fetchResponse = await fetch(url);\n const responseClone = fetchResponse.clone();\n cache.put(url, responseClone);\n const arrayBuffer = await fetchResponse.arrayBuffer();\n return context.decodeAudioData(arrayBuffer);\n } catch (error) {\n console.error('Failed to fetch and cache audio data:', error);\n throw error;\n }\n }\n\n public static async getAudioBuffer(url: string, context: IAudioContext): Promise<AudioBuffer> {\n const cache = await this.openCache();\n\n // First, check if there's a pending request.\n let pendingRequest = this.pendingRequests.get(url);\n if (pendingRequest) {\n return pendingRequest;\n }\n\n // Try getting the buffer from cache.\n const bufferFromCache = await this.getAudioBufferFromCache(url, cache, context);\n if (bufferFromCache) {\n return bufferFromCache;\n }\n\n // If it's not in the cache, fetch and cache it.\n pendingRequest = this.fetchAndCacheAudioBuffer(url, cache, context);\n this.pendingRequests.set(url, pendingRequest);\n\n return pendingRequest;\n }\n}\n","import { AudioContext, IAudioBuffer, IAudioBufferSourceNode, IAudioListener, IBiquadFilterNode, IGainNode, IMediaElementAudioSourceNode, IMediaStreamAudioSourceNode, IPannerNode, IPannerOptions } from 'standardized-audio-context';\nimport { CacheManager } from './cache';\n\nexport enum SoundType {\n HTML = 'HTML',\n Streaming = 'Streaming',\n Buffer = 'Buffer'\n}\n\n\ntype GainNode = IGainNode<AudioContext>;\ntype BiquadFilterNode = IBiquadFilterNode<AudioContext>;\n\ntype AudioBufferSourceNode = IAudioBufferSourceNode<AudioContext>;\ntype MediaElementSourceNode = IMediaElementAudioSourceNode<AudioContext>;\n\ntype SourceNode = AudioBufferSourceNode | MediaElementSourceNode;\n\ntype PannerNode = IPannerNode<AudioContext>;\ntype MediaStreamAudioSourceNode = IMediaStreamAudioSourceNode<AudioContext>;\n\n\nexport type Position = [number, number, number];\n\nexport type Orientation = {\n forward: Position;\n up: Position;\n}\n\n\nexport type LoopCount = number | 'infinite';\n\nexport type FadeType = 'linear' | 'exponential'\n\nexport interface BaseSound {\n // the stuff you should be able to do with anything that makes sound including groups, sounds, and playbacks.\n isPlaying(): boolean;\n play(): BaseSound[];\n seek?(time: number): void;\n stop(): void;\n pause(): void;\n resume(): void;\n addFilter(filter: BiquadFilterNode): void;\n removeFilter(filter: BiquadFilterNode): void;\n volume: number;\n playbackRate: number;\n position: Position;\n loop?(loopCount?: LoopCount): LoopCount;\n // Getter and setter for threeDOptions representing PannerNode attributes\n threeDOptions?: IPannerOptions;\n}\n\nexport class Cacophony {\n context: AudioContext;\n globalGainNode: GainNode;\n listener: IAudioListener;\n private prevVolume: number = 1;\n private finalizationRegistry: FinalizationRegistry<Playback>;\n\n constructor(context?: AudioContext) {\n this.context = context || new AudioContext();\n this.listener = this.context.listener;\n this.globalGainNode = this.context.createGain();\n this.globalGainNode.connect(this.context.destination);\n this.finalizationRegistry = new FinalizationRegistry((heldValue) => {\n // Cleanup callback for Playbacks\n heldValue.cleanup();\n });\n }\n\n async createSound(buffer: AudioBuffer, type?: SoundType): Promise<Sound>\n\n async createSound(url: string, type?: SoundType): Promise<Sound>\n\n async createSound(bufferOrUrl: AudioBuffer | string, type: SoundType = SoundType.Buffer): Promise<BaseSound> {\n if (bufferOrUrl instanceof AudioBuffer) {\n return Promise.resolve(new Sound(\"\", bufferOrUrl, this.context, this.globalGainNode, SoundType.Buffer));\n }\n const url = bufferOrUrl;\n if (type === SoundType.HTML) {\n const audio = new Audio();\n audio.src = url;\n audio.crossOrigin = 'anonymous';\n return new Sound(url, undefined, this.context, this.globalGainNode, SoundType.HTML);\n }\n return CacheManager.getAudioBuffer(url, this.context).then(buffer => new Sound(url, buffer, this.context, this.globalGainNode, type));\n }\n\n async createGroup(sounds: Sound[]): Promise<Group> {\n const group = new Group();\n sounds.forEach(sound => group.addSound(sound));\n return group;\n }\n\n async createGroupFromUrls(urls: string[]): Promise<Group> {\n const group = new Group();\n const sounds = await Promise.all(urls.map(url => this.createSound(url)));\n sounds.forEach(sound => group.addSound(sound));\n return group;\n }\n\n async createStream(url: string): Promise<Sound> {\n const stream = await createStream(url, this.context);\n const sound = new Sound(url, undefined, this.context, this.globalGainNode, SoundType.Streaming);\n return sound;\n }\n\n createBiquadFilter(type: BiquadFilterType): BiquadFilterNode {\n const filter = this.context.createBiquadFilter();\n filter.type = type;\n return filter;\n }\n\n pause() {\n if ('suspend' in this.context) {\n this.context.suspend();\n }\n }\n\n resume() {\n if ('resume' in this.context) {\n this.context.resume();\n }\n }\n\n setGlobalVolume(volume: number) {\n this.globalGainNode.gain.value = volume;\n }\n\n get volume(): number {\n return this.globalGainNode.gain.value;\n }\n\n set volume(volume: number) {\n if (this.muted) {\n this.prevVolume = volume;\n return;\n }\n this.setGlobalVolume(volume);\n }\n\n mute() {\n if (!this.muted) {\n this.prevVolume = this.globalGainNode.gain.value;\n this.setGlobalVolume(0);\n }\n }\n\n unmute() {\n if (this.muted) {\n this.setGlobalVolume(this.prevVolume);\n }\n }\n\n get muted(): boolean {\n return this.globalGainNode.gain.value === 0;\n }\n\n set muted(muted: boolean) {\n if (muted !== this.muted) {\n if (muted) {\n this.mute();\n } else {\n this.unmute();\n }\n }\n }\n\n getMicrophoneStream(): Promise<MicrophoneStream> {\n return new Promise((resolve, reject) => {\n navigator.mediaDevices.getUserMedia({ audio: true })\n .then(stream => {\n const microphoneStream = new MicrophoneStream(this.context);\n microphoneStream.play();\n resolve(microphoneStream);\n })\n .catch(err => {\n reject(err);\n });\n });\n }\n\n get listenerOrientation(): Orientation {\n return {\n forward: [this.listener.forwardX.value, this.listener.forwardY.value, this.listener.forwardZ.value],\n up: [this.listener.upX.value, this.listener.upY.value, this.listener.upZ.value]\n };\n }\n\n set listenerOrientation(orientation: Orientation) {\n const { forward, up } = orientation;\n const [forwardX, forwardY, forwardZ] = forward;\n const [upX, upY, upZ] = up;\n this.listener.forwardX.setValueAtTime(forwardX, this.context.currentTime);\n this.listener.forwardY.setValueAtTime(forwardY, this.context.currentTime);\n this.listener.forwardZ.setValueAtTime(forwardZ, this.context.currentTime);\n this.listener.upX.setValueAtTime(upX, this.context.currentTime);\n this.listener.upY.setValueAtTime(upY, this.context.currentTime);\n this.listener.upZ.setValueAtTime(upZ, this.context.currentTime);\n }\n\n get listenerUpOrientation(): Position {\n return [this.listener.upX.value, this.listener.upY.value, this.listener.upZ.value];\n }\n\n set listenerUpOrientation(up: Position) {\n const [x, y, z] = up;\n this.listener.upX.setValueAtTime(x, this.context.currentTime);\n this.listener.upY.setValueAtTime(y, this.context.currentTime);\n this.listener.upZ.setValueAtTime(z, this.context.currentTime);\n }\n\n get listenerForwardOrientation(): Position {\n return [this.listener.forwardX.value, this.listener.forwardY.value, this.listener.forwardZ.value];\n }\n\n set listenerForwardOrientation(forward: Position) {\n const [x, y, z] = forward;\n this.listener.forwardX.setValueAtTime(x, this.context.currentTime);\n this.listener.forwardY.setValueAtTime(y, this.context.currentTime);\n this.listener.forwardZ.setValueAtTime(z, this.context.currentTime);\n }\n\n get listenerPosition(): Position {\n return [this.listener.positionX.value, this.listener.positionY.value, this.listener.positionZ.value];\n }\n\n set listenerPosition(position: Position) {\n const [x, y, z] = position;\n this.listener.positionX.setValueAtTime(x, this.context.currentTime);\n this.listener.positionY.setValueAtTime(y, this.context.currentTime);\n this.listener.positionZ.setValueAtTime(z, this.context.currentTime);\n }\n\n}\n\n\nabstract class FilterManager {\n protected filters: BiquadFilterNode[] = [];\n\n addFilter(filter: BiquadFilterNode) {\n this.filters.push(filter);\n }\n\n removeFilter(filter: BiquadFilterNode) {\n this.filters = this.filters.filter(f => f !== filter);\n }\n\n applyFilters(connection: any): any {\n this.filters.reduce((prevConnection, filter) => {\n prevConnection.connect(filter);\n return filter;\n }, connection);\n return this.filters.length > 0 ? this.filters[this.filters.length - 1] : connection;\n }\n}\n\n\nexport class Sound extends FilterManager implements BaseSound {\n buffer?: IAudioBuffer;\n context: AudioContext;\n playbacks: Playback[] = [];\n private globalGainNode: GainNode;\n private _position: Position = [0, 0, 0];\n private _threeDOptions: IPannerOptions = {\n coneInnerAngle: 360,\n coneOuterAngle: 360,\n coneOuterGain: 0,\n distanceModel: 'inverse',\n maxDistance: 10000,\n channelCount: 2,\n channelCountMode: 'clamped-max',\n channelInterpretation: 'speakers',\n panningModel: 'HRTF',\n refDistance: 1,\n rolloffFactor: 1,\n positionX: 0,\n positionY: 0,\n positionZ: 0,\n orientationX: 0,\n orientationY: 0,\n orientationZ: 0\n };\n loopCount: LoopCount = 0;\n private _playbackRate: number = 1;\n private _volume: number = 1;\n\n constructor(public url: string, buffer: AudioBuffer | undefined, context: AudioContext, globalGainNode: GainNode, public type: SoundType = SoundType.Buffer) {\n super();\n this.buffer = buffer;\n this.context = context;\n this.globalGainNode = globalGainNode;\n this._position = [0, 0, 0];\n }\n\n preplay(): Playback[] {\n let source: SourceNode;\n if (this.buffer) {\n source = this.context.createBufferSource();\n source.buffer = this.buffer;\n } else {\n const audio = new Audio();\n audio.crossOrigin = 'anonymous';\n audio.src = this.url;\n audio.preload = \"auto\"\n // we have the audio, let's make a buffer source node out of it\n source = this.context.createMediaElementSource(audio);\n }\n const gainNode = this.context.createGain();\n gainNode.connect(this.globalGainNode);\n const playback = new Playback(source, gainNode, this.context, this.loopCount);\n // this.finalizationRegistry.register(playback, playback);\n playback.volume = this.volume;\n playback.playbackRate = this.playbackRate;\n this.filters.forEach(filter => playback.addFilter(filter));\n playback.threeDOptions = this.threeDOptions;\n playback.position = this.position;\n this.playbacks.push(playback);\n return [playback];\n }\n\n play(): Playback[] {\n const playback = this.preplay();\n playback.forEach(p => p.play());\n return playback;\n }\n\n stop() {\n this.playbacks.forEach(p => p.stop());\n }\n\n pause() {\n if ('suspend' in this.context) {\n this.context.suspend();\n }\n }\n\n resume(): void {\n if ('resume' in this.context) {\n this.context.resume();\n }\n }\n\n seek(time: number): void {\n this.playbacks.forEach(playback => playback.seek(time));\n }\n\n set position(position: Position) {\n this._threeDOptions.positionX = position[0];\n this._threeDOptions.positionY = position[1];\n this._threeDOptions.positionZ = position[2];\n this.playbacks.forEach(p => p.position = position);\n }\n\n get position(): Position {\n return [this._threeDOptions.positionX, this._threeDOptions.positionY, this._threeDOptions.positionZ]\n }\n\n get threeDOptions(): IPannerOptions {\n return this._threeDOptions;\n }\n\n set threeDOptions(options: Partial<IPannerOptions>) {\n this._threeDOptions = { ...this._threeDOptions, ...options };\n this.playbacks.forEach(p => p.threeDOptions = this._threeDOptions);\n }\n\n loop(loopCount?: LoopCount): LoopCount {\n if (loopCount === undefined) {\n return this.loopCount;\n }\n this.loopCount = loopCount;\n this.playbacks.forEach(p => p.sourceLoop = true);\n return this.loopCount;\n }\n\n addFilter(filter: BiquadFilterNode): void {\n super.addFilter(filter);\n this.playbacks.forEach(p => p.addFilter(filter));\n }\n\n removeFilter(filter: BiquadFilterNode): void {\n super.removeFilter(filter);\n this.playbacks.forEach(p => p.removeFilter(filter));\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set volume(volume: number) {\n this._volume = volume;\n this.playbacks.forEach(p => p.volume = volume);\n }\n\n isPlaying(): boolean {\n return this.playbacks.some(p => p.isPlaying());\n }\n\n get playbackRate(): number {\n return this._playbackRate;\n }\n\n set playbackRate(rate: number) {\n this._playbackRate = rate;\n this.playbacks.forEach(p => p.playbackRate = rate);\n }\n\n}\n\nexport class Playback extends FilterManager implements BaseSound {\n private context: AudioContext;\n private source?: SourceNode;\n private gainNode?: GainNode;\n private panner?: PannerNode;\n loopCount: LoopCount = 0;\n currentLoop: number = 0;\n private buffer?: IAudioBuffer;\n private playing: boolean = false;\n\n constructor(source: SourceNode, gainNode: GainNode, context: AudioContext, loopCount: LoopCount = 0) {\n super();\n this.loopCount = loopCount;\n this.source = source;\n if ('buffer' in source && source.buffer) {\n this.buffer = source.buffer;\n }\n if ('mediaElement' in source && source.mediaElement) {\n source.mediaElement.onended = this.handleLoop.bind(this);\n } else if ('onended' in source) {\n source.onended = this.handleLoop.bind(this);\n }\n this.gainNode = gainNode;\n this.context = context;\n this.panner = context.createPanner();\n source.connect(this.panner);\n this.panner.connect(this.gainNode);\n this.refreshFilters();\n }\n\n get playbackRate() {\n if (!this.source) {\n throw new Error('Cannot get playback rate of a sound that has been cleaned up');\n }\n if ('playbackRate' in this.source) {\n return this.source.playbackRate.value;\n }\n if ('mediaElement' in this.source && this.source.mediaElement) {\n return this.source.mediaElement.playbackRate;\n }\n throw new Error('Unsupported source type');\n }\n set playbackRate(rate: number) {\n if (!this.source) {\n throw new Error('Cannot set playback rate of a sound that has been cleaned up');\n }\n if ('playbackRate' in this.source) {\n this.source.playbackRate.value = rate;\n }\n if ('mediaElement' in this.source && this.source.mediaElement) {\n this.source.mediaElement.playbackRate = rate;\n }\n }\n\n handleLoop() {\n if (this.buffer) {\n this.source = this.context.createBufferSource();\n this.source.buffer = this.buffer;\n } else {\n this.seek(0);\n }\n if (this.loopCount === 'infinite' || this.currentLoop < this.loopCount) {\n this.currentLoop++;\n if (this.playing) {\n this.play();\n }\n } else {\n this.playing = false;\n }\n }\n\n\n play(): [this] {\n if (!this.source) {\n throw new Error('Cannot play a sound that has been cleaned up');\n }\n if ('mediaElement' in this.source && this.source.mediaElement) {\n this.source.mediaElement.play();\n } else if ('start' in this.source && this.source.start) {\n this.source.start();\n }\n this.playing = true;\n return [this];\n }\n\n get threeDOptions(): IPannerOptions {\n if (!this.panner) {\n throw new Error('Cannot get 3D options of a sound that has been cleaned up');\n }\n return {\n coneInnerAngle: this.panner.coneInnerAngle,\n coneOuterAngle: this.panner.coneOuterAngle,\n coneOuterGain: this.panner.coneOuterGain,\n distanceModel: this.panner.distanceModel,\n maxDistance: this.panner.maxDistance,\n channelCount: this.panner.channelCount,\n channelCountMode: this.panner.channelCountMode,\n channelInterpretation: this.panner.channelInterpretation,\n panningModel: this.panner.panningModel,\n refDistance: this.panner.refDistance,\n rolloffFactor: this.panner.rolloffFactor,\n positionX: this.panner.positionX.value,\n positionY: this.panner.positionY.value,\n positionZ: this.panner.positionZ.value,\n orientationX: this.panner.orientationX.value,\n orientationY: this.panner.orientationY.value,\n orientationZ: this.panner.orientationZ.value\n }\n }\n\n set threeDOptions(options: Partial<IPannerOptions>) {\n if (!this.panner) {\n throw new Error('Cannot set 3D options of a sound that has been cleaned up');\n }\n this.panner.coneInnerAngle = options.coneInnerAngle || this.panner.coneInnerAngle;\n this.panner.coneOuterAngle = options.coneOuterAngle || this.panner.coneOuterAngle;\n this.panner.coneOuterGain = options.coneOuterGain || this.panner.coneOuterGain;\n this.panner.distanceModel = options.distanceModel || this.panner.distanceModel;\n this.panner.maxDistance = options.maxDistance || this.panner.maxDistance;\n this.panner.channelCount = options.channelCount || this.panner.channelCount;\n this.panner.channelCountMode = options.channelCountMode || this.panner.channelCountMode;\n this.panner.channelInterpretation = options.channelInterpretation || this.panner.channelInterpretation;\n this.panner.panningModel = options.panningModel || this.panner.panningModel;\n this.panner.refDistance = options.refDistance || this.panner.refDistance;\n this.panner.rolloffFactor = options.rolloffFactor || this.panner.rolloffFactor;\n this.panner.positionX.value = options.positionX || this.panner.positionX.value;\n this.panner.positionY.value = options.positionY || this.panner.positionY.value;\n this.panner.positionZ.value = options.positionZ || this.panner.positionZ.value;\n this.panner.orientationX.value = options.orientationX || this.panner.orientationX.value;\n this.panner.orientationY.value = options.orientationY || this.panner.orientationY.value;\n this.panner.orientationZ.value = options.orientationZ || this.panner.orientationZ.value;\n }\n\n seek(time: number): void {\n if (!this.source || !this.buffer || !this.gainNode || !this.panner) {\n throw new Error('Cannot seek a sound that has been cleaned up');\n }\n const playing = this.isPlaying();\n // Stop the current playback\n this.stop(); // Create a new source to start from the desired time\n this.source = this.context.createBufferSource();\n this.source.buffer = this.buffer;\n this.refreshFilters();\n this.source.connect(this.panner).connect(this.gainNode);\n if (playing) {\n this.source.start(0, time);\n }\n }\n\n get volume(): number {\n if (!this.gainNode) {\n throw new Error('Cannot get volume of a sound that has been cleaned up');\n }\n return this.gainNode.gain.value;\n }\n\n set volume(v: number) {\n if (!this.gainNode) {\n throw new Error('Cannot set volume of a sound that has been cleaned up');\n }\n this.gainNode.gain.value = v;\n }\n\n set sourceLoop(loop: boolean) {\n if (!this.source) {\n throw new Error('Cannot set loop on a sound that has been cleaned up');\n }\n if ('loop' in this.source) {\n this.source.loop = loop;\n }\n if (\"mediaElement\" in this.source && this.source.mediaElement) {\n this.source.mediaElement.loop = loop;\n }\n }\n\n fadeIn(time: number, fadeType: FadeType = 'linear'): Promise<void> {\n return new Promise(resolve => {\n if (!this.gainNode) {\n throw new Error('Cannot fade in a sound that has been cleaned up');\n }\n\n const initialVolume = this.gainNode.gain.value;\n const targetVolume = 1; // Assuming the target volume after fade-in is 1 (full volume)\n\n // Reset volume to 0 to start the fade-in process\n this.gainNode.gain.value = 0;\n\n switch (fadeType) {\n case 'exponential':\n // Start at a low value (0.01) because exponentialRampToValueAtTime cannot ramp from 0\n this.gainNode.gain.setValueAtTime(0.01, this.context.currentTime);\n this.gainNode.gain.exponentialRampToValueAtTime(targetVolume, this.context.currentTime + time);\n break;\n case 'linear':\n this.gainNode.gain.linearRampToValueAtTime(targetVolume, this.context.currentTime + time);\n break;\n }\n\n // Resolve the Promise after the fade-in time\n setTimeout(() => {\n // Ensure the final volume is set to the target volume\n if (!this.gainNode) {\n throw new Error('Cannot fade in a sound that has been cleaned up');\n }\n this.gainNode.gain.value = targetVolume;\n resolve();\n }, time * 1000);\n });\n }\n\n fadeOut(time: number, fadeType: FadeType = 'linear'): Promise<void> {\n return new Promise(resolve => {\n // Storing the current gain value\n if (!this.gainNode) {\n throw new Error('Cannot fade out a sound that has been cleaned up');\n }\n const initialVolume = this.gainNode.gain.value;\n switch (fadeType) {\n case 'exponential':\n // Scheduling an exponential fade down\n this.gainNode.gain.exponentialRampToValueAtTime(0.01, this.context.currentTime + time);\n break;\n case 'linear':\n\n // Scheduling a linear ramp to 0 over the given duration\n this.gainNode.gain.linearRampToValueAtTime(0, this.context.currentTime + time);\n }\n // Resolving the Promise after the fade-out time\n setTimeout(() => resolve(), time * 1000);\n });\n }\n\n isPlaying(): boolean {\n if (!this.source) {\n throw new Error('Cannot check if a sound is playing that has been cleaned up');\n }\n return this.playing;\n }\n\n cleanup(): void {\n // Ensure cleanup is idempotent\n if (this.source) {\n this.source.disconnect();\n this.source = undefined;\n }\n if (this.gainNode) {\n this.gainNode.disconnect();\n this.gainNode = undefined;\n }\n this.filters.forEach(filter => {\n if (filter) {\n filter.disconnect();\n }\n });\n this.filters = [];\n // Additional cleanup logic if needed\n }\n\n loop(loopCount?: LoopCount): LoopCount {\n if (!this.source) {\n throw new Error('Cannot loop a sound that has been cleaned up');\n }\n\n // Check if the source is an AudioBufferSourceNode\n if (this.source instanceof AudioBufferSourceNode) {\n if (loopCount === undefined) {\n return this.source.loop === true ? 'infinite' : 0;\n }\n this.source.loop = true;\n this.source.loopEnd = this.source.buffer?.duration || 0;\n this.source.loopStart = 0;\n return this.source.loop === true ? 'infinite' : 0;\n }\n\n // Check if the source is a MediaElementSourceNode\n if (\"mediaElement\" in this.source && this.source.mediaElement) {\n const mediaElement = this.source.mediaElement;\n if (loopCount === undefined) {\n return mediaElement.loop === true ? 'infinite' : 0;\n }\n mediaElement.loop = true;\n // Looping for HTMLMediaElement is controlled by the 'loop' attribute, no need for loopStart or loopEnd\n return mediaElement.loop === true ? 'infinite' : 0;\n }\n\n throw new Error('Unsupported source type');\n }\n\n stop(): void {\n if (!this.source) {\n throw new Error('Cannot stop a sound that has been cleaned up');\n }\n if (!this.isPlaying()) {\n return;\n }\n if ('stop' in this.source) {\n this.source.stop();\n }\n if (\"mediaElement\" in this.source && this.source.mediaElement) {\n this.source.mediaElement.pause();\n this.source.mediaElement.currentTime = 0;\n }\n this.playing = false;\n }\n\n pause(): void {\n if (!this.source) {\n throw new Error('Cannot pause a sound that has been cleaned up');\n }\n if ('suspend' in this.source.context) {\n this.source.context.suspend();\n }\n }\n\n resume(): void {\n if (!this.source) {\n throw new Error('Cannot resume a sound that has been cleaned up');\n }\n if ('resume' in this.source.context) {\n this.source.context.resume();\n }\n }\n\n addFilter(filter: BiquadFilterNode): void {\n super.addFilter(filter);\n this.refreshFilters();\n }\n\n removeFilter(filter: BiquadFilterNode): void {\n super.removeFilter(filter);\n this.refreshFilters();\n }\n\n set position(position: Position) {\n if (!this.panner) {\n throw new Error('Cannot move a sound that has been cleaned up');\n }\n const [x, y, z] = position;\n this.panner.positionX.setValueAtTime(x, this.context.currentTime);\n this.panner.positionY.setValueAtTime(y, this.context.currentTime);\n this.panner.positionZ.setValueAtTime(z, this.context.currentTime);\n }\n\n get position(): Position {\n if (!this.panner) {\n throw new Error('Cannot get position of a sound that has been cleaned up');\n }\n return [this.panner.positionX.value, this.panner.positionY.value, this.panner.positionZ.value];\n }\n\n private refreshFilters(): void {\n if (!this.panner || !this.gainNode) {\n throw new Error('Cannot update filters on a sound that has been cleaned up');\n }\n let connection = this.panner;\n connection.disconnect();\n connection = this.applyFilters(connection);\n connection.connect(this.gainNode);\n }\n}\n\n\nexport class Group implements BaseSound {\n sounds: BaseSound[] = [];\n private _position: Position = [0, 0, 0];\n loopCount: LoopCount = 0;\n\n seek(time: number): void {\n this.sounds.forEach(sound => sound.seek && sound.seek(time));\n }\n\n addSound(sound: BaseSound): void {\n this.sounds.push(sound);\n }\n\n preplay(): Playback[] {\n return (this.sounds as Sound[]).reduce<Playback[]>((playbacks, sound) => {\n sound.loop && sound.loop(this.loopCount);\n return playbacks.concat(sound.preplay());\n }, []);\n }\n\n play(): Playback[] {\n return this.preplay().map(playback => {\n playback.play();\n return playback;\n });\n }\n\n isPlaying(): boolean {\n return this.sounds.some(sound => sound.isPlaying());\n }\n\n stop(): void {\n this.sounds.forEach(sound => sound.stop());\n }\n\n pause(): void {\n this.sounds.forEach(sound => sound.pause());\n }\n\n resume(): void {\n this.sounds.forEach(sound => sound.resume());\n }\n\n loop(loopCount?: LoopCount): LoopCount {\n if (loopCount === undefined) {\n return this.loopCount;\n }\n this.loopCount = loopCount;\n this.sounds.forEach(sound => sound.loop && sound.loop(loopCount));\n return this.loopCount;\n }\n\n addFilter(filter: BiquadFilterNode): void {\n this.sounds.forEach(sound => sound.addFilter(filter));\n }\n\n removeFilter(filter: BiquadFilterNode): void {\n this.sounds.forEach(sound => sound.removeFilter(filter));\n }\n\n set position(position: [number, number, number]) {\n this._position = position;\n this.sounds.forEach(sound => sound.position = this._position);\n }\n\n get position(): [number, number, number] {\n return this._position;\n }\n\n get volume(): number {\n return this.sounds.map(sound => sound.volume).reduce((a, b) => a + b, 0) / this.sounds.length;\n }\n\n set volume(volume: number) {\n this.sounds.forEach(sound => sound.volume = volume);\n }\n\n get playbackRate(): number {\n if (this.sounds.length === 0) {\n return 1;\n }\n return this.sounds[0].playbackRate\n }\n\n set playbackRate(rate: number) {\n this.sounds.forEach(sound => sound.playbackRate = rate);\n }\n\n\n}\n\nexport class MicrophonePlayback extends FilterManager {\n private context: AudioContext;\n private source?: MediaStreamAudioSourceNode;\n private gainNode?: GainNode;\n private panner?: PannerNode;\n\n constructor(source: MediaStreamAudioSourceNode, gainNode: GainNode, context: AudioContext, loopCount: LoopCount = 0) {\n super();\n this.source = source;\n this.gainNode = gainNode;\n this.context = context;\n this.panner = context.createPanner();\n source.connect(this.panner).connect(this.gainNode);\n this.refreshFilters();\n }\n\n play() {\n if (!this.source) {\n throw new Error('Cannot play a sound that has been cleaned up');\n }\n return [this];\n }\n\n isPlaying() {\n return Boolean(this.source);\n }\n\n get volume(): number {\n if (!this.gainNode) {\n throw new Error('Cannot get volume of a sound that has been cleaned up');\n }\n return this.gainNode.gain.value;\n }\n\n set volume(v: number) {\n if (!this.gainNode) {\n throw new Error('Cannot set volume of a sound that has been cleaned up');\n }\n this.gainNode.gain.value = v;\n }\n\n stop(): void {\n if (!this.source) {\n throw new Error('Cannot stop a sound that has been cleaned up');\n }\n this.source.mediaStream.getTracks().forEach(track => track.stop());\n }\n\n pause(): void {\n if (!this.source) {\n throw new Error('Cannot pause a sound that has been cleaned up');\n }\n this.source.mediaStream.getTracks().forEach(track => track.enabled = false);\n }\n\n resume(): void {\n if (!this.source) {\n throw new Error('Cannot resume a sound that has been cleaned up');\n }\n this.source.mediaStream.getTracks().forEach(track => track.enabled = true);\n }\n\n addFilter(filter: BiquadFilterNode): void {\n super.addFilter(filter);\n this.refreshFilters();\n }\n\n removeFilter(filter: BiquadFilterNode): void {\n super.removeFilter(filter);\n this.refreshFilters();\n }\n\n set position(position: Position) {\n if (!this.panner) {\n throw new Error('Cannot move a sound that has been cleaned up');\n }\n const [x, y, z] = position;\n this.panner.positionX.value = x;\n this.panner.positionY.value = y;\n this.panner.positionZ.value = z;\n }\n\n get position(): Position {\n if (!this.panner) {\n throw new Error('Cannot get position of a sound that has been cleaned up');\n }\n return [this.panner.positionX.value, this.panner.positionY.value, this.panner.positionZ.value];\n }\n\n private refreshFilters(): void {\n if (!this.source || !this.gainNode) {\n throw new Error('Cannot update filters on a sound that has been cleaned up');\n }\n let connection = this.source;\n this.source.disconnect();\n connection = this.applyFilters(connection);\n connection.connect(this.gainNode);\n }\n\n get playbackRate(): number {\n // Playback rate is not applicable for live microphone stream\n return 1;\n }\n\n set playbackRate(rate: number) {\n }\n\n\n\n}\n\nexport class MicrophoneStream extends FilterManager implements BaseSound {\n context: AudioContext;\n private _position: Position = [0, 0, 0];\n loopCount: LoopCount = 0;\n private prevVolume: number = 1;\n private microphoneGainNode: GainNode;\n private streamPlayback?: MicrophonePlayback;\n private stream: MediaStream | undefined;\n private streamSource?: MediaStreamAudioSourceNode;\n\n constructor(context: AudioContext) {\n super();\n this.context = context;\n this.microphoneGainNode = this.context.createGain();\n }\n\n play(): MicrophonePlayback[] {\n if (!this.stream) {\n navigator.mediaDevices.getUserMedia({ audio: true })\n .then(stream => {\n this.stream = stream;\n this.streamSource = this.context.createMediaStreamSource(this.stream);\n this.streamPlayback = new MicrophonePlayback(this.streamSource, this.microphoneGainNode, this.context);\n this.streamPlayback.play();\n })\n .catch(err => {\n console.error('Error initializing microphone stream:', err);\n });\n }\n return this.streamPlayback ? [this.streamPlayback] : [];\n }\n\n seek(time: number) {\n // Seeking is not applicable for live microphone stream\n }\n\n isPlaying(): boolean {\n return Boolean(this.streamPlayback);\n }\n\n stop() {\n if (this.streamPlayback) {\n this.streamPlayback.stop();\n this.streamPlayback = undefined;\n }\n }\n\n pause() {\n if (this.streamPlayback) {\n this.streamPlayback.pause();\n }\n }\n\n resume() {\n if (this.streamPlayback) {\n this.streamPlayback.resume();\n }\n }\n\n addFilter(filter: BiquadFilterNode): void {\n if (this.streamPlayback) {\n this.streamPlayback.addFilter(filter);\n }\n }\n\n removeFilter(filter: BiquadFilterNode): void {\n if (this.streamPlayback) {\n this.streamPlayback.removeFilter(filter);\n }\n }\n\n get volume(): number {\n return this.streamPlayback ? this.streamPlayback.volume : 0;\n }\n\n set volume(volume: number) {\n if (this.streamPlayback) {\n this.streamPlayback.volume = volume;\n }\n }\n\n get position(): Position {\n // Position is not applicable for live microphone stream\n return [0, 0, 0];\n }\n\n set position(position: Position) {\n // Position is not applicable for live microphone stream\n }\n\n loop(loopCount?: LoopCount): LoopCount {\n // Looping is not applicable for live microphone stream\n return 0;\n }\n\n\n get playbackRate(): number {\n // Playback rate is not applicable for live microphone stream\n return 1;\n }\n\n set playbackRate(rate: number) {\n }\n\n}\n\n\nconst appendBuffer = (buffer1: ArrayBuffer, buffer2: ArrayBuffer): ArrayBuffer => {\n var tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength);\n tmp.set(new Uint8Array(buffer1), 0);\n tmp.set(new Uint8Array(buffer2), buffer1.byteLength);\n return tmp.buffer;\n}\n\n\nfunction createStream(url: string, context: AudioContext) {\n const audioStack: IAudioBuffer[] = [];\n let nextTime = 0;\n\n fetch(url).then(function (response) {\n if (!response.ok) {\n throw new Error('HTTP error, status = ' + response.status);\n }\n if (!response.body) {\n throw new Error('Missing body');\n }\n\n var reader = response.body.getReader();\n let header = new ArrayBuffer(0);//first 44bytes\n\n function read() {\n return reader.read().then(({ value, done }) => {\n let audioBuffer = null;\n if (!value) {\n return;\n }\n\n if (!header.byteLength) {\n //copy first 44 bytes (wav header)\n header = value.buffer.slice(0, 44);\n audioBuffer = value.buffer;\n } else {\n audioBuffer = appendBuffer(header, value.buffer);\n }\n\n context.decodeAudioData(audioBuffer, function (buffer) {\n\n audioStack.push(buffer);\n if (audioStack.length) {\n scheduleBuffers();\n }\n }, function (err) {\n console.log(\"err(decodeAudioData): \" + err);\n });\n if (done) {\n console.log('done');\n return;\n }\n //read next buffer\n read();\n });\n }\n read();\n })\n\n function scheduleBuffers() {\n while (audioStack.length) {\n let buffer = audioStack.shift();\n const source = context.createBufferSource();\n if (!buffer) {\n return;\n }\n source.buffer = buffer;\n source.connect(context.destination);\n if (nextTime == 0)\n nextTime = context.currentTime + 0.02; /// add 50ms latency to work well across systems - tune this if you like\n source.start(nextTime);\n nextTime += source.buffer.duration; // Make the next buffer wait the length of the last buffer before being played\n };\n }\n}\n\n"],"names":["CacheManager","error","url","cache","context","response","arrayBuffer","fetchResponse","responseClone","pendingRequest","bufferFromCache","SoundType","Cacophony","AudioContext","heldValue","bufferOrUrl","type","Sound","audio","buffer","sounds","group","Group","sound","urls","createStream","filter","volume","muted","resolve","reject","stream","microphoneStream","MicrophoneStream","err","orientation","forward","up","forwardX","forwardY","forwardZ","upX","upY","upZ","x","y","z","position","FilterManager","f","connection","prevConnection","globalGainNode","source","gainNode","playback","Playback","p","time","options","loopCount","rate","playing","v","loop","fadeType","targetVolume","mediaElement","playbacks","a","b","MicrophonePlayback","track","appendBuffer","buffer1","buffer2","tmp","audioStack","nextTime","reader","header","read","value","done","audioBuffer","scheduleBuffers"],"mappings":"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"}
@@ -206,4 +206,3 @@ export declare class MicrophoneStream extends FilterManager implements BaseSound
206
206
  set playbackRate(rate: number);
207
207
  }
208
208
  export {};
209
- //# sourceMappingURL=cacophony.d.ts.map