cm-web-modules
Advanced tools
Comparing version 2.2.0 to 2.3.0
{ | ||
"name": "cm-web-modules", | ||
"version": "2.2.0", | ||
"version": "2.3.0", | ||
"description": "Collection of clean and small ES6 modules for the web", | ||
@@ -5,0 +5,0 @@ "main": "src/LibraryManager.js", |
@@ -9,80 +9,63 @@ // noinspection JSUnresolvedVariable | ||
export class Audio { | ||
let audioContext = new AudioContext() | ||
const mainGainNode = audioContext.createGain() | ||
mainGainNode.gain.value = 1 | ||
mainGainNode.connect(audioContext.destination) | ||
constructor(props = {}) { | ||
if (this.audioContext) { | ||
console.warn("AudioContext already created") | ||
} | ||
this.props = { | ||
gain: 1, | ||
debug: false, | ||
...props | ||
} | ||
this.events = [ | ||
{name: 'click'}, {name: 'touchstart'}, {name: 'touchend'}, {name: 'keydown'}, {name: 'mousedown'}, {name: 'mouseup'}, {name: 'dblclick'} | ||
] | ||
this.audioContext = new AudioContext() | ||
this.mainGainNode = this.audioContext.createGain() | ||
this.mainGainNode.gain.value = this.props.gain | ||
this.mainGainNode.connect(this.audioContext.destination) | ||
this.addEventListeners() | ||
if(this.props.debug) { | ||
console.log("AudioContext created, state:", this.audioContext.state) | ||
} | ||
} | ||
const events = ['click', 'touchstart', 'touchend', 'keydown', 'mousedown', 'mouseup', 'dblclick'] | ||
static getInstance(props) { | ||
if (!Audio.instance) { | ||
Audio.instance = new Audio(props) | ||
function addEventListeners() { | ||
events.forEach(event => { | ||
document.addEventListener(event, resumeAudioContext) | ||
}) | ||
document.addEventListener('visibilitychange', () => { | ||
if (!document.hidden) { | ||
setTimeout(resumeAudioContext, 200) | ||
} | ||
return Audio.instance | ||
} | ||
}) | ||
} | ||
addEventListeners() { | ||
this.events.forEach(event => { | ||
const listener = this.resumeAudioContext.bind(this) | ||
document.addEventListener(event.name, listener) | ||
event.listener = listener | ||
function removeEventListeners() { | ||
events.forEach(event => { | ||
document.removeEventListener(event, resumeAudioContext) | ||
}) | ||
} | ||
// start context after user interaction | ||
function resumeAudioContext() { | ||
if (audioContext.state !== "running") { | ||
audioContext.resume().then(() => { | ||
console.log('AudioContext resumed successfully, state:', audioContext.state) | ||
removeEventListeners() | ||
}).catch(error => { | ||
console.log('Failed to resume AudioContext:', error) | ||
}) | ||
/* | ||
document.addEventListener('visibilitychange', () => { | ||
if (!document.hidden) { | ||
setTimeout(this.resumeAudioContext, 200) | ||
} | ||
}) | ||
*/ | ||
} | ||
} | ||
removeEventListeners() { | ||
this.events.forEach(event => { | ||
document.removeEventListener(event.name, event.listener) | ||
}) | ||
console.log("AudioContext.state:", audioContext.state) | ||
addEventListeners() | ||
export class Audio { | ||
static context() { | ||
return audioContext | ||
} | ||
// start context after user interaction | ||
resumeAudioContext() { | ||
if (this.audioContext.state !== "running") { | ||
this.audioContext.resume().then(() => { | ||
if(this.props.debug) { | ||
console.log('AudioContext resumed successfully, state:', this.audioContext.state) | ||
} | ||
this.removeEventListeners() | ||
}).catch(error => { | ||
console.log('Failed to resume AudioContext:', error) | ||
}) | ||
} | ||
static destination() { | ||
return mainGainNode | ||
} | ||
set gain(gain) { | ||
this.mainGainNode.gain.setValueAtTime(gain, this.audioContext.currentTime) | ||
static setGain(gain) { | ||
mainGainNode.gain.setValueAtTime(gain, audioContext.currentTime) | ||
} | ||
get running() { | ||
return this.audioContext.state === "running" | ||
static isEnabled() { | ||
return audioContext.state === "running" | ||
} | ||
addStateListener(listener) { | ||
this.audioContext.addEventListener("statechange", listener) | ||
static addStateListener(listener) { | ||
audioContext.addEventListener("statechange", listener) | ||
} | ||
} |
@@ -7,11 +7,7 @@ /** | ||
import {Audio} from "./Audio.js" | ||
export class Sample { | ||
/** | ||
* @param audio Audio | ||
* @param src | ||
* @param props | ||
*/ | ||
constructor(audio, src, props = {}) { | ||
this.audio = audio | ||
constructor(src, props = {}) { | ||
this.src = src | ||
@@ -23,3 +19,3 @@ this.props = { | ||
Object.assign(this.props, props) | ||
this.gainNode = this.audio.audioContext.createGain() | ||
this.gainNode = Audio.context().createGain() | ||
this.setGain(this.props.gain) | ||
@@ -31,7 +27,7 @@ this.audioBuffer = null | ||
setGain(gain) { | ||
this.gainNode.gain.setValueAtTime(gain, this.audio.audioContext.currentTime) | ||
this.gainNode.gain.setValueAtTime(gain, Audio.context().currentTime) | ||
} | ||
play(when = undefined, offset = undefined, duration = undefined) { | ||
if (this.props.startWithoutAudioContext || this.audio.running()) { | ||
if (this.props.startWithoutAudioContext || Audio.isEnabled()) { | ||
this.loading.then(() => { | ||
@@ -47,6 +43,6 @@ let source | ||
createBufferSource() { | ||
const source = this.audio.audioContext.createBufferSource() | ||
const source = Audio.context().createBufferSource() | ||
source.buffer = this.audioBuffer | ||
source.connect(this.gainNode) | ||
this.gainNode.connect(this.audio.mainGainNode) | ||
this.gainNode.connect(Audio.destination()) | ||
return source | ||
@@ -61,3 +57,3 @@ } | ||
request.onload = () => { | ||
this.audio.audioContext.decodeAudioData(request.response, (audioBuffer) => { | ||
Audio.context().decodeAudioData(request.response, (audioBuffer) => { | ||
this.audioBuffer = audioBuffer | ||
@@ -64,0 +60,0 @@ resolve() |
Sorry, the diff of this file is not supported yet
135082
2232