A cdylib loaded by the APO from the driver store. It wraps
DeepFilterNet3 (crate deep_filter,
dual MIT/Apache-2.0) with the model embedded in the DLL.
cargo test --release
cargo clippy --release --all-targets -- -D warnings
cargo build --release # -> target/release/kwiet_dsp.dllNon-negotiable, with the reasoning in
../docs/architecture.md §9:
- Static CRT via
.cargo/config.toml. Without it the DLL importsVCRUNTIME140.dlland may fail to load insideaudiodg. - No panic crosses the C boundary:
catch_unwindat every entry point, and emphatically notpanic = "abort"— an abort would killaudiodg, and with it every sound on the machine. kwiet_dsp_processis called from the worker thread, never the real-time one.
Declared in include/kwiet_dsp.h:
uint32_t kwiet_dsp_abi_version(void); // guards against a stale DLL
KwietDsp* kwiet_dsp_create(uint32_t sample_rate, uint32_t channels); // not real-time
void kwiet_dsp_destroy(KwietDsp*);
uint32_t kwiet_dsp_block_frames(void); // fixed frame the host must feed
int32_t kwiet_dsp_process(KwietDsp*, const float* in, float* out, uint32_t frames);
void kwiet_dsp_set_attenuation_db(KwietDsp*, float db); // thread-safe, atomicThe crate published on crates.io (deep_filter 0.2.5, 2022) is still DFN2, so we
depend on the Git repository. Two pins are needed to compile at all, both
commented in Cargo.toml:
- the
tractfamily at=0.21.4—deep_filterasks for^0.21.4, buttractrenamed a public field (symbol_table→symbols) in a release cargo considers compatible. The pin must live in the manifest:cargo update --precisedowngrades crate by crate and breaks the family's internal coherence (tract-pulse-oplrequires=its own version); kstringat2.0.2— 2.0.4 requires rustc 1.96.
The model ships inside the DLL: DfParams::default() embeds
DeepFilterNet3_onnx.tar.gz (7.6 MB) through the default-model feature. There
is no file to deploy next to it.
- 48 kHz only.
kwiet_dsp_createreturnsNULLfor any other rate and the host stays in passthrough. Resampling is still to be done. - Mono. The host's channels are summed on the way in, and the mono result is written back across every channel.
- Fixed frame of
kwiet_dsp_block_frames()(480 = 10 ms). The host uses that as its worker's block size; the rings decouple it from the APO's quantum. processallocates — tract allocates per inference. That is acceptable precisely because it runs on the worker and never on the real-time thread.