update: audimanager
This commit is contained in:
@@ -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));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user