@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
2 lines (1 loc) • 3.74 kB
JavaScript
import{math as s}from"../../core/math/math.js";import{hasAudioContext as t}from"./capabilities.js";class e{constructor(s,e,i={}){var o,h,u;if(this.volume=null!=(o=i.volume)?o:1,this.loop=null!=(h=i.loop)&&h,this.pitch=null!=(u=i.pitch)?u:1,this.sound=e,this.paused=!1,this.suspended=!1,this.manager=s,this.source=null,t()){this.startTime=0,this.startOffset=0;const t=s.context;this.gain=t.createGain()}else e.audio&&(this.source=e.audio.cloneNode(!1),this.source.pause())}getVolume(){return this.volume}getLoop(){return this.loop}setLoop(s){this.loop=s,this.source&&(this.source.loop=s)}getPitch(){return this.pitch}onManagerVolumeChange(){this.setVolume(this.getVolume())}onManagerSuspend(){this.isPlaying()&&!this.suspended&&(this.suspended=!0,this.pause())}onManagerResume(){this.suspended&&(this.suspended=!1,this.unpause())}play(){if(this.source)throw new Error("Call stop() before calling play()");this._createSource(),this.source&&(this.startTime=this.manager.context.currentTime,this.source.start(0,this.startOffset%this.source.buffer.duration),this.setVolume(this.volume),this.setLoop(this.loop),this.setPitch(this.pitch),this.manager.on("volumechange",this.onManagerVolumeChange,this),this.manager.on("suspend",this.onManagerSuspend,this),this.manager.on("resume",this.onManagerResume,this),this.manager.suspended&&this.onManagerSuspend())}pause(){this.source&&(this.paused=!0,this.startOffset+=this.manager.context.currentTime-this.startTime,this.source.stop(0),this.source=null)}unpause(){!this.source&&this.paused?(this._createSource(),this.source&&(this.startTime=this.manager.context.currentTime,this.source.start(0,this.startOffset%this.source.buffer.duration),this.setVolume(this.volume),this.setLoop(this.loop),this.setPitch(this.pitch),this.paused=!1)):console.warn("Call pause() before unpausing.")}stop(){this.source&&(this.source.stop(0),this.source=null),this.manager.off("volumechange",this.onManagerVolumeChange,this),this.manager.off("suspend",this.onManagerSuspend,this),this.manager.off("resume",this.onManagerResume,this)}setVolume(t){t=s.clamp(t,0,1),this.volume=t,this.gain&&(this.gain.gain.value=t*this.manager.volume)}setPitch(s){this.pitch=s,this.source&&(this.source.playbackRate.value=s)}isPlaying(){return!this.paused&&this.source.playbackState===this.source.PLAYING_STATE}getDuration(){return this.source?this.source.buffer.duration:0}_createSource(){const s=this.manager.context;this.sound.buffer&&(this.source=s.createBufferSource(),this.source.buffer=this.sound.buffer,this.source.connect(this.gain),this.gain.connect(s.destination),this.loop||(this.source.onended=this.pause.bind(this)))}}t()||Object.assign(e.prototype,{play:function(){this.source&&(this.paused=!1,this.setVolume(this.volume),this.setLoop(this.loop),this.setPitch(this.pitch),this.source.play()),this.manager.on("volumechange",this.onManagerVolumeChange,this),this.manager.on("suspend",this.onManagerSuspend,this),this.manager.on("resume",this.onManagerResume,this),this.manager.suspended&&this.onManagerSuspend()},pause:function(){this.source&&(this.paused=!0,this.source.pause())},unpause:function(){this.source&&(this.paused=!1,this.source.play())},stop:function(){this.source&&this.source.pause(),this.manager.off("volumechange",this.onManagerVolumeChange,this),this.manager.off("suspend",this.onManagerSuspend,this),this.manager.off("resume",this.onManagerResume,this)},setVolume:function(t){t=s.clamp(t,0,1),this.volume=t,this.source&&(this.source.volume=t*this.manager.volume)},setPitch:function(s){this.pitch=s,this.source&&(this.source.playbackRate=s)},getDuration:function(){return this.source&&!isNaN(this.source.duration)?this.source.duration:0},isPlaying:function(){return!this.source.paused}});export{e as Channel};