import { Emitter } from '@wonderlandengine/api';
import { BufferPlayer } from './audio-players.js';
/**
 * Enumerates the available channels within the AudioManager.
 * These channels can be utilized to regulate global volume.
 */
export declare enum AudioChannel {
    /** Intended for sound effects. Connects to Master AudioChannel. */
    Sfx = 0,
    /** Intended for music. Connects to Master AudioChannel. */
    Music = 1,
    /** Connects directly to output. */
    Master = 2
}
/**
 * Enumerates the possible states of playback for audio sources.
 */
export declare enum PlayState {
    /** The source is ready to be played */
    Ready = 0,
    /** The source has started playing */
    Playing = 1,
    /** The source has stopped */
    Stopped = 2,
    /** The source has paused */
    Paused = 3
}
/**
 * Represents a combination of a unique identifier and a play state.
 */
type PlayStateWithID = {
    /** Unique identifier associated with the audio source. */
    id: number;
    /** Current state of playback for the audio source. */
    state: PlayState;
};
/**
 * Combines all settings for configuring playback in the AudioManager.
 */
export type PlayConfig = {
    /** Sets the volume of the player (0-1) */
    volume?: number;
    /** Whether to loop the audio */
    loop?: boolean;
    /**
     * Sets the position of the audio source and makes it spatial.
     *
     * @remarks Panned audio will always use HRTF for spatialization.
     * For this to work correctly, the audio-listener needs to be set up!
     */
    position?: Float32Array;
    /** Sets the channel on which the audio will be played. */
    channel?: AudioChannel;
    /**
     * Whether the audio has priority or not. If not, playback can be stopped to free up a player when no others are
     * available.
     */
    priority?: boolean;
    /** Defines the offset in seconds on where to start playing the audio */
    playOffset?: number;
    /** Marks the playback as being a one-shot, @deprecated since >1.2.0 */
    oneShot?: boolean;
};
/**
 * Default number of internal players.
 */
export declare const DEF_PLAYER_COUNT = 32;
/**
 * Manages audio files and players, providing control over playback on three audio channels.
 *
 * @classdesc
 * The AudioManager handles audio files and players, offering control over playback on three distinct channels.
 * @see AudioChannel
 *
 * @remarks The AudioManager is able to play audio with spatial positioning. Keep in mind that for this to work
 * correctly, you will need to set up the `audio-listener` component!
 *
 * @example
 * ```js
 * enum Sounds {
 *      Click,
 *      GunShot,
 * }
 *
 * // AudioManager can't be constructed in a non-browser environment!
 * export const am = window.AudioContext ? new AudioManager() : null;
 *
 * if (am != null) {
 *      am.load('path/to/click.wav', Sounds.Click);
 *      am.load('path/to/gunshot.wav', Sounds.GunShot);
 * }
 *
 * onPress() {
 *      am.play(Sounds.Click, {volume: 0.8, position: [0, 5, 1]});
 * }
 * ```
 */
export interface IAudioManager {
    /**
     * Decodes and stores the given audio files and associates them with the given ID.
     *
     * @param path Path to the audio files. Can either be a single string or a list of strings.
     * @param id Identifier for the given audio files.
     *
     * @remarks Is there more than one audio file available per id, on playback, they will be selected at random.
     * This enables easy variation of the same sounds!
     *
     * @returns A Promise that resolves when all files are successfully loaded.
     */
    load(path: string[] | string, id: number): void;
    /**
     * Same as load(), but lets you easily load a bunch of files without needing to call the manager everytime.
     *
     * @see load
     *
     * @param pair Pair of source files and associating identifier.
     * Multiple pairs can be provided as separate arguments.
     *
     * @returns A Promise that resolves when all files are successfully loaded.
     */
    loadBatch(...pair: [string[] | string, number][]): void;
    /**
     * Plays the audio file associated with the given ID.
     *
     * @param id ID of the file that should be played.
     * @param config Optional parameter that will configure how the audio is played. Is no configuration provided,
     * the audio will play at volume 1.0, without panning and on the SFX channel, priority set to false.
     *
     * @note If the 'priority' parameter is set to true, the audio playback will not be interrupted
     * to allocate a player in case all players are currently occupied. If 'priority' is set to false (default),
     * playback may be interrupted to allocate a player for a new 'play()' call.
     *
     * @returns The playId that identifies this specific playback, so it can be stopped or identified in the
     * emitter. If playback could not be started, an invalid playId is returned.
     */
    play(id: number, config?: PlayConfig): number;
    /**
     * Plays the audio file associated with the given ID until it naturally ends.
     *
     * @note
     * - IDs can be triggered as often as there are one-shot players in the AudioManager.
     * - One shots work with First-In-First-Out principle. If all players are occupied, the manager will stop the
     *   one that started playing first, to free up a player for the new ID.
     * - One-shots are always connect to the SFX channel.
     * - One-shots cant loop.
     * - One-shots can only be stopped all at once with stopOneShots().
     * - One-shots can't be assigned a priority.
     *
     * @param id ID of the file that should be played.
     * @param config  Optional parameter that will configure how the audio is played. Note that only the position
     * and volume settings will affect the playback.
     *
     * @deprecated since > 1.2.0, use play() instead.
     */
    playOneShot(id: number, config?: PlayConfig): void;
    /**
     * Same as `play()` but waits until the user has interacted with the website.
     *
     * @param id ID of the file that should be played.
     * @param config Optional parameter that will configure how the audio is played. Is no configuration provided,
     * the audio will play at volume 1.0, without panning and on the SFX channel, priority set to false.
     *
     * @returns The playId that identifies this specific playback, so it can be stopped or identified in the
     * emitter.
     */
    autoplay(id: number, config?: PlayConfig): number;
    /**
     * Stops the audio associated with the given ID.
     *
     * @param playId Specifies the exact audio that should be stopped.
     *
     * @note Obtain the playId from the play() method.
     * @see play
     */
    stop(playId: number): void;
    /**
     * Pauses a playing audio.
     *
     * @param playId Id of the source that should be paused.
     */
    pause(playId: number): void;
    /**
     * Resumes a paused audio.
     *
     * @param playId Id of the source that should be resumed.
     */
    resume(playId: number): void;
    /**
     * Stops playback of all one-shot players.
     * @deprecated since >1.2.0, use  regular play() with stop() instead.
     */
    stopOneShots(): void;
    /**
     * Resumes all paused players.
     */
    resumeAll(): void;
    /**
     * Pauses all playing players.
     */
    pauseAll(): void;
    /**
     * Stops all audio.
     */
    stopAll(): void;
    /**
     * Sets the volume of the given audio channel.
     *
     * @param channel Specifies the audio channel that should be modified.
     * @param volume Volume that the channel should be set to.
     * @param time Optional time parameter that specifies the time it takes for the channel to reach the specified
     * volume in seconds (Default is 0).
     */
    setGlobalVolume(channel: AudioChannel, volume: number, time: number): void;
    /**
     * Removes all decoded audio from the manager that is associated with the given ID.
     *
     * @warning This will stop playback of the given ID.
     * @param id Identifier of the audio that should be removed.
     */
    remove(id: number): void;
    /**
     * Removes all decoded audio from the manager, effectively resetting it.
     *
     * @warning This will stop playback entirely.
     */
    removeAll(): void;
    /**
     * Gets the sourceId of a playId.
     *
     * @param playId of which to get the sourceId from.
     */
    getSourceIdFromPlayId(playId: number): number;
    /**
     * Gets the current amount of free players in the audio manager.
     *
     * @note Use this to check how many resources your current project is using.
     */
    get amountOfFreePlayers(): number;
}
export declare class AudioManager implements IAudioManager {
    /** The emitter will notify all listeners about the PlayState of a unique ID.
     *
     * @remarks
     * - READY will be emitted if all sources of a given source ID have loaded.
     * - PLAYING / STOPPED / PAUSED are only emitted for play IDs that are returned by the play() method.
     * - If you want to check the status for a source ID, convert the play ID of the message using the
     *   getSourceIdFromPlayId() method.
     *
     * @see getSourceIdFromPlayId
     * @example
     * ```js
     * const music = audioManager.play(Sounds.Music);
     * audioManager.emitter.add((msg) => {
     *    if (msg.id === music) {
     *          console.log(msg.state);
     *    }
     * });
     * ```
     */
    readonly emitter: Emitter<[PlayStateWithID]>;
    /**
     * Sets the random function the manager will use for selecting buffers.
     *
     * @remarks Default random function is Math.random()
     * @param func Function that should be used for select the buffer.
     */
    randomBufferSelectFunction: () => number;
    private _bufferCache;
    private _playerCache;
    private _playerCacheIndex;
    private _amountOfFreePlayers;
    private _instanceCounter;
    private _masterGain;
    private _musicGain;
    private _sfxGain;
    private _unlocked;
    private _autoplayStorage;
    /**
     * Constructs a AudioManager.
     *
     * Uses the default amount of players.
     * @see DEF_PLAYER_COUNT
     * @example
     * ```js
     * // AudioManager can't be constructed in a non-browser environment!
     * export const am = window.AudioContext ? new AudioManager() : null!;
     * ```
     */
    constructor();
    load(path: string[] | string, id: number): Promise<void>;
    loadBatch(...pair: [string[] | string, number][]): Promise<void[]>;
    play(id: number, config?: PlayConfig): number;
    private _playWithUniqueId;
    playOneShot(id: number, config?: PlayConfig): void;
    /**
     * Advances the _playerCacheIndex and stops the player on that position.
     *
     * @returns A BufferPlayer with PlayState.Stopped, or undefined if no player can be stopped.
     */
    _getAvailablePlayer(): BufferPlayer | undefined;
    autoplay(id: number, config?: PlayConfig): number;
    stop(playId: number): void;
    pause(playId: number): void;
    resume(playId: number): void;
    stopOneShots(): void;
    resumeAll(): void;
    pauseAll(): void;
    stopAll(): void;
    setGlobalVolume(channel: AudioChannel, volume: number, time?: number): void;
    remove(id: number): void;
    removeAll(): void;
    getSourceIdFromPlayId(playId: number): number;
    get amountOfFreePlayers(): number;
    private _selectRandomBuffer;
    private _generateUniqueId;
    /**
     * @warning This function is for internal use only!
     */
    _returnPriorityPlayer(player: BufferPlayer): void;
    private _unlockAudioContext;
}
export declare class EmptyAudioManager implements IAudioManager {
    load(path: string[] | string, id: number): Promise<void>;
    loadBatch(...pair: [string[] | string, number][]): Promise<void>;
    play(id: number, config?: PlayConfig): number;
    playOneShot(id: number, config?: PlayConfig): void;
    autoplay(id: number, config?: PlayConfig): number;
    stop(playId: number): void;
    pause(playId: number): void;
    resume(playId: number): void;
    stopOneShots(): void;
    resumeAll(): void;
    pauseAll(): void;
    stopAll(): void;
    setGlobalVolume(channel: AudioChannel, volume: number, time: number): void;
    remove(id: number): void;
    removeAll(): void;
    getSourceIdFromPlayId(playId: number): number;
    get amountOfFreePlayers(): number;
}
/**
 * Global instance of a AudioManager.
 *
 * @remarks
 * To construct an AudioManager, the WebAudio API is needed. For non-browser environments, like during the packaging
 * step of the wonderland editor, the globalAudioManager is set to an `EmptyAudioManager`.
 * It enables the usage of `load()` and `loadBatch()` in top-level code.
 *
 * @warning
 * ⚠️ Only load() and loadBatch() can be used in top-level code ⚠️
 */
export declare const globalAudioManager: IAudioManager;
export {};
