@combos-fun/plugin-sound 0.0.29 → 0.0.31
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.
package/dist/plugin-sound.cjs.js
CHANGED
|
@@ -6,22 +6,36 @@ var engine = require('@combos-fun/engine');
|
|
|
6
6
|
let SoundSystem$1 = class SoundSystem extends engine.System {
|
|
7
7
|
static { this.systemName = 'SoundSystem'; }
|
|
8
8
|
get muted() {
|
|
9
|
-
return this.
|
|
9
|
+
return this._muted;
|
|
10
10
|
}
|
|
11
11
|
set muted(v) {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
this.gainNode.gain.setValueAtTime(v ? 0 : 1, 0);
|
|
12
|
+
this._muted = v;
|
|
13
|
+
this.applyGain();
|
|
16
14
|
}
|
|
17
15
|
get volume() {
|
|
18
|
-
return this.
|
|
16
|
+
return this._volume;
|
|
19
17
|
}
|
|
20
18
|
set volume(v) {
|
|
21
|
-
if (
|
|
19
|
+
if (typeof v !== 'number' || v < 0 || v > 1) {
|
|
22
20
|
return;
|
|
23
21
|
}
|
|
24
|
-
this.
|
|
22
|
+
this._volume = v;
|
|
23
|
+
this.applyGain();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Apply the effective gain (`muted ? 0 : volume`) to the gain node.
|
|
27
|
+
*
|
|
28
|
+
* Assigns `gain.value` directly rather than `setValueAtTime`: `.value` updates
|
|
29
|
+
* the AudioParam's intrinsic value synchronously, so the `muted` / `volume`
|
|
30
|
+
* getters reflect the change immediately. `setValueAtTime` only schedules an
|
|
31
|
+
* event on the automation timeline and leaves `.value` stale until the next
|
|
32
|
+
* render quantum, which made `muted` report the pre-change value.
|
|
33
|
+
*/
|
|
34
|
+
applyGain() {
|
|
35
|
+
if (!this.gainNode) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
this.gainNode.gain.value = this._muted ? 0 : this._volume;
|
|
25
39
|
}
|
|
26
40
|
get audioLocked() {
|
|
27
41
|
if (!this.ctx) {
|
|
@@ -37,6 +51,9 @@ let SoundSystem$1 = class SoundSystem extends engine.System {
|
|
|
37
51
|
this.pausedComponents = [];
|
|
38
52
|
this.audioBufferCache = {};
|
|
39
53
|
this.decodeAudioPromiseMap = {};
|
|
54
|
+
/** Desired mute/volume are the source of truth; the gain node is derived. */
|
|
55
|
+
this._muted = false;
|
|
56
|
+
this._volume = 1;
|
|
40
57
|
Object.assign(this, obj);
|
|
41
58
|
}
|
|
42
59
|
/**
|
|
@@ -145,7 +162,7 @@ let SoundSystem$1 = class SoundSystem extends engine.System {
|
|
|
145
162
|
}
|
|
146
163
|
this.gainNode =
|
|
147
164
|
typeof this.ctx.createGain === 'undefined' ? this.ctx.createGainNode() : this.ctx.createGain();
|
|
148
|
-
this.
|
|
165
|
+
this.applyGain();
|
|
149
166
|
this.gainNode.connect(this.ctx.destination);
|
|
150
167
|
this.unlockAudio();
|
|
151
168
|
}
|
|
@@ -235,7 +252,7 @@ var SoundSystem = SoundSystem$1;
|
|
|
235
252
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
236
253
|
Object.assign(SoundSystem, {
|
|
237
254
|
packageName: "@combos-fun/plugin-sound",
|
|
238
|
-
packageVersion: "0.0.
|
|
255
|
+
packageVersion: "0.0.31",
|
|
239
256
|
});
|
|
240
257
|
|
|
241
258
|
class Sound extends engine.Component {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-sound.cjs.js","sources":["../lib/SoundSystem.ts","../lib/__combosPackageMeta.gen.ts","../lib/Sound.ts"],"sourcesContent":["import { System, decorators, ComponentChanged, OBSERVER_TYPE, resource } from '@combos-fun/engine';\nimport SoundComponent from './Sound';\n\ninterface SoundSystemParams {\n autoPauseAndStart?: boolean;\n onError?: (error: any) => void;\n}\n\n@decorators.componentObserver({\n Sound: [],\n})\nclass SoundSystem extends System {\n static systemName = 'SoundSystem';\n\n private ctx: AudioContext;\n\n private gainNode: GainNode;\n\n /** Whether to pause/resume in sync with the game. */\n private autoPauseAndStart = true;\n\n private onError: (error: any) => void;\n\n private components: SoundComponent[] = [];\n\n private pausedComponents: SoundComponent[] = [];\n\n private audioBufferCache = {};\n\n private decodeAudioPromiseMap = {};\n\n get muted(): boolean {\n return this.gainNode ? this.gainNode.gain.value === 0 : false;\n }\n\n set muted(v: boolean) {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v ? 0 : 1, 0);\n }\n\n get volume(): number {\n return this.gainNode ? this.gainNode.gain.value : 1;\n }\n\n set volume(v: number) {\n if (!this.gainNode || typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v, 0);\n }\n\n get audioLocked(): boolean {\n if (!this.ctx) {\n return true;\n }\n return this.ctx.state !== 'running';\n }\n\n constructor(obj?: SoundSystemParams) {\n super();\n Object.assign(this, obj);\n }\n\n /**\n * Resume playback of all paused audio.\n */\n resumeAll() {\n const handleResume = () => {\n this.pausedComponents.forEach(component => {\n component.play();\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n };\n this.ctx.resume().then(handleResume, handleResume);\n }\n\n /**\n * Pause all currently playing audio.\n */\n pauseAll() {\n this.components.forEach(component => {\n if (component.playing) {\n this.pausedComponents.push(component);\n component.pause();\n }\n });\n this.ctx.suspend().then();\n }\n\n /**\n * Stop all currently playing audio.\n */\n stopAll() {\n this.components.forEach(component => {\n if (component.playing) {\n component.stop();\n }\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n this.ctx.suspend().then();\n }\n\n /**\n * System init: configure params before the game starts.\n */\n init() {\n this.setupAudioContext();\n }\n\n update() {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n /**\n * Called when the game starts or resumes playing after a pause.\n */\n onResume() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.resumeAll();\n }\n\n /**\n * Called when the game is paused.\n */\n onPause() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.pauseAll();\n }\n\n /**\n * Called when the system is destroyed.\n */\n onDestroy() {\n this.components.forEach(component => {\n component.onDestroy();\n });\n this.components = [];\n if (this.ctx) {\n this.gainNode.disconnect();\n this.gainNode = null;\n this.ctx.close();\n this.ctx = null;\n }\n }\n\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Sound') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.add(changed);\n }\n }\n\n private setupAudioContext() {\n try {\n const AudioContext = window.AudioContext || (window as any).webkitAudioContext;\n this.ctx = new AudioContext();\n } catch (error) {\n console.error(error);\n if (this.onError) {\n this.onError(error);\n }\n }\n\n if (!this.ctx) {\n return;\n }\n this.gainNode =\n typeof this.ctx.createGain === 'undefined' ? (this.ctx as any).createGainNode() : this.ctx.createGain();\n this.gainNode.gain.setValueAtTime(this.muted ? 0 : this.volume, this.ctx.currentTime);\n this.gainNode.connect(this.ctx.destination);\n this.unlockAudio();\n }\n\n private unlockAudio() {\n if (!this.ctx || !this.audioLocked) {\n return;\n }\n\n const unlock = () => {\n if (this.ctx) {\n const removeListenerFn = () => {\n document.body.removeEventListener('touchstart', unlock);\n document.body.removeEventListener('touchend', unlock);\n document.body.removeEventListener('click', unlock);\n };\n this.ctx.resume().then(removeListenerFn, removeListenerFn);\n }\n };\n document.body.addEventListener('touchstart', unlock);\n document.body.addEventListener('touchend', unlock);\n document.body.addEventListener('click', unlock);\n }\n\n private async add(changed: ComponentChanged) {\n const component = changed.component as SoundComponent;\n this.components.push(component);\n try {\n const { config } = component;\n component.state = 'loading';\n\n const audio = await resource.getResource(config.resource);\n if (!this.audioBufferCache[audio.name] && audio?.data?.audio) {\n this.audioBufferCache[audio.name] = await this.decodeAudioData(audio.data.audio, audio.name);\n }\n if (this.audioBufferCache[audio.name]) {\n component.systemContext = this.ctx;\n component.systemDestination = this.gainNode;\n component.onload(this.audioBufferCache[audio.name]);\n }\n } catch (error) {\n if (this.onError) {\n this.onError(error);\n }\n }\n }\n\n private decodeAudioData(arraybuffer: ArrayBuffer, name: string) {\n if (this.decodeAudioPromiseMap[name]) {\n return this.decodeAudioPromiseMap[name];\n }\n\n const promise = new Promise<AudioBuffer>((resolve, reject) => {\n if (!this.ctx) {\n reject(new Error('No audio support'));\n }\n\n const success = (decodedData: AudioBuffer) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n if (decodedData) {\n resolve(decodedData);\n } else {\n reject(new Error(`Error decoding audio ${name}`));\n }\n };\n\n const error = (err: DOMException) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n reject(new Error(`${err}. arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n };\n\n const promise = this.ctx.decodeAudioData(arraybuffer, success, error)\n if (promise instanceof Promise) {\n promise.catch((err) => {\n reject(new Error(`catch ${err}, arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n });\n }\n });\n\n this.decodeAudioPromiseMap[name] = promise;\n return promise;\n }\n}\n\nexport default SoundSystem;\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport SoundSystem from './SoundSystem';\n\nObject.assign(SoundSystem, {\n packageName: \"@combos-fun/plugin-sound\",\n packageVersion: \"0.0.28\",\n});\n","import { Component } from '@combos-fun/engine';\n\nexport interface SoundParams {\n resource: string;\n autoplay?: boolean;\n muted?: boolean;\n volume?: number;\n loop?: boolean;\n seek?: number;\n duration?: number;\n onEnd?: () => void;\n}\n\nclass Sound extends Component<SoundParams> {\n static componentName = 'Sound';\n\n systemContext: AudioContext;\n\n systemDestination: GainNode;\n\n playing: boolean;\n\n state: 'unloaded' | 'loading' | 'loaded' = 'unloaded';\n\n config: SoundParams = {\n resource: '',\n autoplay: false,\n muted: false,\n volume: 1,\n loop: false,\n seek: 0,\n };\n\n private buffer: AudioBuffer;\n\n private sourceNode: AudioBufferSourceNode;\n\n private gainNode: GainNode;\n\n private paused: boolean;\n\n private playTime: number = 0;\n\n private startTime: number = 0;\n\n private duration: number = 0;\n\n private actionQueue: (() => void)[] = [];\n\n private endedListener: () => void;\n\n get muted(): boolean {\n return this.gainNode ? this.gainNode.gain.value === 0 : false;\n }\n\n set muted(v: boolean) {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v ? 0 : this.config.volume, 0);\n }\n\n get volume(): number {\n return this.gainNode ? this.gainNode.gain.value : 1;\n }\n\n set volume(v: number) {\n if (typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this.config.volume = v;\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v, 0);\n }\n\n init(obj?: SoundParams) {\n if (!obj) {\n return;\n }\n\n Object.assign(this.config, obj);\n if (this.config.autoplay) {\n this.actionQueue.push(this.play.bind(this));\n }\n }\n\n play() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.play.bind(this));\n }\n this.destroySource();\n this.createSource();\n\n if (!this.sourceNode) {\n return;\n }\n const when = this.systemContext.currentTime;\n const offset = this.config.seek;\n const duration = this.config.duration;\n\n this.sourceNode.start(0, offset, duration);\n\n this.startTime = when;\n this.playTime = when - offset;\n this.paused = false;\n this.playing = true;\n this.resetConfig();\n this.endedListener = () => {\n if (!this.sourceNode) {\n return;\n }\n if (this.config.onEnd) {\n this.config.onEnd();\n }\n // Release resources once non-interactive playback finishes.\n if (this.playing) {\n this.destroySource();\n }\n };\n this.sourceNode.addEventListener('ended', this.endedListener);\n }\n\n pause() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.pause.bind(this));\n }\n if (this.paused || !this.playing) {\n return;\n }\n this.paused = true;\n this.playing = false;\n this.config.seek = this.getCurrentTime();\n this.destroySource();\n }\n\n stop() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.stop.bind(this));\n }\n if (!this.paused && !this.playing) {\n return;\n }\n this.playing = false;\n this.paused = false;\n this.destroySource();\n this.resetConfig();\n }\n\n onload(buffer: AudioBuffer) {\n this.state = 'loaded';\n this.buffer = buffer;\n this.duration = this.buffer.duration;\n this.actionQueue.forEach(action => action());\n this.actionQueue.length = 0;\n }\n\n onDestroy() {\n this.actionQueue.length = 0;\n this.destroySource();\n }\n\n private resetConfig() {\n this.config.seek = 0;\n }\n\n private getCurrentTime() {\n if (this.config.loop && this.duration > 0) {\n return (this.systemContext.currentTime - this.playTime) % this.duration;\n }\n\n return this.systemContext.currentTime - this.playTime;\n }\n\n private createSource() {\n if (!this.systemContext || this.state !== 'loaded') {\n return;\n }\n this.sourceNode = this.systemContext.createBufferSource();\n this.sourceNode.buffer = this.buffer;\n this.sourceNode.loop = this.config.loop;\n\n if (!this.gainNode) {\n this.gainNode = this.systemContext.createGain();\n this.gainNode.connect(this.systemDestination);\n Object.assign(this, this.config);\n }\n this.sourceNode.connect(this.gainNode);\n }\n\n private destroySource() {\n if (!this.sourceNode) return;\n this.sourceNode.removeEventListener('ended', this.endedListener);\n this.sourceNode.stop();\n this.sourceNode.disconnect();\n this.sourceNode = null;\n\n this.startTime = 0;\n this.playTime = 0;\n this.playing = false;\n }\n}\n\nexport default Sound;\n"],"names":["SoundSystem","System","OBSERVER_TYPE","resource","__decorate","decorators","Component"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-sound.cjs.js","sources":["../lib/SoundSystem.ts","../lib/__combosPackageMeta.gen.ts","../lib/Sound.ts"],"sourcesContent":["import { System, decorators, ComponentChanged, OBSERVER_TYPE, resource } from '@combos-fun/engine';\nimport SoundComponent from './Sound';\n\ninterface SoundSystemParams {\n autoPauseAndStart?: boolean;\n onError?: (error: any) => void;\n}\n\n@decorators.componentObserver({\n Sound: [],\n})\nclass SoundSystem extends System {\n static systemName = 'SoundSystem';\n\n private ctx: AudioContext;\n\n private gainNode: GainNode;\n\n /** Whether to pause/resume in sync with the game. */\n private autoPauseAndStart = true;\n\n private onError: (error: any) => void;\n\n private components: SoundComponent[] = [];\n\n private pausedComponents: SoundComponent[] = [];\n\n private audioBufferCache = {};\n\n private decodeAudioPromiseMap = {};\n\n /** Desired mute/volume are the source of truth; the gain node is derived. */\n private _muted = false;\n\n private _volume = 1;\n\n get muted(): boolean {\n return this._muted;\n }\n\n set muted(v: boolean) {\n this._muted = v;\n this.applyGain();\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set volume(v: number) {\n if (typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this._volume = v;\n this.applyGain();\n }\n\n /**\n * Apply the effective gain (`muted ? 0 : volume`) to the gain node.\n *\n * Assigns `gain.value` directly rather than `setValueAtTime`: `.value` updates\n * the AudioParam's intrinsic value synchronously, so the `muted` / `volume`\n * getters reflect the change immediately. `setValueAtTime` only schedules an\n * event on the automation timeline and leaves `.value` stale until the next\n * render quantum, which made `muted` report the pre-change value.\n */\n private applyGain() {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.value = this._muted ? 0 : this._volume;\n }\n\n get audioLocked(): boolean {\n if (!this.ctx) {\n return true;\n }\n return this.ctx.state !== 'running';\n }\n\n constructor(obj?: SoundSystemParams) {\n super();\n Object.assign(this, obj);\n }\n\n /**\n * Resume playback of all paused audio.\n */\n resumeAll() {\n const handleResume = () => {\n this.pausedComponents.forEach(component => {\n component.play();\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n };\n this.ctx.resume().then(handleResume, handleResume);\n }\n\n /**\n * Pause all currently playing audio.\n */\n pauseAll() {\n this.components.forEach(component => {\n if (component.playing) {\n this.pausedComponents.push(component);\n component.pause();\n }\n });\n this.ctx.suspend().then();\n }\n\n /**\n * Stop all currently playing audio.\n */\n stopAll() {\n this.components.forEach(component => {\n if (component.playing) {\n component.stop();\n }\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n this.ctx.suspend().then();\n }\n\n /**\n * System init: configure params before the game starts.\n */\n init() {\n this.setupAudioContext();\n }\n\n update() {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n /**\n * Called when the game starts or resumes playing after a pause.\n */\n onResume() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.resumeAll();\n }\n\n /**\n * Called when the game is paused.\n */\n onPause() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.pauseAll();\n }\n\n /**\n * Called when the system is destroyed.\n */\n onDestroy() {\n this.components.forEach(component => {\n component.onDestroy();\n });\n this.components = [];\n if (this.ctx) {\n this.gainNode.disconnect();\n this.gainNode = null;\n this.ctx.close();\n this.ctx = null;\n }\n }\n\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Sound') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.add(changed);\n }\n }\n\n private setupAudioContext() {\n try {\n const AudioContext = window.AudioContext || (window as any).webkitAudioContext;\n this.ctx = new AudioContext();\n } catch (error) {\n console.error(error);\n if (this.onError) {\n this.onError(error);\n }\n }\n\n if (!this.ctx) {\n return;\n }\n this.gainNode =\n typeof this.ctx.createGain === 'undefined' ? (this.ctx as any).createGainNode() : this.ctx.createGain();\n this.applyGain();\n this.gainNode.connect(this.ctx.destination);\n this.unlockAudio();\n }\n\n private unlockAudio() {\n if (!this.ctx || !this.audioLocked) {\n return;\n }\n\n const unlock = () => {\n if (this.ctx) {\n const removeListenerFn = () => {\n document.body.removeEventListener('touchstart', unlock);\n document.body.removeEventListener('touchend', unlock);\n document.body.removeEventListener('click', unlock);\n };\n this.ctx.resume().then(removeListenerFn, removeListenerFn);\n }\n };\n document.body.addEventListener('touchstart', unlock);\n document.body.addEventListener('touchend', unlock);\n document.body.addEventListener('click', unlock);\n }\n\n private async add(changed: ComponentChanged) {\n const component = changed.component as SoundComponent;\n this.components.push(component);\n try {\n const { config } = component;\n component.state = 'loading';\n\n const audio = await resource.getResource(config.resource);\n if (!this.audioBufferCache[audio.name] && audio?.data?.audio) {\n this.audioBufferCache[audio.name] = await this.decodeAudioData(audio.data.audio, audio.name);\n }\n if (this.audioBufferCache[audio.name]) {\n component.systemContext = this.ctx;\n component.systemDestination = this.gainNode;\n component.onload(this.audioBufferCache[audio.name]);\n }\n } catch (error) {\n if (this.onError) {\n this.onError(error);\n }\n }\n }\n\n private decodeAudioData(arraybuffer: ArrayBuffer, name: string) {\n if (this.decodeAudioPromiseMap[name]) {\n return this.decodeAudioPromiseMap[name];\n }\n\n const promise = new Promise<AudioBuffer>((resolve, reject) => {\n if (!this.ctx) {\n reject(new Error('No audio support'));\n }\n\n const success = (decodedData: AudioBuffer) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n if (decodedData) {\n resolve(decodedData);\n } else {\n reject(new Error(`Error decoding audio ${name}`));\n }\n };\n\n const error = (err: DOMException) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n reject(new Error(`${err}. arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n };\n\n const promise = this.ctx.decodeAudioData(arraybuffer, success, error)\n if (promise instanceof Promise) {\n promise.catch((err) => {\n reject(new Error(`catch ${err}, arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n });\n }\n });\n\n this.decodeAudioPromiseMap[name] = promise;\n return promise;\n }\n}\n\nexport default SoundSystem;\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport SoundSystem from './SoundSystem';\n\nObject.assign(SoundSystem, {\n packageName: \"@combos-fun/plugin-sound\",\n packageVersion: \"0.0.31\",\n});\n","import { Component } from '@combos-fun/engine';\n\nexport interface SoundParams {\n resource: string;\n autoplay?: boolean;\n muted?: boolean;\n volume?: number;\n loop?: boolean;\n seek?: number;\n duration?: number;\n onEnd?: () => void;\n}\n\nclass Sound extends Component<SoundParams> {\n static componentName = 'Sound';\n\n systemContext: AudioContext;\n\n systemDestination: GainNode;\n\n playing: boolean;\n\n state: 'unloaded' | 'loading' | 'loaded' = 'unloaded';\n\n config: SoundParams = {\n resource: '',\n autoplay: false,\n muted: false,\n volume: 1,\n loop: false,\n seek: 0,\n };\n\n private buffer: AudioBuffer;\n\n private sourceNode: AudioBufferSourceNode;\n\n private gainNode: GainNode;\n\n private paused: boolean;\n\n private playTime: number = 0;\n\n private startTime: number = 0;\n\n private duration: number = 0;\n\n private actionQueue: (() => void)[] = [];\n\n private endedListener: () => void;\n\n get muted(): boolean {\n return this.gainNode ? this.gainNode.gain.value === 0 : false;\n }\n\n set muted(v: boolean) {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v ? 0 : this.config.volume, 0);\n }\n\n get volume(): number {\n return this.gainNode ? this.gainNode.gain.value : 1;\n }\n\n set volume(v: number) {\n if (typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this.config.volume = v;\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v, 0);\n }\n\n init(obj?: SoundParams) {\n if (!obj) {\n return;\n }\n\n Object.assign(this.config, obj);\n if (this.config.autoplay) {\n this.actionQueue.push(this.play.bind(this));\n }\n }\n\n play() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.play.bind(this));\n }\n this.destroySource();\n this.createSource();\n\n if (!this.sourceNode) {\n return;\n }\n const when = this.systemContext.currentTime;\n const offset = this.config.seek;\n const duration = this.config.duration;\n\n this.sourceNode.start(0, offset, duration);\n\n this.startTime = when;\n this.playTime = when - offset;\n this.paused = false;\n this.playing = true;\n this.resetConfig();\n this.endedListener = () => {\n if (!this.sourceNode) {\n return;\n }\n if (this.config.onEnd) {\n this.config.onEnd();\n }\n // Release resources once non-interactive playback finishes.\n if (this.playing) {\n this.destroySource();\n }\n };\n this.sourceNode.addEventListener('ended', this.endedListener);\n }\n\n pause() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.pause.bind(this));\n }\n if (this.paused || !this.playing) {\n return;\n }\n this.paused = true;\n this.playing = false;\n this.config.seek = this.getCurrentTime();\n this.destroySource();\n }\n\n stop() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.stop.bind(this));\n }\n if (!this.paused && !this.playing) {\n return;\n }\n this.playing = false;\n this.paused = false;\n this.destroySource();\n this.resetConfig();\n }\n\n onload(buffer: AudioBuffer) {\n this.state = 'loaded';\n this.buffer = buffer;\n this.duration = this.buffer.duration;\n this.actionQueue.forEach(action => action());\n this.actionQueue.length = 0;\n }\n\n onDestroy() {\n this.actionQueue.length = 0;\n this.destroySource();\n }\n\n private resetConfig() {\n this.config.seek = 0;\n }\n\n private getCurrentTime() {\n if (this.config.loop && this.duration > 0) {\n return (this.systemContext.currentTime - this.playTime) % this.duration;\n }\n\n return this.systemContext.currentTime - this.playTime;\n }\n\n private createSource() {\n if (!this.systemContext || this.state !== 'loaded') {\n return;\n }\n this.sourceNode = this.systemContext.createBufferSource();\n this.sourceNode.buffer = this.buffer;\n this.sourceNode.loop = this.config.loop;\n\n if (!this.gainNode) {\n this.gainNode = this.systemContext.createGain();\n this.gainNode.connect(this.systemDestination);\n Object.assign(this, this.config);\n }\n this.sourceNode.connect(this.gainNode);\n }\n\n private destroySource() {\n if (!this.sourceNode) return;\n this.sourceNode.removeEventListener('ended', this.endedListener);\n this.sourceNode.stop();\n this.sourceNode.disconnect();\n this.sourceNode = null;\n\n this.startTime = 0;\n this.playTime = 0;\n this.playing = false;\n }\n}\n\nexport default Sound;\n"],"names":["SoundSystem","System","OBSERVER_TYPE","resource","__decorate","decorators","Component"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("tslib"),e=require("@combos-fun/engine");let s=class extends e.System{static{this.systemName="SoundSystem"}get muted(){return
|
|
1
|
+
"use strict";var t=require("tslib"),e=require("@combos-fun/engine");let s=class extends e.System{static{this.systemName="SoundSystem"}get muted(){return this._muted}set muted(t){this._muted=t,this.applyGain()}get volume(){return this._volume}set volume(t){"number"!=typeof t||t<0||t>1||(this._volume=t,this.applyGain())}applyGain(){this.gainNode&&(this.gainNode.gain.value=this._muted?0:this._volume)}get audioLocked(){return!this.ctx||"running"!==this.ctx.state}constructor(t){super(),this.autoPauseAndStart=!0,this.components=[],this.pausedComponents=[],this.audioBufferCache={},this.decodeAudioPromiseMap={},this._muted=!1,this._volume=1,Object.assign(this,t)}resumeAll(){const t=()=>{this.pausedComponents.forEach(t=>{t.play()}),this.pausedComponents=[]};this.ctx.resume().then(t,t)}pauseAll(){this.components.forEach(t=>{t.playing&&(this.pausedComponents.push(t),t.pause())}),this.ctx.suspend().then()}stopAll(){this.components.forEach(t=>{t.playing&&t.stop()}),this.pausedComponents=[],this.ctx.suspend().then()}init(){this.setupAudioContext()}update(){const t=this.componentObserver.clear();for(const e of t)this.componentChanged(e)}onResume(){this.autoPauseAndStart&&this.resumeAll()}onPause(){this.autoPauseAndStart&&this.pauseAll()}onDestroy(){this.components.forEach(t=>{t.onDestroy()}),this.components=[],this.ctx&&(this.gainNode.disconnect(),this.gainNode=null,this.ctx.close(),this.ctx=null)}async componentChanged(t){"Sound"===t.componentName&&t.type===e.OBSERVER_TYPE.ADD&&this.add(t)}setupAudioContext(){try{const t=window.AudioContext||window.webkitAudioContext;this.ctx=new t}catch(t){console.error(t),this.onError&&this.onError(t)}this.ctx&&(this.gainNode=void 0===this.ctx.createGain?this.ctx.createGainNode():this.ctx.createGain(),this.applyGain(),this.gainNode.connect(this.ctx.destination),this.unlockAudio())}unlockAudio(){if(!this.ctx||!this.audioLocked)return;const t=()=>{if(this.ctx){const e=()=>{document.body.removeEventListener("touchstart",t),document.body.removeEventListener("touchend",t),document.body.removeEventListener("click",t)};this.ctx.resume().then(e,e)}};document.body.addEventListener("touchstart",t),document.body.addEventListener("touchend",t),document.body.addEventListener("click",t)}async add(t){const s=t.component;this.components.push(s);try{const{config:t}=s;s.state="loading";const i=await e.resource.getResource(t.resource);!this.audioBufferCache[i.name]&&i?.data?.audio&&(this.audioBufferCache[i.name]=await this.decodeAudioData(i.data.audio,i.name)),this.audioBufferCache[i.name]&&(s.systemContext=this.ctx,s.systemDestination=this.gainNode,s.onload(this.audioBufferCache[i.name]))}catch(t){this.onError&&this.onError(t)}}decodeAudioData(t,e){if(this.decodeAudioPromiseMap[e])return this.decodeAudioPromiseMap[e];const s=new Promise((s,i)=>{this.ctx||i(new Error("No audio support"));const o=this.ctx.decodeAudioData(t,t=>{this.decodeAudioPromiseMap[e]&&delete this.decodeAudioPromiseMap[e],t?s(t):i(new Error(`Error decoding audio ${e}`))},s=>{this.decodeAudioPromiseMap[e]&&delete this.decodeAudioPromiseMap[e],i(new Error(`${s}. arrayBuffer byteLength: ${t?t.byteLength:0}`))});o instanceof Promise&&o.catch(e=>{i(new Error(`catch ${e}, arrayBuffer byteLength: ${t?t.byteLength:0}`))})});return this.decodeAudioPromiseMap[e]=s,s}};s=t.__decorate([e.decorators.componentObserver({Sound:[]})],s);var i=s;Object.assign(i,{packageName:"@combos-fun/plugin-sound",packageVersion:"0.0.31"});class o extends e.Component{constructor(){super(...arguments),this.state="unloaded",this.config={resource:"",autoplay:!1,muted:!1,volume:1,loop:!1,seek:0},this.playTime=0,this.startTime=0,this.duration=0,this.actionQueue=[]}static{this.componentName="Sound"}get muted(){return!!this.gainNode&&0===this.gainNode.gain.value}set muted(t){this.gainNode&&this.gainNode.gain.setValueAtTime(t?0:this.config.volume,0)}get volume(){return this.gainNode?this.gainNode.gain.value:1}set volume(t){"number"!=typeof t||t<0||t>1||(this.config.volume=t,this.gainNode&&this.gainNode.gain.setValueAtTime(t,0))}init(t){t&&(Object.assign(this.config,t),this.config.autoplay&&this.actionQueue.push(this.play.bind(this)))}play(){if("loaded"!==this.state&&this.actionQueue.push(this.play.bind(this)),this.destroySource(),this.createSource(),!this.sourceNode)return;const t=this.systemContext.currentTime,e=this.config.seek,s=this.config.duration;this.sourceNode.start(0,e,s),this.startTime=t,this.playTime=t-e,this.paused=!1,this.playing=!0,this.resetConfig(),this.endedListener=()=>{this.sourceNode&&(this.config.onEnd&&this.config.onEnd(),this.playing&&this.destroySource())},this.sourceNode.addEventListener("ended",this.endedListener)}pause(){"loaded"!==this.state&&this.actionQueue.push(this.pause.bind(this)),!this.paused&&this.playing&&(this.paused=!0,this.playing=!1,this.config.seek=this.getCurrentTime(),this.destroySource())}stop(){"loaded"!==this.state&&this.actionQueue.push(this.stop.bind(this)),(this.paused||this.playing)&&(this.playing=!1,this.paused=!1,this.destroySource(),this.resetConfig())}onload(t){this.state="loaded",this.buffer=t,this.duration=this.buffer.duration,this.actionQueue.forEach(t=>t()),this.actionQueue.length=0}onDestroy(){this.actionQueue.length=0,this.destroySource()}resetConfig(){this.config.seek=0}getCurrentTime(){return this.config.loop&&this.duration>0?(this.systemContext.currentTime-this.playTime)%this.duration:this.systemContext.currentTime-this.playTime}createSource(){this.systemContext&&"loaded"===this.state&&(this.sourceNode=this.systemContext.createBufferSource(),this.sourceNode.buffer=this.buffer,this.sourceNode.loop=this.config.loop,this.gainNode||(this.gainNode=this.systemContext.createGain(),this.gainNode.connect(this.systemDestination),Object.assign(this,this.config)),this.sourceNode.connect(this.gainNode))}destroySource(){this.sourceNode&&(this.sourceNode.removeEventListener("ended",this.endedListener),this.sourceNode.stop(),this.sourceNode.disconnect(),this.sourceNode=null,this.startTime=0,this.playTime=0,this.playing=!1)}}exports.Sound=o,exports.SoundSystem=i;
|
package/dist/plugin-sound.d.ts
CHANGED
|
@@ -15,10 +15,23 @@ declare class SoundSystem extends System {
|
|
|
15
15
|
private pausedComponents;
|
|
16
16
|
private audioBufferCache;
|
|
17
17
|
private decodeAudioPromiseMap;
|
|
18
|
+
/** Desired mute/volume are the source of truth; the gain node is derived. */
|
|
19
|
+
private _muted;
|
|
20
|
+
private _volume;
|
|
18
21
|
get muted(): boolean;
|
|
19
22
|
set muted(v: boolean);
|
|
20
23
|
get volume(): number;
|
|
21
24
|
set volume(v: number);
|
|
25
|
+
/**
|
|
26
|
+
* Apply the effective gain (`muted ? 0 : volume`) to the gain node.
|
|
27
|
+
*
|
|
28
|
+
* Assigns `gain.value` directly rather than `setValueAtTime`: `.value` updates
|
|
29
|
+
* the AudioParam's intrinsic value synchronously, so the `muted` / `volume`
|
|
30
|
+
* getters reflect the change immediately. `setValueAtTime` only schedules an
|
|
31
|
+
* event on the automation timeline and leaves `.value` stale until the next
|
|
32
|
+
* render quantum, which made `muted` report the pre-change value.
|
|
33
|
+
*/
|
|
34
|
+
private applyGain;
|
|
22
35
|
get audioLocked(): boolean;
|
|
23
36
|
constructor(obj?: SoundSystemParams);
|
|
24
37
|
/**
|
package/dist/plugin-sound.esm.js
CHANGED
|
@@ -4,22 +4,36 @@ import { System, OBSERVER_TYPE, resource, decorators, Component } from '@combos-
|
|
|
4
4
|
let SoundSystem = class SoundSystem extends System {
|
|
5
5
|
static { this.systemName = 'SoundSystem'; }
|
|
6
6
|
get muted() {
|
|
7
|
-
return this.
|
|
7
|
+
return this._muted;
|
|
8
8
|
}
|
|
9
9
|
set muted(v) {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
this.gainNode.gain.setValueAtTime(v ? 0 : 1, 0);
|
|
10
|
+
this._muted = v;
|
|
11
|
+
this.applyGain();
|
|
14
12
|
}
|
|
15
13
|
get volume() {
|
|
16
|
-
return this.
|
|
14
|
+
return this._volume;
|
|
17
15
|
}
|
|
18
16
|
set volume(v) {
|
|
19
|
-
if (
|
|
17
|
+
if (typeof v !== 'number' || v < 0 || v > 1) {
|
|
20
18
|
return;
|
|
21
19
|
}
|
|
22
|
-
this.
|
|
20
|
+
this._volume = v;
|
|
21
|
+
this.applyGain();
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Apply the effective gain (`muted ? 0 : volume`) to the gain node.
|
|
25
|
+
*
|
|
26
|
+
* Assigns `gain.value` directly rather than `setValueAtTime`: `.value` updates
|
|
27
|
+
* the AudioParam's intrinsic value synchronously, so the `muted` / `volume`
|
|
28
|
+
* getters reflect the change immediately. `setValueAtTime` only schedules an
|
|
29
|
+
* event on the automation timeline and leaves `.value` stale until the next
|
|
30
|
+
* render quantum, which made `muted` report the pre-change value.
|
|
31
|
+
*/
|
|
32
|
+
applyGain() {
|
|
33
|
+
if (!this.gainNode) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this.gainNode.gain.value = this._muted ? 0 : this._volume;
|
|
23
37
|
}
|
|
24
38
|
get audioLocked() {
|
|
25
39
|
if (!this.ctx) {
|
|
@@ -35,6 +49,9 @@ let SoundSystem = class SoundSystem extends System {
|
|
|
35
49
|
this.pausedComponents = [];
|
|
36
50
|
this.audioBufferCache = {};
|
|
37
51
|
this.decodeAudioPromiseMap = {};
|
|
52
|
+
/** Desired mute/volume are the source of truth; the gain node is derived. */
|
|
53
|
+
this._muted = false;
|
|
54
|
+
this._volume = 1;
|
|
38
55
|
Object.assign(this, obj);
|
|
39
56
|
}
|
|
40
57
|
/**
|
|
@@ -143,7 +160,7 @@ let SoundSystem = class SoundSystem extends System {
|
|
|
143
160
|
}
|
|
144
161
|
this.gainNode =
|
|
145
162
|
typeof this.ctx.createGain === 'undefined' ? this.ctx.createGainNode() : this.ctx.createGain();
|
|
146
|
-
this.
|
|
163
|
+
this.applyGain();
|
|
147
164
|
this.gainNode.connect(this.ctx.destination);
|
|
148
165
|
this.unlockAudio();
|
|
149
166
|
}
|
|
@@ -233,7 +250,7 @@ var SoundSystem$1 = SoundSystem;
|
|
|
233
250
|
/** Auto-generated by scripts/build-package.mjs — do not edit. */
|
|
234
251
|
Object.assign(SoundSystem$1, {
|
|
235
252
|
packageName: "@combos-fun/plugin-sound",
|
|
236
|
-
packageVersion: "0.0.
|
|
253
|
+
packageVersion: "0.0.31",
|
|
237
254
|
});
|
|
238
255
|
|
|
239
256
|
class Sound extends Component {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin-sound.esm.js","sources":["../lib/SoundSystem.ts","../lib/__combosPackageMeta.gen.ts","../lib/Sound.ts"],"sourcesContent":["import { System, decorators, ComponentChanged, OBSERVER_TYPE, resource } from '@combos-fun/engine';\nimport SoundComponent from './Sound';\n\ninterface SoundSystemParams {\n autoPauseAndStart?: boolean;\n onError?: (error: any) => void;\n}\n\n@decorators.componentObserver({\n Sound: [],\n})\nclass SoundSystem extends System {\n static systemName = 'SoundSystem';\n\n private ctx: AudioContext;\n\n private gainNode: GainNode;\n\n /** Whether to pause/resume in sync with the game. */\n private autoPauseAndStart = true;\n\n private onError: (error: any) => void;\n\n private components: SoundComponent[] = [];\n\n private pausedComponents: SoundComponent[] = [];\n\n private audioBufferCache = {};\n\n private decodeAudioPromiseMap = {};\n\n get muted(): boolean {\n return this.gainNode ? this.gainNode.gain.value === 0 : false;\n }\n\n set muted(v: boolean) {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v ? 0 : 1, 0);\n }\n\n get volume(): number {\n return this.gainNode ? this.gainNode.gain.value : 1;\n }\n\n set volume(v: number) {\n if (!this.gainNode || typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v, 0);\n }\n\n get audioLocked(): boolean {\n if (!this.ctx) {\n return true;\n }\n return this.ctx.state !== 'running';\n }\n\n constructor(obj?: SoundSystemParams) {\n super();\n Object.assign(this, obj);\n }\n\n /**\n * Resume playback of all paused audio.\n */\n resumeAll() {\n const handleResume = () => {\n this.pausedComponents.forEach(component => {\n component.play();\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n };\n this.ctx.resume().then(handleResume, handleResume);\n }\n\n /**\n * Pause all currently playing audio.\n */\n pauseAll() {\n this.components.forEach(component => {\n if (component.playing) {\n this.pausedComponents.push(component);\n component.pause();\n }\n });\n this.ctx.suspend().then();\n }\n\n /**\n * Stop all currently playing audio.\n */\n stopAll() {\n this.components.forEach(component => {\n if (component.playing) {\n component.stop();\n }\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n this.ctx.suspend().then();\n }\n\n /**\n * System init: configure params before the game starts.\n */\n init() {\n this.setupAudioContext();\n }\n\n update() {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n /**\n * Called when the game starts or resumes playing after a pause.\n */\n onResume() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.resumeAll();\n }\n\n /**\n * Called when the game is paused.\n */\n onPause() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.pauseAll();\n }\n\n /**\n * Called when the system is destroyed.\n */\n onDestroy() {\n this.components.forEach(component => {\n component.onDestroy();\n });\n this.components = [];\n if (this.ctx) {\n this.gainNode.disconnect();\n this.gainNode = null;\n this.ctx.close();\n this.ctx = null;\n }\n }\n\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Sound') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.add(changed);\n }\n }\n\n private setupAudioContext() {\n try {\n const AudioContext = window.AudioContext || (window as any).webkitAudioContext;\n this.ctx = new AudioContext();\n } catch (error) {\n console.error(error);\n if (this.onError) {\n this.onError(error);\n }\n }\n\n if (!this.ctx) {\n return;\n }\n this.gainNode =\n typeof this.ctx.createGain === 'undefined' ? (this.ctx as any).createGainNode() : this.ctx.createGain();\n this.gainNode.gain.setValueAtTime(this.muted ? 0 : this.volume, this.ctx.currentTime);\n this.gainNode.connect(this.ctx.destination);\n this.unlockAudio();\n }\n\n private unlockAudio() {\n if (!this.ctx || !this.audioLocked) {\n return;\n }\n\n const unlock = () => {\n if (this.ctx) {\n const removeListenerFn = () => {\n document.body.removeEventListener('touchstart', unlock);\n document.body.removeEventListener('touchend', unlock);\n document.body.removeEventListener('click', unlock);\n };\n this.ctx.resume().then(removeListenerFn, removeListenerFn);\n }\n };\n document.body.addEventListener('touchstart', unlock);\n document.body.addEventListener('touchend', unlock);\n document.body.addEventListener('click', unlock);\n }\n\n private async add(changed: ComponentChanged) {\n const component = changed.component as SoundComponent;\n this.components.push(component);\n try {\n const { config } = component;\n component.state = 'loading';\n\n const audio = await resource.getResource(config.resource);\n if (!this.audioBufferCache[audio.name] && audio?.data?.audio) {\n this.audioBufferCache[audio.name] = await this.decodeAudioData(audio.data.audio, audio.name);\n }\n if (this.audioBufferCache[audio.name]) {\n component.systemContext = this.ctx;\n component.systemDestination = this.gainNode;\n component.onload(this.audioBufferCache[audio.name]);\n }\n } catch (error) {\n if (this.onError) {\n this.onError(error);\n }\n }\n }\n\n private decodeAudioData(arraybuffer: ArrayBuffer, name: string) {\n if (this.decodeAudioPromiseMap[name]) {\n return this.decodeAudioPromiseMap[name];\n }\n\n const promise = new Promise<AudioBuffer>((resolve, reject) => {\n if (!this.ctx) {\n reject(new Error('No audio support'));\n }\n\n const success = (decodedData: AudioBuffer) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n if (decodedData) {\n resolve(decodedData);\n } else {\n reject(new Error(`Error decoding audio ${name}`));\n }\n };\n\n const error = (err: DOMException) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n reject(new Error(`${err}. arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n };\n\n const promise = this.ctx.decodeAudioData(arraybuffer, success, error)\n if (promise instanceof Promise) {\n promise.catch((err) => {\n reject(new Error(`catch ${err}, arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n });\n }\n });\n\n this.decodeAudioPromiseMap[name] = promise;\n return promise;\n }\n}\n\nexport default SoundSystem;\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport SoundSystem from './SoundSystem';\n\nObject.assign(SoundSystem, {\n packageName: \"@combos-fun/plugin-sound\",\n packageVersion: \"0.0.28\",\n});\n","import { Component } from '@combos-fun/engine';\n\nexport interface SoundParams {\n resource: string;\n autoplay?: boolean;\n muted?: boolean;\n volume?: number;\n loop?: boolean;\n seek?: number;\n duration?: number;\n onEnd?: () => void;\n}\n\nclass Sound extends Component<SoundParams> {\n static componentName = 'Sound';\n\n systemContext: AudioContext;\n\n systemDestination: GainNode;\n\n playing: boolean;\n\n state: 'unloaded' | 'loading' | 'loaded' = 'unloaded';\n\n config: SoundParams = {\n resource: '',\n autoplay: false,\n muted: false,\n volume: 1,\n loop: false,\n seek: 0,\n };\n\n private buffer: AudioBuffer;\n\n private sourceNode: AudioBufferSourceNode;\n\n private gainNode: GainNode;\n\n private paused: boolean;\n\n private playTime: number = 0;\n\n private startTime: number = 0;\n\n private duration: number = 0;\n\n private actionQueue: (() => void)[] = [];\n\n private endedListener: () => void;\n\n get muted(): boolean {\n return this.gainNode ? this.gainNode.gain.value === 0 : false;\n }\n\n set muted(v: boolean) {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v ? 0 : this.config.volume, 0);\n }\n\n get volume(): number {\n return this.gainNode ? this.gainNode.gain.value : 1;\n }\n\n set volume(v: number) {\n if (typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this.config.volume = v;\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v, 0);\n }\n\n init(obj?: SoundParams) {\n if (!obj) {\n return;\n }\n\n Object.assign(this.config, obj);\n if (this.config.autoplay) {\n this.actionQueue.push(this.play.bind(this));\n }\n }\n\n play() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.play.bind(this));\n }\n this.destroySource();\n this.createSource();\n\n if (!this.sourceNode) {\n return;\n }\n const when = this.systemContext.currentTime;\n const offset = this.config.seek;\n const duration = this.config.duration;\n\n this.sourceNode.start(0, offset, duration);\n\n this.startTime = when;\n this.playTime = when - offset;\n this.paused = false;\n this.playing = true;\n this.resetConfig();\n this.endedListener = () => {\n if (!this.sourceNode) {\n return;\n }\n if (this.config.onEnd) {\n this.config.onEnd();\n }\n // Release resources once non-interactive playback finishes.\n if (this.playing) {\n this.destroySource();\n }\n };\n this.sourceNode.addEventListener('ended', this.endedListener);\n }\n\n pause() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.pause.bind(this));\n }\n if (this.paused || !this.playing) {\n return;\n }\n this.paused = true;\n this.playing = false;\n this.config.seek = this.getCurrentTime();\n this.destroySource();\n }\n\n stop() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.stop.bind(this));\n }\n if (!this.paused && !this.playing) {\n return;\n }\n this.playing = false;\n this.paused = false;\n this.destroySource();\n this.resetConfig();\n }\n\n onload(buffer: AudioBuffer) {\n this.state = 'loaded';\n this.buffer = buffer;\n this.duration = this.buffer.duration;\n this.actionQueue.forEach(action => action());\n this.actionQueue.length = 0;\n }\n\n onDestroy() {\n this.actionQueue.length = 0;\n this.destroySource();\n }\n\n private resetConfig() {\n this.config.seek = 0;\n }\n\n private getCurrentTime() {\n if (this.config.loop && this.duration > 0) {\n return (this.systemContext.currentTime - this.playTime) % this.duration;\n }\n\n return this.systemContext.currentTime - this.playTime;\n }\n\n private createSource() {\n if (!this.systemContext || this.state !== 'loaded') {\n return;\n }\n this.sourceNode = this.systemContext.createBufferSource();\n this.sourceNode.buffer = this.buffer;\n this.sourceNode.loop = this.config.loop;\n\n if (!this.gainNode) {\n this.gainNode = this.systemContext.createGain();\n this.gainNode.connect(this.systemDestination);\n Object.assign(this, this.config);\n }\n this.sourceNode.connect(this.gainNode);\n }\n\n private destroySource() {\n if (!this.sourceNode) return;\n this.sourceNode.removeEventListener('ended', this.endedListener);\n this.sourceNode.stop();\n this.sourceNode.disconnect();\n this.sourceNode = null;\n\n this.startTime = 0;\n this.playTime = 0;\n this.playing = false;\n }\n}\n\nexport default Sound;\n"],"names":["SoundSystem"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"plugin-sound.esm.js","sources":["../lib/SoundSystem.ts","../lib/__combosPackageMeta.gen.ts","../lib/Sound.ts"],"sourcesContent":["import { System, decorators, ComponentChanged, OBSERVER_TYPE, resource } from '@combos-fun/engine';\nimport SoundComponent from './Sound';\n\ninterface SoundSystemParams {\n autoPauseAndStart?: boolean;\n onError?: (error: any) => void;\n}\n\n@decorators.componentObserver({\n Sound: [],\n})\nclass SoundSystem extends System {\n static systemName = 'SoundSystem';\n\n private ctx: AudioContext;\n\n private gainNode: GainNode;\n\n /** Whether to pause/resume in sync with the game. */\n private autoPauseAndStart = true;\n\n private onError: (error: any) => void;\n\n private components: SoundComponent[] = [];\n\n private pausedComponents: SoundComponent[] = [];\n\n private audioBufferCache = {};\n\n private decodeAudioPromiseMap = {};\n\n /** Desired mute/volume are the source of truth; the gain node is derived. */\n private _muted = false;\n\n private _volume = 1;\n\n get muted(): boolean {\n return this._muted;\n }\n\n set muted(v: boolean) {\n this._muted = v;\n this.applyGain();\n }\n\n get volume(): number {\n return this._volume;\n }\n\n set volume(v: number) {\n if (typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this._volume = v;\n this.applyGain();\n }\n\n /**\n * Apply the effective gain (`muted ? 0 : volume`) to the gain node.\n *\n * Assigns `gain.value` directly rather than `setValueAtTime`: `.value` updates\n * the AudioParam's intrinsic value synchronously, so the `muted` / `volume`\n * getters reflect the change immediately. `setValueAtTime` only schedules an\n * event on the automation timeline and leaves `.value` stale until the next\n * render quantum, which made `muted` report the pre-change value.\n */\n private applyGain() {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.value = this._muted ? 0 : this._volume;\n }\n\n get audioLocked(): boolean {\n if (!this.ctx) {\n return true;\n }\n return this.ctx.state !== 'running';\n }\n\n constructor(obj?: SoundSystemParams) {\n super();\n Object.assign(this, obj);\n }\n\n /**\n * Resume playback of all paused audio.\n */\n resumeAll() {\n const handleResume = () => {\n this.pausedComponents.forEach(component => {\n component.play();\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n };\n this.ctx.resume().then(handleResume, handleResume);\n }\n\n /**\n * Pause all currently playing audio.\n */\n pauseAll() {\n this.components.forEach(component => {\n if (component.playing) {\n this.pausedComponents.push(component);\n component.pause();\n }\n });\n this.ctx.suspend().then();\n }\n\n /**\n * Stop all currently playing audio.\n */\n stopAll() {\n this.components.forEach(component => {\n if (component.playing) {\n component.stop();\n }\n });\n // Clear the previously cached paused list.\n this.pausedComponents = [];\n this.ctx.suspend().then();\n }\n\n /**\n * System init: configure params before the game starts.\n */\n init() {\n this.setupAudioContext();\n }\n\n update() {\n const changes = this.componentObserver.clear();\n for (const changed of changes) {\n this.componentChanged(changed);\n }\n }\n\n /**\n * Called when the game starts or resumes playing after a pause.\n */\n onResume() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.resumeAll();\n }\n\n /**\n * Called when the game is paused.\n */\n onPause() {\n if (!this.autoPauseAndStart) {\n return;\n }\n this.pauseAll();\n }\n\n /**\n * Called when the system is destroyed.\n */\n onDestroy() {\n this.components.forEach(component => {\n component.onDestroy();\n });\n this.components = [];\n if (this.ctx) {\n this.gainNode.disconnect();\n this.gainNode = null;\n this.ctx.close();\n this.ctx = null;\n }\n }\n\n async componentChanged(changed: ComponentChanged) {\n if (changed.componentName !== 'Sound') return;\n\n if (changed.type === OBSERVER_TYPE.ADD) {\n this.add(changed);\n }\n }\n\n private setupAudioContext() {\n try {\n const AudioContext = window.AudioContext || (window as any).webkitAudioContext;\n this.ctx = new AudioContext();\n } catch (error) {\n console.error(error);\n if (this.onError) {\n this.onError(error);\n }\n }\n\n if (!this.ctx) {\n return;\n }\n this.gainNode =\n typeof this.ctx.createGain === 'undefined' ? (this.ctx as any).createGainNode() : this.ctx.createGain();\n this.applyGain();\n this.gainNode.connect(this.ctx.destination);\n this.unlockAudio();\n }\n\n private unlockAudio() {\n if (!this.ctx || !this.audioLocked) {\n return;\n }\n\n const unlock = () => {\n if (this.ctx) {\n const removeListenerFn = () => {\n document.body.removeEventListener('touchstart', unlock);\n document.body.removeEventListener('touchend', unlock);\n document.body.removeEventListener('click', unlock);\n };\n this.ctx.resume().then(removeListenerFn, removeListenerFn);\n }\n };\n document.body.addEventListener('touchstart', unlock);\n document.body.addEventListener('touchend', unlock);\n document.body.addEventListener('click', unlock);\n }\n\n private async add(changed: ComponentChanged) {\n const component = changed.component as SoundComponent;\n this.components.push(component);\n try {\n const { config } = component;\n component.state = 'loading';\n\n const audio = await resource.getResource(config.resource);\n if (!this.audioBufferCache[audio.name] && audio?.data?.audio) {\n this.audioBufferCache[audio.name] = await this.decodeAudioData(audio.data.audio, audio.name);\n }\n if (this.audioBufferCache[audio.name]) {\n component.systemContext = this.ctx;\n component.systemDestination = this.gainNode;\n component.onload(this.audioBufferCache[audio.name]);\n }\n } catch (error) {\n if (this.onError) {\n this.onError(error);\n }\n }\n }\n\n private decodeAudioData(arraybuffer: ArrayBuffer, name: string) {\n if (this.decodeAudioPromiseMap[name]) {\n return this.decodeAudioPromiseMap[name];\n }\n\n const promise = new Promise<AudioBuffer>((resolve, reject) => {\n if (!this.ctx) {\n reject(new Error('No audio support'));\n }\n\n const success = (decodedData: AudioBuffer) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n if (decodedData) {\n resolve(decodedData);\n } else {\n reject(new Error(`Error decoding audio ${name}`));\n }\n };\n\n const error = (err: DOMException) => {\n if (this.decodeAudioPromiseMap[name]) {\n delete this.decodeAudioPromiseMap[name];\n }\n reject(new Error(`${err}. arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n };\n\n const promise = this.ctx.decodeAudioData(arraybuffer, success, error)\n if (promise instanceof Promise) {\n promise.catch((err) => {\n reject(new Error(`catch ${err}, arrayBuffer byteLength: ${arraybuffer ? arraybuffer.byteLength : 0}`));\n });\n }\n });\n\n this.decodeAudioPromiseMap[name] = promise;\n return promise;\n }\n}\n\nexport default SoundSystem;\n","/** Auto-generated by scripts/build-package.mjs — do not edit. */\n\nimport SoundSystem from './SoundSystem';\n\nObject.assign(SoundSystem, {\n packageName: \"@combos-fun/plugin-sound\",\n packageVersion: \"0.0.31\",\n});\n","import { Component } from '@combos-fun/engine';\n\nexport interface SoundParams {\n resource: string;\n autoplay?: boolean;\n muted?: boolean;\n volume?: number;\n loop?: boolean;\n seek?: number;\n duration?: number;\n onEnd?: () => void;\n}\n\nclass Sound extends Component<SoundParams> {\n static componentName = 'Sound';\n\n systemContext: AudioContext;\n\n systemDestination: GainNode;\n\n playing: boolean;\n\n state: 'unloaded' | 'loading' | 'loaded' = 'unloaded';\n\n config: SoundParams = {\n resource: '',\n autoplay: false,\n muted: false,\n volume: 1,\n loop: false,\n seek: 0,\n };\n\n private buffer: AudioBuffer;\n\n private sourceNode: AudioBufferSourceNode;\n\n private gainNode: GainNode;\n\n private paused: boolean;\n\n private playTime: number = 0;\n\n private startTime: number = 0;\n\n private duration: number = 0;\n\n private actionQueue: (() => void)[] = [];\n\n private endedListener: () => void;\n\n get muted(): boolean {\n return this.gainNode ? this.gainNode.gain.value === 0 : false;\n }\n\n set muted(v: boolean) {\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v ? 0 : this.config.volume, 0);\n }\n\n get volume(): number {\n return this.gainNode ? this.gainNode.gain.value : 1;\n }\n\n set volume(v: number) {\n if (typeof v !== 'number' || v < 0 || v > 1) {\n return;\n }\n this.config.volume = v;\n if (!this.gainNode) {\n return;\n }\n this.gainNode.gain.setValueAtTime(v, 0);\n }\n\n init(obj?: SoundParams) {\n if (!obj) {\n return;\n }\n\n Object.assign(this.config, obj);\n if (this.config.autoplay) {\n this.actionQueue.push(this.play.bind(this));\n }\n }\n\n play() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.play.bind(this));\n }\n this.destroySource();\n this.createSource();\n\n if (!this.sourceNode) {\n return;\n }\n const when = this.systemContext.currentTime;\n const offset = this.config.seek;\n const duration = this.config.duration;\n\n this.sourceNode.start(0, offset, duration);\n\n this.startTime = when;\n this.playTime = when - offset;\n this.paused = false;\n this.playing = true;\n this.resetConfig();\n this.endedListener = () => {\n if (!this.sourceNode) {\n return;\n }\n if (this.config.onEnd) {\n this.config.onEnd();\n }\n // Release resources once non-interactive playback finishes.\n if (this.playing) {\n this.destroySource();\n }\n };\n this.sourceNode.addEventListener('ended', this.endedListener);\n }\n\n pause() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.pause.bind(this));\n }\n if (this.paused || !this.playing) {\n return;\n }\n this.paused = true;\n this.playing = false;\n this.config.seek = this.getCurrentTime();\n this.destroySource();\n }\n\n stop() {\n if (this.state !== 'loaded') {\n this.actionQueue.push(this.stop.bind(this));\n }\n if (!this.paused && !this.playing) {\n return;\n }\n this.playing = false;\n this.paused = false;\n this.destroySource();\n this.resetConfig();\n }\n\n onload(buffer: AudioBuffer) {\n this.state = 'loaded';\n this.buffer = buffer;\n this.duration = this.buffer.duration;\n this.actionQueue.forEach(action => action());\n this.actionQueue.length = 0;\n }\n\n onDestroy() {\n this.actionQueue.length = 0;\n this.destroySource();\n }\n\n private resetConfig() {\n this.config.seek = 0;\n }\n\n private getCurrentTime() {\n if (this.config.loop && this.duration > 0) {\n return (this.systemContext.currentTime - this.playTime) % this.duration;\n }\n\n return this.systemContext.currentTime - this.playTime;\n }\n\n private createSource() {\n if (!this.systemContext || this.state !== 'loaded') {\n return;\n }\n this.sourceNode = this.systemContext.createBufferSource();\n this.sourceNode.buffer = this.buffer;\n this.sourceNode.loop = this.config.loop;\n\n if (!this.gainNode) {\n this.gainNode = this.systemContext.createGain();\n this.gainNode.connect(this.systemDestination);\n Object.assign(this, this.config);\n }\n this.sourceNode.connect(this.gainNode);\n }\n\n private destroySource() {\n if (!this.sourceNode) return;\n this.sourceNode.removeEventListener('ended', this.endedListener);\n this.sourceNode.stop();\n this.sourceNode.disconnect();\n this.sourceNode = null;\n\n this.startTime = 0;\n this.playTime = 0;\n this.playing = false;\n }\n}\n\nexport default Sound;\n"],"names":["SoundSystem"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@combos-fun/plugin-sound",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.31",
|
|
4
4
|
"description": "Audio playback",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "dist/plugin-sound.esm.js",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"author": "sun668 <q947692259@gmail.com>",
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"eventemitter3": "^5.0.4",
|
|
41
|
-
"@combos-fun/engine": "0.0.
|
|
41
|
+
"@combos-fun/engine": "0.0.31"
|
|
42
42
|
},
|
|
43
43
|
"scripts": {
|
|
44
44
|
"build": "node ../../scripts/build-package.mjs"
|