import { AudioFrame } from './audio_frame.js'; export { AsyncQueue } from './async_queue.js'; import '@livekit/rtc-ffi-bindings'; type AudioStream = { [Symbol.asyncIterator](): { next(): Promise>; }; }; 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>; }; /** * Immediately stop mixing and close the mixer. * * This stops the mixing task, and any unconsumed output in the queue may be dropped. */ aclose(): Promise; /** * 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; private timeout; } export { AudioMixer, type AudioMixerOptions };