import { type AudioCaptureOpener, type AudioCaptureWarn } from './types.js'; /** * Provenance and license of the embedded filter, for a surface that describes * what it is running and for anything that redistributes it. * * SpeexDSP is BSD 3-clause: its copyright notice, condition list and disclaimer * must be reproduced with binary redistribution, and the base64 module inside * this package IS binary redistribution. {@link noticePath} is that reproduction, * carried in the repository beside the build inputs exactly as the wake model's * NOTICE is carried beside its artifacts. */ export declare const SPEEXDSP_PREPROCESS: { readonly component: "SpeexDSP"; readonly version: "1.2.1"; readonly license: "BSD-3-Clause"; readonly sourceUrl: "https://github.com/xiph/speexdsp/archive/refs/tags/SpeexDSP-1.2.1.tar.gz"; readonly upstreamSha256: "d17ca363654556a4ff1d02cc13d9eb1fc5a8642c90b40bd54ce266c3807b91a7"; readonly noticePath: "native/speexdsp-wasm/NOTICE.txt"; readonly licensePath: "native/speexdsp-wasm/SpeexDSP-1.2.1-COPYING.txt"; /** Bytes and checksum of the module actually embedded. */ readonly moduleBytes: 53678; readonly moduleSha256: "4829d9fa97e648ab9c45e9a685adba7bd762a4f948ec499c59b073bd03cce2bb"; /** Compiler, linker and sysroot the module was produced with. */ readonly toolchain: { readonly upstreamVersion: "1.2.1"; readonly upstreamUrl: "https://github.com/xiph/speexdsp/archive/refs/tags/SpeexDSP-1.2.1.tar.gz"; readonly upstreamSha256: "d17ca363654556a4ff1d02cc13d9eb1fc5a8642c90b40bd54ce266c3807b91a7"; readonly compiler: "clang version 22.1.8"; readonly linker: "LLD 22.1.8"; readonly sysroot: "wasi-libc 1:0+592+161b3195-1"; readonly builtins: "wasi-compiler-rt 22.1.0-2"; readonly flags: "--target=wasm32-wasip1 -Oz -DFLOATING_POINT -DUSE_SMALLFT -DOS_SUPPORT_CUSTOM -DEXPORT= -nostartfiles -Wl,--no-entry -Wl,--strip-all"; }; /** * What the denoiser is asked to do: attenuate the estimated noise floor by this * many dB. SpeexDSP's own default, read back from the running state rather than * assumed, {@link NoiseSuppressionStage.suppressionDb}. */ readonly defaultSuppressionDb: -15; }; /** * Samples per call into the suppressor: 20 ms at 16 kHz. * * NOT the 1280-sample (80 ms) frame the wake engine takes. The suppressor * estimates a noise floor per block over a window twice the block length, so an * 80 ms block would track a room four times more slowly than the 10–20 ms * SpeexDSP is designed and tuned around. An 80 ms frame is therefore filtered as * four consecutive 20 ms blocks through ONE state, which is a continuous filter * over the stream, not four independent ones. */ export declare const SPEEX_BLOCK_SAMPLES = 320; /** A running suppression filter over one capture stream. */ export interface NoiseSuppressionStage { /** What is filtering, for an indicator or a log: e.g. `speexdsp 1.2.1`. */ readonly label: string; /** Samples handed to the filter at a time. */ readonly blockSamples: number; /** The suppression floor in dB, read back from the running filter. */ readonly suppressionDb: number; /** * Filter one frame, returning a NEW frame. The input is left untouched, because * a caller may hold on to what it handed over (the wake pre-roll buffer does). * * `frame.length` must be a whole number of {@link blockSamples}. A frame that * is not throws: filtering the whole blocks and passing the tail through is the * silent half-measure this row exists to prevent. */ process(frame: Float32Array): Float32Array; /** Release the filter's memory. Idempotent; `process` after it throws. */ close(): void; } /** Builds a stage. Injected so a test can drive the wiring without WebAssembly. */ export type NoiseSuppressionFactory = (request: { readonly frameSamples: number; readonly sampleRate: number; }) => Promise; /** Whether this runtime can run the stage at all, and why not when it cannot. */ export interface NoiseSuppressionSupport { readonly supported: boolean; /** Written reason, for a settings row that must say why rather than just "no". */ readonly reason: string; } /** * Can this runtime run the filter? * * The answer is a WebAssembly check and nothing else: the module is embedded, so * there is no library to find, no download to have completed and no host * configuration involved. A JavaScript runtime without WebAssembly (a bare * Hermes build, for instance) is the one place the answer is no, and it gets a * reason a settings row can show. */ export declare function noiseSuppressionSupport(): NoiseSuppressionSupport; /** * Build a speexdsp suppression stage for frames of `frameSamples` samples. * * Rejects rather than degrading: no WebAssembly, an altered artifact, an ABI * mismatch or an out-of-memory instantiation all produce an error the caller * turns into a refusal, because the alternative is capturing unfiltered audio * while the setting says otherwise. */ export declare function createSpeexNoiseSuppression(options: { readonly frameSamples: number; readonly sampleRate?: number | undefined; }): Promise; /** How a wrapped opener is built. */ export interface NoiseSuppressingOpenerOptions { /** Stage builder. Defaults to the embedded speexdsp filter. */ readonly create?: NoiseSuppressionFactory | undefined; /** Capture rate, for the filter's noise model. Defaults to 16 kHz. */ readonly sampleRate?: number | undefined; readonly warn?: AudioCaptureWarn | undefined; } /** * Wrap a capture opener so `noiseSuppression: 'speex'` is actually applied. * * The inner opener is asked for the SAME request with `noiseSuppression: 'none'`, * because it is now being asked for raw frames that this wrapper filters, which * is also what makes wrapping idempotent: a host that wraps its own opener and * then hands it to the listener ends up with the outer wrapper filtering and the * inner one passing through, never with the audio filtered twice. * * With `none`, the inner opener is called unchanged and its frames are handed on * untouched, the same Float32Array objects, so the path is byte-identical to * having no wrapper at all. */ export declare function createNoiseSuppressingOpener(inner: AudioCaptureOpener, options?: NoiseSuppressingOpenerOptions): AudioCaptureOpener; //# sourceMappingURL=noise-suppression.d.ts.map