import type { AudioChannel, Vec2 } from '../core/types'; import { EventBus } from '../core/EventBus'; export interface SoundOptions { volume?: number; loop?: boolean; channel?: AudioChannel; pitch?: number; pan?: number; position?: Vec2; maxDistance?: number; } export interface MusicOptions { volume?: number; loop?: boolean; fadeIn?: number; } export declare class AudioManager { readonly events: EventBus; private ctx; private masterGain; private channelGains; private bufferCache; private activeMusic; private activeSounds; private pool; private _listenerPos; private _muted; private volumes; /** Initialize audio context (must be called after user gesture). */ init(): void; /** Ensure context is running (after autoplay policy). */ resume(): Promise; dispose(): void; /** Load an audio file and cache its buffer. */ load(id: string, url: string): Promise; /** Check if a sound is loaded. */ isLoaded(id: string): boolean; /** Play a sound effect. Returns an ID to control it. */ play(id: string, options?: SoundOptions): number; /** Stop a specific playing sound. */ stopSound(soundId: number): void; /** Play background music with optional crossfade. */ playMusic(id: string, options?: MusicOptions): void; /** Stop music with fade out. */ stopMusic(fadeOut?: number): void; private fadeOutMusic; setVolume(channel: AudioChannel, volume: number): void; getVolume(channel: AudioChannel): number; get muted(): boolean; set muted(value: boolean); setListenerPosition(pos: Vec2): void; /** Stop all sounds and music, properly disconnecting audio nodes. */ stopAll(): void; get activeSoundCount(): number; }