import { AudioFrame } from './audio_frame.cjs';
export { AsyncQueue } from './async_queue.cjs';
import '@livekit/rtc-ffi-bindings';

type AudioStream = {
    [Symbol.asyncIterator](): {
        next(): Promise<IteratorResult<AudioFrame>>;
    };
};
interface AudioMixerOptions {
    /**
     * The size of the audio block (in samples) for mixing.
     * If not provided, defaults to sampleRate / 10 (100ms).
     */
    blocksize?: number;
    /**
     * The maximum wait time in milliseconds for each stream to provide
     * audio data before timing out. Defaults to 100 ms.
     */
    streamTimeoutMs?: number;
    /**
     * The maximum number of mixed frames to store in the output queue.
     * Defaults to 100.
     */
    capacity?: number;
}
/**
 * AudioMixer combines multiple async audio streams into a single output stream.
 *
 * The mixer accepts multiple async audio streams and mixes them into a single output stream.
 * Each output frame is generated with a fixed chunk size determined by the blocksize (in samples).
 * If blocksize is not provided (or 0), it defaults to 100ms.
 *
 * Each input stream is processed in parallel, accumulating audio data until at least one chunk
 * of samples is available. If an input stream does not provide data within the specified timeout,
 * a warning is logged. The mixer can be closed immediately
 * (dropping unconsumed frames) or allowed to flush remaining data using endInput().
 *
 * @example
 * ```typescript
 * const mixer = new AudioMixer(48000, 2);
 * mixer.addStream(stream1);
 * mixer.addStream(stream2);
 *
 * for await (const frame of mixer) {
 *   // Process mixed audio frame
 * }
 * ```
 */
declare class AudioMixer {
    private streams;
    private buffers;
    private streamIterators;
    private sampleRate;
    private numChannels;
    private chunkSize;
    private streamTimeoutMs;
    private queue;
    private streamSignal;
    private ending;
    private mixerTask?;
    private closed;
    /**
     * Initialize the AudioMixer.
     *
     * @param sampleRate - The audio sample rate in Hz.
     * @param numChannels - The number of audio channels.
     * @param options - Optional configuration for the mixer.
     */
    constructor(sampleRate: number, numChannels: number, options?: AudioMixerOptions);
    /**
     * Add an audio stream to the mixer.
     *
     * The stream is added to the internal set of streams and an empty buffer is initialized for it,
     * if not already present.
     *
     * @param stream - An async iterable that produces AudioFrame objects.
     * @throws Error if the mixer has been closed.
     */
    addStream(stream: AudioStream): void;
    /**
     * Remove an audio stream from the mixer.
     *
     * This method removes the specified stream and its associated buffer from the mixer.
     *
     * @param stream - The audio stream to remove.
     */
    removeStream(stream: AudioStream): void;
    /**
     * Returns an async iterator for the mixed audio frames.
     */
    [Symbol.asyncIterator](): {
        next: () => Promise<IteratorResult<AudioFrame>>;
    };
    /**
     * Immediately stop mixing and close the mixer.
     *
     * This stops the mixing task, and any unconsumed output in the queue may be dropped.
     */
    aclose(): Promise<void>;
    /**
     * Signal that no more streams will be added.
     *
     * This method marks the mixer as closed so that it flushes any remaining buffered output before ending.
     * Note that existing streams will still be processed until exhausted.
     */
    endInput(): void;
    private getNextFrame;
    private mixer;
    private getContribution;
    private mixAudio;
    private sleep;
    /** Race a promise against a timeout. The losing setTimeout is automatically
     *  cleared via `.finally()` so callers don't need to manage cleanup. */
    private timeoutRace;
}

export { AudioMixer, type AudioMixerOptions };
