update: audimanager

This commit is contained in:
Tom Boullay
2026-05-11 10:22:12 +02:00
parent 78f6f5c1b0
commit c4f3cc0ff6
+28 -1
View File
@@ -24,10 +24,19 @@ interface StereoNodes {
panner: StereoPannerNode; panner: StereoPannerNode;
} }
interface OneShotAudioState {
category: OneShotAudioCategory;
volume: number;
}
export class AudioManager { export class AudioManager {
private static _instance: AudioManager | null = null; private static _instance: AudioManager | null = null;
private readonly _audioPools = new Map<string, HTMLAudioElement[]>(); private readonly _audioPools = new Map<string, HTMLAudioElement[]>();
private readonly _stereoNodes = new WeakMap<HTMLAudioElement, StereoNodes>(); private readonly _stereoNodes = new WeakMap<HTMLAudioElement, StereoNodes>();
private readonly _oneShotStates = new WeakMap<
HTMLAudioElement,
OneShotAudioState
>();
private readonly _categoryVolumes: Record<AudioCategory, number> = { private readonly _categoryVolumes: Record<AudioCategory, number> = {
...DEFAULT_CATEGORY_VOLUMES, ...DEFAULT_CATEGORY_VOLUMES,
}; };
@@ -59,7 +68,10 @@ export class AudioManager {
if (category === "music" && this._music) { if (category === "music" && this._music) {
this._music.volume = this._getEffectiveVolume("music", this._musicVolume); this._music.volume = this._getEffectiveVolume("music", this._musicVolume);
return;
} }
this._updateOneShotVolumes(category);
} }
getCategoryVolume(category: AudioCategory): number { getCategoryVolume(category: AudioCategory): number {
@@ -73,7 +85,9 @@ export class AudioManager {
): HTMLAudioElement { ): HTMLAudioElement {
const audio = this._acquireAudio(path); const audio = this._acquireAudio(path);
const category = options.category ?? AudioManager.DEFAULT_SOUND_CATEGORY; const category = options.category ?? AudioManager.DEFAULT_SOUND_CATEGORY;
audio.volume = this._getEffectiveVolume(category, volume); const baseVolume = AudioManager._clampVolume(volume);
this._oneShotStates.set(audio, { category, volume: baseVolume });
audio.volume = this._getEffectiveVolume(category, baseVolume);
audio.playbackRate = options.playbackRate ?? 1; audio.playbackRate = options.playbackRate ?? 1;
audio.currentTime = 0; audio.currentTime = 0;
this._setStereoPan(audio, options.pan ?? 0); this._setStereoPan(audio, options.pan ?? 0);
@@ -234,6 +248,19 @@ export class AudioManager {
return AudioManager._clampVolume(volume) * this._categoryVolumes[category]; return AudioManager._clampVolume(volume) * this._categoryVolumes[category];
} }
private _updateOneShotVolumes(category: AudioCategory): void {
if (category === "music") return;
this._audioPools.forEach((pool) => {
pool.forEach((audio) => {
const state = this._oneShotStates.get(audio);
if (!state || state.category !== category) return;
audio.volume = this._getEffectiveVolume(category, state.volume);
});
});
}
private static _clampPan(pan: number): number { private static _clampPan(pan: number): number {
return Math.max(-1, Math.min(1, pan)); return Math.max(-1, Math.min(1, pan));
} }