Add new crate denoise required by audio (#38217)

David Kleingeld and Mikayla created

The audio crate will use the denoise crate to remove background noises
from microphone input.

We intent to contribute this to rodio. Before that can happen a PR needs
to land in candle. Until then this lives here.

Uses a candle fork which removes the dependency on `protoc` and has the PR's mentioned above already applied.

Release Notes:

- N/A

---------

Co-authored-by: Mikayla <mikayla@zed.dev>

Change summary

Cargo.lock                                              | 577 ++++++++++
Cargo.toml                                              |   1 
crates/denoise/Cargo.toml                               |  21 
crates/denoise/LICENSE-GPL                              |   1 
crates/denoise/README.md                                |  20 
crates/denoise/examples/denoise.rs                      |  11 
crates/denoise/examples/enable_disable.rs               |  23 
crates/denoise/models/model_1_converted_simplified.onnx |   0 
crates/denoise/models/model_2_converted_simplified.onnx |   0 
crates/denoise/src/engine.rs                            | 204 +++
crates/denoise/src/lib.rs                               | 270 +++++
tooling/workspace-hack/Cargo.toml                       |  66 
12 files changed, 1,156 insertions(+), 38 deletions(-)

Detailed changes

Cargo.lock 🔗

@@ -688,6 +688,9 @@ name = "arbitrary"
 version = "1.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
+dependencies = [
+ "derive_arbitrary",
+]
 
 [[package]]
 name = "arc-swap"
@@ -2187,7 +2190,7 @@ dependencies = [
  "bitflags 2.9.0",
  "cexpr",
  "clang-sys",
- "itertools 0.12.1",
+ "itertools 0.11.0",
  "lazy_static",
  "lazycell",
  "log",
@@ -2685,6 +2688,53 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "candle-core"
+version = "0.9.1"
+source = "git+https://github.com/zed-industries/candle?branch=9.1-patched#724d75eb3deebefe83f2a7381a45d4fac6eda383"
+dependencies = [
+ "byteorder",
+ "float8",
+ "gemm 0.17.1",
+ "half",
+ "memmap2",
+ "num-traits",
+ "num_cpus",
+ "rand 0.9.1",
+ "rand_distr",
+ "rayon",
+ "safetensors",
+ "thiserror 1.0.69",
+ "ug",
+ "yoke",
+ "zip 1.1.4",
+]
+
+[[package]]
+name = "candle-nn"
+version = "0.9.1"
+source = "git+https://github.com/zed-industries/candle?branch=9.1-patched#724d75eb3deebefe83f2a7381a45d4fac6eda383"
+dependencies = [
+ "candle-core",
+ "half",
+ "libc",
+ "num-traits",
+ "rayon",
+ "safetensors",
+ "serde",
+ "thiserror 1.0.69",
+]
+
+[[package]]
+name = "candle-onnx"
+version = "0.9.1"
+source = "git+https://github.com/zed-industries/candle?branch=9.1-patched#724d75eb3deebefe83f2a7381a45d4fac6eda383"
+dependencies = [
+ "candle-core",
+ "candle-nn",
+ "prost 0.12.6",
+]
+
 [[package]]
 name = "cap-fs-ext"
 version = "3.4.4"
@@ -4635,6 +4685,20 @@ version = "0.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "da692b8d1080ea3045efaab14434d40468c3d8657e42abddfffca87b428f4c1b"
 
+[[package]]
+name = "denoise"
+version = "0.1.0"
+dependencies = [
+ "candle-core",
+ "candle-onnx",
+ "log",
+ "realfft",
+ "rodio",
+ "rustfft",
+ "thiserror 2.0.12",
+ "workspace-hack",
+]
+
 [[package]]
 name = "der"
 version = "0.6.1"
@@ -4666,6 +4730,17 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "derive_arbitrary"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e567bd82dcff979e4b03460c307b3cdc9e96fde3d73bed1496d2bc75d9dd62a"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
 [[package]]
 name = "derive_more"
 version = "0.99.19"
@@ -4821,7 +4896,7 @@ dependencies = [
  "libc",
  "option-ext",
  "redox_users 0.5.0",
- "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
 ]
 
 [[package]]
@@ -4979,6 +5054,25 @@ version = "1.0.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005"
 
+[[package]]
+name = "dyn-stack"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "56e53799688f5632f364f8fb387488dd05db9fe45db7011be066fc20e7027f8b"
+dependencies = [
+ "bytemuck",
+ "reborrow",
+]
+
+[[package]]
+name = "dyn-stack"
+version = "0.13.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "490bd48eb68fffcfed519b4edbfd82c69cbe741d175b84f0e0cbe8c57cbe0bdd"
+dependencies = [
+ "bytemuck",
+]
+
 [[package]]
 name = "ec4rs"
 version = "1.2.0"
@@ -5239,6 +5333,18 @@ version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
 
+[[package]]
+name = "enum-as-inner"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc"
+dependencies = [
+ "heck 0.5.0",
+ "proc-macro2",
+ "quote",
+ "syn 2.0.101",
+]
+
 [[package]]
 name = "enumflags2"
 version = "0.7.11"
@@ -5869,6 +5975,18 @@ version = "0.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ce81f49ae8a0482e4c55ea62ebbd7e5a686af544c00b9d090bba3ff9be97b3d"
 
+[[package]]
+name = "float8"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4203231de188ebbdfb85c11f3c20ca2b063945710de04e7b59268731e728b462"
+dependencies = [
+ "half",
+ "num-traits",
+ "rand 0.9.1",
+ "rand_distr",
+]
+
 [[package]]
 name = "float_next_after"
 version = "1.0.0"
@@ -6323,6 +6441,243 @@ dependencies = [
  "thread_local",
 ]
 
+[[package]]
+name = "gemm"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ab24cc62135b40090e31a76a9b2766a501979f3070fa27f689c27ec04377d32"
+dependencies = [
+ "dyn-stack 0.10.0",
+ "gemm-c32 0.17.1",
+ "gemm-c64 0.17.1",
+ "gemm-common 0.17.1",
+ "gemm-f16 0.17.1",
+ "gemm-f32 0.17.1",
+ "gemm-f64 0.17.1",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 10.7.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ab96b703d31950f1aeddded248bc95543c9efc7ac9c4a21fda8703a83ee35451"
+dependencies = [
+ "dyn-stack 0.13.0",
+ "gemm-c32 0.18.2",
+ "gemm-c64 0.18.2",
+ "gemm-common 0.18.2",
+ "gemm-f16 0.18.2",
+ "gemm-f32 0.18.2",
+ "gemm-f64 0.18.2",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 11.6.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-c32"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9c030d0b983d1e34a546b86e08f600c11696fde16199f971cd46c12e67512c0"
+dependencies = [
+ "dyn-stack 0.10.0",
+ "gemm-common 0.17.1",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 10.7.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-c32"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f6db9fd9f40421d00eea9dd0770045a5603b8d684654816637732463f4073847"
+dependencies = [
+ "dyn-stack 0.13.0",
+ "gemm-common 0.18.2",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 11.6.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-c64"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fbb5f2e79fefb9693d18e1066a557b4546cd334b226beadc68b11a8f9431852a"
+dependencies = [
+ "dyn-stack 0.10.0",
+ "gemm-common 0.17.1",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 10.7.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-c64"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dfcad8a3d35a43758330b635d02edad980c1e143dc2f21e6fd25f9e4eada8edf"
+dependencies = [
+ "dyn-stack 0.13.0",
+ "gemm-common 0.18.2",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 11.6.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-common"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a2e7ea062c987abcd8db95db917b4ffb4ecdfd0668471d8dc54734fdff2354e8"
+dependencies = [
+ "bytemuck",
+ "dyn-stack 0.10.0",
+ "half",
+ "num-complex",
+ "num-traits",
+ "once_cell",
+ "paste",
+ "pulp 0.18.22",
+ "raw-cpuid 10.7.0",
+ "rayon",
+ "seq-macro",
+ "sysctl 0.5.5",
+]
+
+[[package]]
+name = "gemm-common"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a352d4a69cbe938b9e2a9cb7a3a63b7e72f9349174a2752a558a8a563510d0f3"
+dependencies = [
+ "bytemuck",
+ "dyn-stack 0.13.0",
+ "half",
+ "libm",
+ "num-complex",
+ "num-traits",
+ "once_cell",
+ "paste",
+ "pulp 0.21.5",
+ "raw-cpuid 11.6.0",
+ "rayon",
+ "seq-macro",
+ "sysctl 0.6.0",
+]
+
+[[package]]
+name = "gemm-f16"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ca4c06b9b11952071d317604acb332e924e817bd891bec8dfb494168c7cedd4"
+dependencies = [
+ "dyn-stack 0.10.0",
+ "gemm-common 0.17.1",
+ "gemm-f32 0.17.1",
+ "half",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 10.7.0",
+ "rayon",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-f16"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cff95ae3259432f3c3410eaa919033cd03791d81cebd18018393dc147952e109"
+dependencies = [
+ "dyn-stack 0.13.0",
+ "gemm-common 0.18.2",
+ "gemm-f32 0.18.2",
+ "half",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 11.6.0",
+ "rayon",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-f32"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e9a69f51aaefbd9cf12d18faf273d3e982d9d711f60775645ed5c8047b4ae113"
+dependencies = [
+ "dyn-stack 0.10.0",
+ "gemm-common 0.17.1",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 10.7.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-f32"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bc8d3d4385393304f407392f754cd2dc4b315d05063f62cf09f47b58de276864"
+dependencies = [
+ "dyn-stack 0.13.0",
+ "gemm-common 0.18.2",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 11.6.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-f64"
+version = "0.17.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa397a48544fadf0b81ec8741e5c0fba0043008113f71f2034def1935645d2b0"
+dependencies = [
+ "dyn-stack 0.10.0",
+ "gemm-common 0.17.1",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 10.7.0",
+ "seq-macro",
+]
+
+[[package]]
+name = "gemm-f64"
+version = "0.18.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "35b2a4f76ce4b8b16eadc11ccf2e083252d8237c1b589558a49b0183545015bd"
+dependencies = [
+ "dyn-stack 0.13.0",
+ "gemm-common 0.18.2",
+ "num-complex",
+ "num-traits",
+ "paste",
+ "raw-cpuid 11.6.0",
+ "seq-macro",
+]
+
 [[package]]
 name = "generator"
 version = "0.8.5"
@@ -7597,9 +7952,12 @@ version = "2.6.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
 dependencies = [
+ "bytemuck",
  "cfg-if",
  "crunchy",
  "num-traits",
+ "rand 0.9.1",
+ "rand_distr",
 ]
 
 [[package]]
@@ -10191,6 +10549,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
 dependencies = [
  "libc",
+ "stable_deref_trait",
 ]
 
 [[package]]
@@ -10457,12 +10816,6 @@ version = "0.8.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a"
 
-[[package]]
-name = "multimap"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03"
-
 [[package]]
 name = "naga"
 version = "25.0.1"
@@ -10836,6 +11189,7 @@ version = "0.4.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495"
 dependencies = [
+ "bytemuck",
  "num-traits",
 ]
 
@@ -12529,6 +12883,15 @@ dependencies = [
  "syn 2.0.101",
 ]
 
+[[package]]
+name = "primal-check"
+version = "0.3.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc0d895b311e3af9902528fbb8f928688abbd95872819320517cc24ca6b2bd08"
+dependencies = [
+ "num-integer",
+]
+
 [[package]]
 name = "proc-macro-crate"
 version = "3.3.0"
@@ -12837,7 +13200,7 @@ dependencies = [
  "itertools 0.10.5",
  "lazy_static",
  "log",
- "multimap 0.8.3",
+ "multimap",
  "petgraph",
  "prost 0.9.0",
  "prost-types 0.9.0",
@@ -12854,9 +13217,9 @@ checksum = "22505a5c94da8e3b7c2996394d1c933236c4d743e81a410bcca4e6989fc066a4"
 dependencies = [
  "bytes 1.10.1",
  "heck 0.5.0",
- "itertools 0.12.1",
+ "itertools 0.11.0",
  "log",
- "multimap 0.10.0",
+ "multimap",
  "once_cell",
  "petgraph",
  "prettyplease",
@@ -12887,7 +13250,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "81bddcdb20abf9501610992b6759a4c888aef7d1a7247ef75e2404275ac24af1"
 dependencies = [
  "anyhow",
- "itertools 0.12.1",
+ "itertools 0.11.0",
  "proc-macro2",
  "quote",
  "syn 2.0.101",
@@ -13028,6 +13391,32 @@ dependencies = [
  "wasmtime-math",
 ]
 
+[[package]]
+name = "pulp"
+version = "0.18.22"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0a01a0dc67cf4558d279f0c25b0962bd08fc6dec0137699eae304103e882fe6"
+dependencies = [
+ "bytemuck",
+ "libm",
+ "num-complex",
+ "reborrow",
+]
+
+[[package]]
+name = "pulp"
+version = "0.21.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "96b86df24f0a7ddd5e4b95c94fc9ed8a98f1ca94d3b01bdce2824097e7835907"
+dependencies = [
+ "bytemuck",
+ "cfg-if",
+ "libm",
+ "num-complex",
+ "reborrow",
+ "version_check",
+]
+
 [[package]]
 name = "qoi"
 version = "0.4.1"
@@ -13204,6 +13593,16 @@ dependencies = [
  "getrandom 0.3.2",
 ]
 
+[[package]]
+name = "rand_distr"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6a8615d50dcf34fa31f7ab52692afec947c4dd0ab803cc87cb3b0b4570ff7463"
+dependencies = [
+ "num-traits",
+ "rand 0.9.1",
+]
+
 [[package]]
 name = "range-map"
 version = "0.2.0"
@@ -13269,6 +13668,24 @@ dependencies = [
  "rgb",
 ]
 
+[[package]]
+name = "raw-cpuid"
+version = "10.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c297679cb867470fa8c9f67dbba74a78d78e3e98d7cf2b08d6d71540f797332"
+dependencies = [
+ "bitflags 1.3.2",
+]
+
+[[package]]
+name = "raw-cpuid"
+version = "11.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "498cd0dc59d73224351ee52a95fee0f1a617a2eae0e7d9d720cc622c73a54186"
+dependencies = [
+ "bitflags 2.9.0",
+]
+
 [[package]]
 name = "raw-window-handle"
 version = "0.6.2"
@@ -13317,6 +13734,21 @@ dependencies = [
  "font-types",
 ]
 
+[[package]]
+name = "realfft"
+version = "3.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f821338fddb99d089116342c46e9f1fbf3828dba077674613e734e01d6ea8677"
+dependencies = [
+ "rustfft",
+]
+
+[[package]]
+name = "reborrow"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "03251193000f4bd3b042892be858ee50e8b3719f2b08e5833ac4353724632430"
+
 [[package]]
 name = "recent_projects"
 version = "0.1.0"
@@ -14133,6 +14565,20 @@ dependencies = [
  "semver",
 ]
 
+[[package]]
+name = "rustfft"
+version = "6.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c6f140db74548f7c9d7cce60912c9ac414e74df5e718dc947d514b051b42f3f4"
+dependencies = [
+ "num-complex",
+ "num-integer",
+ "num-traits",
+ "primal-check",
+ "strength_reduce",
+ "transpose",
+]
+
 [[package]]
 name = "rustix"
 version = "0.38.44"
@@ -14357,6 +14803,16 @@ version = "1.0.20"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
 
+[[package]]
+name = "safetensors"
+version = "0.4.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44560c11236a6130a46ce36c836a62936dc81ebf8c36a37947423571be0e55b6"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
 [[package]]
 name = "salsa20"
 version = "0.10.2"
@@ -14738,6 +15194,12 @@ dependencies = [
  "serde",
 ]
 
+[[package]]
+name = "seq-macro"
+version = "0.3.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
+
 [[package]]
 name = "serde"
 version = "1.0.221"
@@ -15692,6 +16154,12 @@ dependencies = [
  "workspace-hack",
 ]
 
+[[package]]
+name = "strength_reduce"
+version = "0.2.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe895eb47f22e2ddd4dabc02bce419d2e643c8e3b585c78158b349195bc24d82"
+
 [[package]]
 name = "strict-num"
 version = "0.1.1"
@@ -16182,6 +16650,34 @@ dependencies = [
  "libc",
 ]
 
+[[package]]
+name = "sysctl"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ec7dddc5f0fee506baf8b9fdb989e242f17e4b11c61dfbb0635b705217199eea"
+dependencies = [
+ "bitflags 2.9.0",
+ "byteorder",
+ "enum-as-inner",
+ "libc",
+ "thiserror 1.0.69",
+ "walkdir",
+]
+
+[[package]]
+name = "sysctl"
+version = "0.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01198a2debb237c62b6826ec7081082d951f46dbb64b0e8c7649a452230d1dfc"
+dependencies = [
+ "bitflags 2.9.0",
+ "byteorder",
+ "enum-as-inner",
+ "libc",
+ "thiserror 1.0.69",
+ "walkdir",
+]
+
 [[package]]
 name = "sysinfo"
 version = "0.31.4"
@@ -17276,6 +17772,16 @@ dependencies = [
  "syn 2.0.101",
 ]
 
+[[package]]
+name = "transpose"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ad61aed86bc3faea4300c7aee358b4c6d0c8d6ccc36524c96e4c92ccf26e77e"
+dependencies = [
+ "num-integer",
+ "strength_reduce",
+]
+
 [[package]]
 name = "tree-sitter"
 version = "0.25.6"
@@ -17637,6 +18143,27 @@ dependencies = [
  "winapi",
 ]
 
+[[package]]
+name = "ug"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90b70b37e9074642bc5f60bb23247fd072a84314ca9e71cdf8527593406a0dd3"
+dependencies = [
+ "gemm 0.18.2",
+ "half",
+ "libloading",
+ "memmap2",
+ "num",
+ "num-traits",
+ "num_cpus",
+ "rayon",
+ "safetensors",
+ "serde",
+ "thiserror 1.0.69",
+ "tracing",
+ "yoke",
+]
+
 [[package]]
 name = "ui"
 version = "0.1.0"
@@ -18905,7 +19432,7 @@ dependencies = [
  "reqwest 0.11.27",
  "scratch",
  "semver",
- "zip",
+ "zip 0.6.6",
 ]
 
 [[package]]
@@ -20050,7 +20577,7 @@ dependencies = [
  "idna",
  "indexmap",
  "inout",
- "itertools 0.12.1",
+ "itertools 0.11.0",
  "itertools 0.13.0",
  "jiff",
  "lazy_static",
@@ -20064,6 +20591,7 @@ dependencies = [
  "lyon_path",
  "md-5",
  "memchr",
+ "memmap2",
  "mime_guess",
  "miniz_oxide",
  "mio 1.0.3",
@@ -20072,8 +20600,10 @@ dependencies = [
  "nix 0.29.0",
  "nix 0.30.1",
  "nom 7.1.3",
+ "num",
  "num-bigint",
  "num-bigint-dig",
+ "num-complex",
  "num-integer",
  "num-iter",
  "num-rational",
@@ -20089,6 +20619,7 @@ dependencies = [
  "phf_shared",
  "prettyplease",
  "proc-macro2",
+ "prost 0.12.6",
  "prost 0.9.0",
  "prost-types 0.9.0",
  "quote",
@@ -20096,6 +20627,7 @@ dependencies = [
  "rand 0.9.1",
  "rand_chacha 0.3.1",
  "rand_core 0.6.4",
+ "rand_distr",
  "regalloc2",
  "regex",
  "regex-automata",
@@ -20125,6 +20657,7 @@ dependencies = [
  "sqlx-macros-core",
  "sqlx-postgres",
  "sqlx-sqlite",
+ "stable_deref_trait",
  "strum 0.26.3",
  "subtle",
  "syn 1.0.109",
@@ -20158,6 +20691,7 @@ dependencies = [
  "windows-sys 0.48.0",
  "windows-sys 0.52.0",
  "windows-sys 0.59.0",
+ "windows-sys 0.60.2",
  "winnow",
  "zeroize",
  "zvariant",
@@ -21008,6 +21542,21 @@ dependencies = [
  "zstd",
 ]
 
+[[package]]
+name = "zip"
+version = "1.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9cc23c04387f4da0374be4533ad1208cbb091d5c11d070dfef13676ad6497164"
+dependencies = [
+ "arbitrary",
+ "crc32fast",
+ "crossbeam-utils",
+ "displaydoc",
+ "indexmap",
+ "num_enum",
+ "thiserror 1.0.69",
+]
+
 [[package]]
 name = "zlib-rs"
 version = "0.5.0"

Cargo.toml 🔗

@@ -52,6 +52,7 @@ members = [
     "crates/debugger_tools",
     "crates/debugger_ui",
     "crates/deepseek",
+    "crates/denoise",
     "crates/diagnostics",
     "crates/docs_preprocessor",
     "crates/edit_prediction",

crates/denoise/Cargo.toml 🔗

@@ -0,0 +1,21 @@
+[package]
+name = "denoise"
+version = "0.1.0"
+edition.workspace = true
+publish.workspace = true
+license = "GPL-3.0-or-later"
+
+[lints]
+workspace = true
+
+[dependencies]
+candle-core = { version = "0.9.1", git ="https://github.com/zed-industries/candle", branch = "9.1-patched" }
+candle-onnx = { version = "0.9.1", git ="https://github.com/zed-industries/candle", branch = "9.1-patched" }
+log.workspace = true
+
+rodio = { workspace = true, features = ["wav_output"] }
+
+rustfft = { version = "6.2.0", features = ["avx"] }
+realfft = "3.4.0"
+thiserror.workspace = true
+workspace-hack.workspace = true

crates/denoise/README.md 🔗

@@ -0,0 +1,20 @@
+Real time streaming audio denoising using a [Dual-Signal Transformation LSTM Network for Real-Time Noise Suppression](https://arxiv.org/abs/2005.07551).
+
+Trivial to build as it uses the native rust Candle crate for inference. Easy to integrate into any Rodio pipeline.
+
+```rust
+    # use rodio::{nz, source::UniformSourceIterator, wav_to_file};
+    let file = std::fs::File::open("clips_airconditioning.wav")?;
+    let decoder = rodio::Decoder::try_from(file)?;
+    let resampled = UniformSourceIterator::new(decoder, nz!(1), nz!(16_000));
+
+    let mut denoised = denoise::Denoiser::try_new(resampled)?;
+    wav_to_file(&mut denoised, "denoised.wav")?;
+    Result::Ok<(), Box<dyn std::error::Error>>
+```
+
+## Acknowledgements & License
+
+The trained models in this repo are optimized versions of the models in the [breizhn/DTLN](https://github.com/breizhn/DTLN?tab=readme-ov-file#model-conversion-and-real-time-processing-with-onnx). These are licensed under MIT.
+
+The FFT code was adapted from Datadog's [dtln-rs Repo](https://github.com/DataDog/dtln-rs/tree/main) also licensed under MIT.

crates/denoise/examples/denoise.rs 🔗

@@ -0,0 +1,11 @@
+use rodio::{nz, source::UniformSourceIterator, wav_to_file};
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    let file = std::fs::File::open("airconditioning.wav")?;
+    let decoder = rodio::Decoder::try_from(file)?;
+    let resampled = UniformSourceIterator::new(decoder, nz!(1), nz!(16_000));
+
+    let mut denoised = denoise::Denoiser::try_new(resampled)?;
+    wav_to_file(&mut denoised, "denoised.wav")?;
+    Ok(())
+}

crates/denoise/examples/enable_disable.rs 🔗

@@ -0,0 +1,23 @@
+use std::time::Duration;
+
+use rodio::Source;
+use rodio::wav_to_file;
+use rodio::{nz, source::UniformSourceIterator};
+
+fn main() -> Result<(), Box<dyn std::error::Error>> {
+    let file = std::fs::File::open("clips_airconditioning.wav")?;
+    let decoder = rodio::Decoder::try_from(file)?;
+    let resampled = UniformSourceIterator::new(decoder, nz!(1), nz!(16_000));
+
+    let mut enabled = true;
+    let denoised = denoise::Denoiser::try_new(resampled)?.periodic_access(
+        Duration::from_secs(2),
+        |denoised| {
+            enabled = !enabled;
+            denoised.set_enabled(enabled);
+        },
+    );
+
+    wav_to_file(denoised, "processed.wav")?;
+    Ok(())
+}

crates/denoise/src/engine.rs 🔗

@@ -0,0 +1,204 @@
+/// use something like https://netron.app/ to inspect the models and understand
+/// the flow
+use std::collections::HashMap;
+
+use candle_core::{Device, IndexOp, Tensor};
+use candle_onnx::onnx::ModelProto;
+use candle_onnx::prost::Message;
+use realfft::RealFftPlanner;
+use rustfft::num_complex::Complex;
+
+pub struct Engine {
+    spectral_model: ModelProto,
+    signal_model: ModelProto,
+
+    fft_planner: RealFftPlanner<f32>,
+    fft_scratch: Vec<Complex<f32>>,
+    spectrum: [Complex<f32>; FFT_OUT_SIZE],
+    signal: [f32; BLOCK_LEN],
+
+    in_magnitude: [f32; FFT_OUT_SIZE],
+    in_phase: [f32; FFT_OUT_SIZE],
+
+    spectral_memory: Tensor,
+    signal_memory: Tensor,
+
+    in_buffer: [f32; BLOCK_LEN],
+    out_buffer: [f32; BLOCK_LEN],
+}
+
+// 32 ms @ 16khz per DTLN docs: https://github.com/breizhn/DTLN
+pub const BLOCK_LEN: usize = 512;
+// 8 ms @ 16khz per DTLN docs.
+pub const BLOCK_SHIFT: usize = 128;
+pub const FFT_OUT_SIZE: usize = BLOCK_LEN / 2 + 1;
+
+impl Engine {
+    pub fn new() -> Self {
+        let mut fft_planner = RealFftPlanner::new();
+        let fft_planned = fft_planner.plan_fft_forward(BLOCK_LEN);
+        let scratch_len = fft_planned.get_scratch_len();
+        Self {
+            // Models are 1.5MB and 2.5MB respectively. Its worth the binary
+            // size increase not to have to distribute the models separately.
+            spectral_model: ModelProto::decode(
+                include_bytes!("../models/model_1_converted_simplified.onnx").as_slice(),
+            )
+            .expect("The model should decode"),
+            signal_model: ModelProto::decode(
+                include_bytes!("../models/model_2_converted_simplified.onnx").as_slice(),
+            )
+            .expect("The model should decode"),
+            fft_planner,
+            fft_scratch: vec![Complex::ZERO; scratch_len],
+            spectrum: [Complex::ZERO; FFT_OUT_SIZE],
+            signal: [0f32; BLOCK_LEN],
+
+            in_magnitude: [0f32; FFT_OUT_SIZE],
+            in_phase: [0f32; FFT_OUT_SIZE],
+
+            spectral_memory: Tensor::from_slice::<_, f32>(
+                &[0f32; 512],
+                (1, 2, BLOCK_SHIFT, 2),
+                &Device::Cpu,
+            )
+            .expect("Tensor has the correct dimensions"),
+            signal_memory: Tensor::from_slice::<_, f32>(
+                &[0f32; 512],
+                (1, 2, BLOCK_SHIFT, 2),
+                &Device::Cpu,
+            )
+            .expect("Tensor has the correct dimensions"),
+            out_buffer: [0f32; BLOCK_LEN],
+            in_buffer: [0f32; BLOCK_LEN],
+        }
+    }
+
+    /// Add a clunk of samples and get the denoised chunk 4 feeds later
+    pub fn feed(&mut self, samples: &[f32]) -> [f32; BLOCK_SHIFT] {
+        /// The name of the output node of the onnx network
+        /// [Dual-Signal Transformation LSTM Network for Real-Time Noise Suppression](https://arxiv.org/abs/2005.07551).
+        const MEMORY_OUTPUT: &'static str = "Identity_1";
+
+        debug_assert_eq!(samples.len(), BLOCK_SHIFT);
+
+        // place new samples at the end of the `in_buffer`
+        self.in_buffer.copy_within(BLOCK_SHIFT.., 0);
+        self.in_buffer[(BLOCK_LEN - BLOCK_SHIFT)..].copy_from_slice(&samples);
+
+        // run inference
+        let inputs = self.spectral_inputs();
+        let mut spectral_outputs = candle_onnx::simple_eval(&self.spectral_model, inputs)
+            .expect("The embedded file must be valid");
+        self.spectral_memory = spectral_outputs
+            .remove(MEMORY_OUTPUT)
+            .expect("The model has an output named Identity_1");
+        let inputs = self.signal_inputs(spectral_outputs);
+        let mut signal_outputs = candle_onnx::simple_eval(&self.signal_model, inputs)
+            .expect("The embedded file must be valid");
+        self.signal_memory = signal_outputs
+            .remove(MEMORY_OUTPUT)
+            .expect("The model has an output named Identity_1");
+        let model_output = model_outputs(signal_outputs);
+
+        // place processed samples at the start of the `out_buffer`
+        // shift the rest left, fill the end with zeros. Zeros are needed as
+        // the out buffer is part of the input of the network
+        self.out_buffer.copy_within(BLOCK_SHIFT.., 0);
+        self.out_buffer[BLOCK_LEN - BLOCK_SHIFT..].fill(0f32);
+        for (a, b) in self.out_buffer.iter_mut().zip(model_output) {
+            *a += b;
+        }
+
+        // samples at the front of the `out_buffer` are now denoised
+        self.out_buffer[..BLOCK_SHIFT]
+            .try_into()
+            .expect("len is correct")
+    }
+
+    fn spectral_inputs(&mut self) -> HashMap<String, Tensor> {
+        // Prepare FFT input
+        let fft = self.fft_planner.plan_fft_forward(BLOCK_LEN);
+
+        // Perform real-to-complex FFT
+        let mut fft_in = self.in_buffer;
+        fft.process_with_scratch(&mut fft_in, &mut self.spectrum, &mut self.fft_scratch)
+            .expect("The fft should run, there is enough scratch space");
+
+        // Generate magnitude and phase
+        for ((magnitude, phase), complex) in self
+            .in_magnitude
+            .iter_mut()
+            .zip(self.in_phase.iter_mut())
+            .zip(self.spectrum)
+        {
+            *magnitude = complex.norm();
+            *phase = complex.arg();
+        }
+
+        const SPECTRUM_INPUT: &str = "input_2";
+        const MEMORY_INPUT: &str = "input_3";
+        let memory_input =
+            Tensor::from_slice::<_, f32>(&self.in_magnitude, (1, 1, FFT_OUT_SIZE), &Device::Cpu)
+                .expect("the in magnitude has enough elements to fill the Tensor");
+
+        let inputs = HashMap::from([
+            (MEMORY_INPUT.to_string(), memory_input),
+            (SPECTRUM_INPUT.to_string(), self.spectral_memory.clone()),
+        ]);
+        inputs
+    }
+
+    fn signal_inputs(&mut self, outputs: HashMap<String, Tensor>) -> HashMap<String, Tensor> {
+        let magnitude_weight = model_outputs(outputs);
+
+        // Apply mask and reconstruct complex spectrum
+        let mut spectrum = [Complex::I; FFT_OUT_SIZE];
+        for i in 0..FFT_OUT_SIZE {
+            let magnitude = self.in_magnitude[i] * magnitude_weight[i];
+            let phase = self.in_phase[i];
+            let real = magnitude * phase.cos();
+            let imag = magnitude * phase.sin();
+            spectrum[i] = Complex::new(real, imag);
+        }
+
+        // Handle DC component (i = 0)
+        let magnitude = self.in_magnitude[0] * magnitude_weight[0];
+        spectrum[0] = Complex::new(magnitude, 0.0);
+
+        // Handle Nyquist component (i = N/2)
+        let magnitude = self.in_magnitude[FFT_OUT_SIZE - 1] * magnitude_weight[FFT_OUT_SIZE - 1];
+        spectrum[FFT_OUT_SIZE - 1] = Complex::new(magnitude, 0.0);
+
+        // Perform complex-to-real IFFT
+        let ifft = self.fft_planner.plan_fft_inverse(BLOCK_LEN);
+        ifft.process_with_scratch(&mut spectrum, &mut self.signal, &mut self.fft_scratch)
+            .expect("The fft should run, there is enough scratch space");
+
+        // Normalize the IFFT output
+        for real in &mut self.signal {
+            *real /= BLOCK_LEN as f32;
+        }
+
+        const SIGNAL_INPUT: &str = "input_4";
+        const SIGNAL_MEMORY: &str = "input_5";
+        let signal_input =
+            Tensor::from_slice::<_, f32>(&self.signal, (1, 1, BLOCK_LEN), &Device::Cpu).unwrap();
+
+        HashMap::from([
+            (SIGNAL_INPUT.to_string(), signal_input),
+            (SIGNAL_MEMORY.to_string(), self.signal_memory.clone()),
+        ])
+    }
+}
+
+// Both models put their outputs in the same location
+fn model_outputs(mut outputs: HashMap<String, Tensor>) -> Vec<f32> {
+    const NON_MEMORY_OUTPUT: &str = "Identity";
+    outputs
+        .remove(NON_MEMORY_OUTPUT)
+        .expect("The model has this output")
+        .i((0, 0))
+        .and_then(|tensor| tensor.to_vec1())
+        .expect("The tensor has the correct dimensions")
+}

crates/denoise/src/lib.rs 🔗

@@ -0,0 +1,270 @@
+mod engine;
+
+use core::fmt;
+use std::{collections::VecDeque, sync::mpsc, thread};
+
+pub use engine::Engine;
+use rodio::{ChannelCount, Sample, SampleRate, Source, nz};
+
+use crate::engine::BLOCK_SHIFT;
+
+const SUPPORTED_SAMPLE_RATE: SampleRate = nz!(16_000);
+const SUPPORTED_CHANNEL_COUNT: ChannelCount = nz!(1);
+
+pub struct Denoiser<S: Source> {
+    inner: S,
+    input_tx: mpsc::Sender<[Sample; BLOCK_SHIFT]>,
+    denoised_rx: mpsc::Receiver<[Sample; BLOCK_SHIFT]>,
+    ready: [Sample; BLOCK_SHIFT],
+    next: usize,
+    state: IterState,
+    // When disabled instead of reading denoised sub-blocks from the engine through
+    // `denoised_rx` we read unprocessed from this queue. This maintains the same
+    // latency so we can 'trivially' re-enable
+    queued: Queue,
+}
+
+impl<S: Source> fmt::Debug for Denoiser<S> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct("Denoiser")
+            .field("state", &self.state)
+            .finish_non_exhaustive()
+    }
+}
+
+struct Queue(VecDeque<[Sample; BLOCK_SHIFT]>);
+
+impl Queue {
+    fn new() -> Self {
+        Self(VecDeque::new())
+    }
+    fn push(&mut self, block: [Sample; BLOCK_SHIFT]) {
+        self.0.push_back(block);
+        self.0.resize(4, [0f32; BLOCK_SHIFT]);
+    }
+    fn pop(&mut self) -> [Sample; BLOCK_SHIFT] {
+        debug_assert!(self.0.len() == 4);
+        self.0.pop_front().expect(
+            "There is no State where the queue is popped while there are less then 4 entries",
+        )
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
+pub enum IterState {
+    Enabled,
+    StartingMidAudio { fed_to_denoiser: usize },
+    Disabled,
+    Startup { enabled: bool },
+}
+
+#[derive(Debug, thiserror::Error)]
+pub enum DenoiserError {
+    #[error("This denoiser only works on sources with samplerate 16000")]
+    UnsupportedSampleRate,
+    #[error("This denoiser only works on mono sources (1 channel)")]
+    UnsupportedChannelCount,
+}
+
+// todo dvdsk needs constant source upstream in rodio
+impl<S: Source> Denoiser<S> {
+    pub fn try_new(source: S) -> Result<Self, DenoiserError> {
+        if source.sample_rate() != SUPPORTED_SAMPLE_RATE {
+            return Err(DenoiserError::UnsupportedSampleRate);
+        }
+        if source.channels() != SUPPORTED_CHANNEL_COUNT {
+            return Err(DenoiserError::UnsupportedChannelCount);
+        }
+
+        let (input_tx, input_rx) = mpsc::channel();
+        let (denoised_tx, denoised_rx) = mpsc::channel();
+
+        thread::spawn(move || {
+            run_neural_denoiser(denoised_tx, input_rx);
+        });
+
+        Ok(Self {
+            inner: source,
+            input_tx,
+            denoised_rx,
+            ready: [0.0; BLOCK_SHIFT],
+            state: IterState::Startup { enabled: true },
+            next: BLOCK_SHIFT,
+            queued: Queue::new(),
+        })
+    }
+
+    pub fn set_enabled(&mut self, enabled: bool) {
+        self.state = match (enabled, self.state) {
+            (false, IterState::StartingMidAudio { .. }) | (false, IterState::Enabled) => {
+                IterState::Disabled
+            }
+            (false, IterState::Startup { enabled: true }) => IterState::Startup { enabled: false },
+            (true, IterState::Disabled) => IterState::StartingMidAudio { fed_to_denoiser: 0 },
+            (_, state) => state,
+        };
+    }
+
+    fn feed(&self, sub_block: [f32; BLOCK_SHIFT]) {
+        self.input_tx.send(sub_block).unwrap();
+    }
+}
+
+fn run_neural_denoiser(
+    denoised_tx: mpsc::Sender<[f32; BLOCK_SHIFT]>,
+    input_rx: mpsc::Receiver<[f32; BLOCK_SHIFT]>,
+) {
+    let mut engine = Engine::new();
+    loop {
+        let Ok(sub_block) = input_rx.recv() else {
+            // tx must have dropped, stop thread
+            break;
+        };
+
+        let denoised_sub_block = engine.feed(&sub_block);
+        if denoised_tx.send(denoised_sub_block).is_err() {
+            break;
+        }
+    }
+}
+
+impl<S: Source> Source for Denoiser<S> {
+    fn current_span_len(&self) -> Option<usize> {
+        self.inner.current_span_len()
+    }
+
+    fn channels(&self) -> rodio::ChannelCount {
+        self.inner.channels()
+    }
+
+    fn sample_rate(&self) -> rodio::SampleRate {
+        self.inner.sample_rate()
+    }
+
+    fn total_duration(&self) -> Option<std::time::Duration> {
+        self.inner.total_duration()
+    }
+}
+
+impl<S: Source> Iterator for Denoiser<S> {
+    type Item = Sample;
+
+    #[inline]
+    fn next(&mut self) -> Option<Self::Item> {
+        self.next += 1;
+        if self.next < self.ready.len() {
+            let sample = self.ready[self.next];
+            return Some(sample);
+        }
+
+        // This is a separate function to prevent it from being inlined
+        // as this code only runs once every 128 samples
+        self.prepare_next_ready()
+            .inspect_err(|_| {
+                log::error!("Denoise engine crashed");
+            })
+            .ok()
+            .flatten()
+    }
+}
+
+#[derive(Debug, thiserror::Error)]
+#[error("Could not send or receive from denoise thread. It must have crashed")]
+struct DenoiseEngineCrashed;
+
+impl<S: Source> Denoiser<S> {
+    #[cold]
+    fn prepare_next_ready(&mut self) -> Result<Option<f32>, DenoiseEngineCrashed> {
+        self.state = match self.state {
+            IterState::Startup { enabled } => {
+                // guaranteed to be coming from silence
+                for _ in 0..3 {
+                    let Some(sub_block) = read_sub_block(&mut self.inner) else {
+                        return Ok(None);
+                    };
+                    self.queued.push(sub_block);
+                    self.input_tx
+                        .send(sub_block)
+                        .map_err(|_| DenoiseEngineCrashed)?;
+                }
+                let Some(sub_block) = read_sub_block(&mut self.inner) else {
+                    return Ok(None);
+                };
+                self.queued.push(sub_block);
+                self.input_tx
+                    .send(sub_block)
+                    .map_err(|_| DenoiseEngineCrashed)?;
+                // throw out old blocks that are denoised silence
+                let _ = self.denoised_rx.iter().take(3).count();
+                self.ready = self.denoised_rx.recv().map_err(|_| DenoiseEngineCrashed)?;
+
+                let Some(sub_block) = read_sub_block(&mut self.inner) else {
+                    return Ok(None);
+                };
+                self.queued.push(sub_block);
+                self.feed(sub_block);
+
+                if enabled {
+                    IterState::Enabled
+                } else {
+                    IterState::Disabled
+                }
+            }
+            IterState::Enabled => {
+                self.ready = self.denoised_rx.recv().map_err(|_| DenoiseEngineCrashed)?;
+                let Some(sub_block) = read_sub_block(&mut self.inner) else {
+                    return Ok(None);
+                };
+                self.queued.push(sub_block);
+                self.input_tx
+                    .send(sub_block)
+                    .map_err(|_| DenoiseEngineCrashed)?;
+                IterState::Enabled
+            }
+            IterState::Disabled => {
+                // Need to maintain the same 512 samples delay such that
+                // we can re-enable at any point.
+                self.ready = self.queued.pop();
+                let Some(sub_block) = read_sub_block(&mut self.inner) else {
+                    return Ok(None);
+                };
+                self.queued.push(sub_block);
+                IterState::Disabled
+            }
+            IterState::StartingMidAudio {
+                fed_to_denoiser: mut sub_blocks_fed,
+            } => {
+                self.ready = self.queued.pop();
+                let Some(sub_block) = read_sub_block(&mut self.inner) else {
+                    return Ok(None);
+                };
+                self.queued.push(sub_block);
+                self.input_tx
+                    .send(sub_block)
+                    .map_err(|_| DenoiseEngineCrashed)?;
+                sub_blocks_fed += 1;
+                if sub_blocks_fed > 4 {
+                    // throw out partially denoised blocks,
+                    // next will be correctly denoised
+                    let _ = self.denoised_rx.iter().take(3).count();
+                    IterState::Enabled
+                } else {
+                    IterState::StartingMidAudio {
+                        fed_to_denoiser: sub_blocks_fed,
+                    }
+                }
+            }
+        };
+
+        self.next = 0;
+        Ok(Some(self.ready[0]))
+    }
+}
+
+fn read_sub_block(s: &mut impl Source) -> Option<[f32; BLOCK_SHIFT]> {
+    let mut res = [0f32; BLOCK_SHIFT];
+    for sample in &mut res {
+        *sample = s.next()?;
+    }
+    Some(res)
+}

tooling/workspace-hack/Cargo.toml 🔗

@@ -67,7 +67,7 @@ futures-sink = { version = "0.3" }
 futures-task = { version = "0.3", default-features = false, features = ["std"] }
 futures-util = { version = "0.3", features = ["channel", "io-compat", "sink"] }
 getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-features = false, features = ["std"] }
-half = { version = "2", features = ["num-traits"] }
+half = { version = "2", features = ["bytemuck", "num-traits", "rand_distr", "use-intrinsics"] }
 handlebars = { version = "4", features = ["rust-embed"] }
 hashbrown-3575ec1268b04181 = { package = "hashbrown", version = "0.15", features = ["serde"] }
 hashbrown-582f2526e08bb6a0 = { package = "hashbrown", version = "0.14", features = ["raw"] }
@@ -84,10 +84,12 @@ lyon = { version = "1", default-features = false, features = ["extra"] }
 lyon_path = { version = "1" }
 md-5 = { version = "0.10" }
 memchr = { version = "2" }
+memmap2 = { version = "0.9", default-features = false, features = ["stable_deref_trait"] }
 mime_guess = { version = "2" }
 miniz_oxide = { version = "0.8", features = ["simd"] }
 nom = { version = "7" }
 num-bigint = { version = "0.4" }
+num-complex = { version = "0.4", features = ["bytemuck"] }
 num-integer = { version = "0.1", features = ["i128"] }
 num-iter = { version = "0.1", default-features = false, features = ["i128", "std"] }
 num-rational = { version = "0.4", features = ["num-bigint-std"] }
@@ -96,11 +98,12 @@ once_cell = { version = "1" }
 percent-encoding = { version = "2" }
 phf = { version = "0.11", features = ["macros"] }
 phf_shared = { version = "0.11" }
-prost = { version = "0.9" }
+prost-274715c4dabd11b0 = { package = "prost", version = "0.9" }
 prost-types = { version = "0.9" }
 rand-c38e5c1d305a1b54 = { package = "rand", version = "0.8", features = ["small_rng"] }
 rand_chacha = { version = "0.3" }
 rand_core = { version = "0.6", default-features = false, features = ["std"] }
+rand_distr = { version = "0.5" }
 regalloc2 = { version = "0.11", features = ["checker", "enable-serde"] }
 regex = { version = "1" }
 regex-automata = { version = "0.4" }
@@ -123,6 +126,7 @@ spin = { version = "0.9" }
 sqlx = { version = "0.8", features = ["bigdecimal", "chrono", "postgres", "runtime-tokio-rustls", "rust_decimal", "sqlite", "time", "uuid"] }
 sqlx-postgres = { version = "0.8", default-features = false, features = ["any", "bigdecimal", "chrono", "json", "migrate", "offline", "rust_decimal", "time", "uuid"] }
 sqlx-sqlite = { version = "0.8", default-features = false, features = ["any", "bundled", "chrono", "json", "migrate", "offline", "time", "uuid"] }
+stable_deref_trait = { version = "1" }
 strum = { version = "0.26", features = ["derive"] }
 subtle = { version = "2" }
 thiserror = { version = "2" }
@@ -130,6 +134,7 @@ time = { version = "0.3", features = ["local-offset", "macros", "serde-well-know
 tokio = { version = "1", features = ["full"] }
 tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"] }
 tokio-util = { version = "0.7", features = ["codec", "compat", "io"] }
+toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 toml_edit = { version = "0.22", features = ["serde"] }
 tracing = { version = "0.1", features = ["log"] }
 tracing-core = { version = "0.1" }
@@ -198,7 +203,7 @@ futures-sink = { version = "0.3" }
 futures-task = { version = "0.3", default-features = false, features = ["std"] }
 futures-util = { version = "0.3", features = ["channel", "io-compat", "sink"] }
 getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-features = false, features = ["std"] }
-half = { version = "2", features = ["num-traits"] }
+half = { version = "2", features = ["bytemuck", "num-traits", "rand_distr", "use-intrinsics"] }
 handlebars = { version = "4", features = ["rust-embed"] }
 hashbrown-3575ec1268b04181 = { package = "hashbrown", version = "0.15", features = ["serde"] }
 hashbrown-582f2526e08bb6a0 = { package = "hashbrown", version = "0.14", features = ["raw"] }
@@ -217,10 +222,12 @@ lyon = { version = "1", default-features = false, features = ["extra"] }
 lyon_path = { version = "1" }
 md-5 = { version = "0.10" }
 memchr = { version = "2" }
+memmap2 = { version = "0.9", default-features = false, features = ["stable_deref_trait"] }
 mime_guess = { version = "2" }
 miniz_oxide = { version = "0.8", features = ["simd"] }
 nom = { version = "7" }
 num-bigint = { version = "0.4" }
+num-complex = { version = "0.4", features = ["bytemuck"] }
 num-integer = { version = "0.1", features = ["i128"] }
 num-iter = { version = "0.1", default-features = false, features = ["i128", "std"] }
 num-rational = { version = "0.4", features = ["num-bigint-std"] }
@@ -231,12 +238,13 @@ phf = { version = "0.11", features = ["macros"] }
 phf_shared = { version = "0.11" }
 prettyplease = { version = "0.2", default-features = false, features = ["verbatim"] }
 proc-macro2 = { version = "1" }
-prost = { version = "0.9" }
+prost-274715c4dabd11b0 = { package = "prost", version = "0.9" }
 prost-types = { version = "0.9" }
 quote = { version = "1" }
 rand-c38e5c1d305a1b54 = { package = "rand", version = "0.8", features = ["small_rng"] }
 rand_chacha = { version = "0.3" }
 rand_core = { version = "0.6", default-features = false, features = ["std"] }
+rand_distr = { version = "0.5" }
 regalloc2 = { version = "0.11", features = ["checker", "enable-serde"] }
 regex = { version = "1" }
 regex-automata = { version = "0.4" }
@@ -261,6 +269,7 @@ sqlx-macros = { version = "0.8", features = ["_rt-tokio", "_tls-rustls-ring-webp
 sqlx-macros-core = { version = "0.8", features = ["_rt-tokio", "_tls-rustls-ring-webpki", "bigdecimal", "chrono", "derive", "json", "macros", "migrate", "postgres", "rust_decimal", "sqlite", "time", "uuid"] }
 sqlx-postgres = { version = "0.8", default-features = false, features = ["any", "bigdecimal", "chrono", "json", "migrate", "offline", "rust_decimal", "time", "uuid"] }
 sqlx-sqlite = { version = "0.8", default-features = false, features = ["any", "bundled", "chrono", "json", "migrate", "offline", "time", "uuid"] }
+stable_deref_trait = { version = "1" }
 strum = { version = "0.26", features = ["derive"] }
 subtle = { version = "2" }
 syn-dff4ba8e3ae991db = { package = "syn", version = "1", features = ["extra-traits", "full"] }
@@ -271,6 +280,7 @@ time-macros = { version = "0.2", default-features = false, features = ["formatti
 tokio = { version = "1", features = ["full"] }
 tokio-rustls = { version = "0.26", default-features = false, features = ["tls12"] }
 tokio-util = { version = "0.7", features = ["codec", "compat", "io"] }
+toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 toml_edit = { version = "0.22", features = ["serde"] }
 tracing = { version = "0.1", features = ["log"] }
 tracing-core = { version = "0.1" }
@@ -293,15 +303,16 @@ foldhash = { version = "0.1", default-features = false, features = ["std"] }
 getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] }
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
 naga = { version = "25", features = ["msl-out", "wgsl-in"] }
 nix-b73a96c0a5f6a7d9 = { package = "nix", version = "0.29", features = ["fs", "pthread", "signal", "user"] }
+num = { version = "0.4" }
 objc2 = { version = "0.6" }
 objc2-core-foundation = { version = "0.3", default-features = false, features = ["CFArray", "CFCGTypes", "CFData", "CFDate", "CFDictionary", "CFRunLoop", "CFString", "CFURL", "objc2", "std"] }
 objc2-foundation = { version = "0.3", default-features = false, features = ["NSArray", "NSAttributedString", "NSBundle", "NSCoder", "NSData", "NSDate", "NSDictionary", "NSEnumerator", "NSError", "NSGeometry", "NSNotification", "NSNull", "NSObjCRuntime", "NSObject", "NSProcessInfo", "NSRange", "NSRunLoop", "NSString", "NSURL", "NSUndoManager", "NSValue", "objc2-core-foundation", "std"] }
 objc2-metal = { version = "0.3" }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
 rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
@@ -322,16 +333,18 @@ foldhash = { version = "0.1", default-features = false, features = ["std"] }
 getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] }
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
+itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
 naga = { version = "25", features = ["msl-out", "wgsl-in"] }
 nix-b73a96c0a5f6a7d9 = { package = "nix", version = "0.29", features = ["fs", "pthread", "signal", "user"] }
+num = { version = "0.4" }
 objc2 = { version = "0.6" }
 objc2-core-foundation = { version = "0.3", default-features = false, features = ["CFArray", "CFCGTypes", "CFData", "CFDate", "CFDictionary", "CFRunLoop", "CFString", "CFURL", "objc2", "std"] }
 objc2-foundation = { version = "0.3", default-features = false, features = ["NSArray", "NSAttributedString", "NSBundle", "NSCoder", "NSData", "NSDate", "NSDictionary", "NSEnumerator", "NSError", "NSGeometry", "NSNotification", "NSNull", "NSObjCRuntime", "NSObject", "NSProcessInfo", "NSRange", "NSRunLoop", "NSString", "NSURL", "NSUndoManager", "NSValue", "objc2-core-foundation", "std"] }
 objc2-metal = { version = "0.3" }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
 rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
@@ -352,15 +365,16 @@ foldhash = { version = "0.1", default-features = false, features = ["std"] }
 getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] }
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
 naga = { version = "25", features = ["msl-out", "wgsl-in"] }
 nix-b73a96c0a5f6a7d9 = { package = "nix", version = "0.29", features = ["fs", "pthread", "signal", "user"] }
+num = { version = "0.4" }
 objc2 = { version = "0.6" }
 objc2-core-foundation = { version = "0.3", default-features = false, features = ["CFArray", "CFCGTypes", "CFData", "CFDate", "CFDictionary", "CFRunLoop", "CFString", "CFURL", "objc2", "std"] }
 objc2-foundation = { version = "0.3", default-features = false, features = ["NSArray", "NSAttributedString", "NSBundle", "NSCoder", "NSData", "NSDate", "NSDictionary", "NSEnumerator", "NSError", "NSGeometry", "NSNotification", "NSNull", "NSObjCRuntime", "NSObject", "NSProcessInfo", "NSRange", "NSRunLoop", "NSString", "NSURL", "NSUndoManager", "NSValue", "objc2-core-foundation", "std"] }
 objc2-metal = { version = "0.3" }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
 rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
@@ -381,16 +395,18 @@ foldhash = { version = "0.1", default-features = false, features = ["std"] }
 getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] }
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
+itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
 naga = { version = "25", features = ["msl-out", "wgsl-in"] }
 nix-b73a96c0a5f6a7d9 = { package = "nix", version = "0.29", features = ["fs", "pthread", "signal", "user"] }
+num = { version = "0.4" }
 objc2 = { version = "0.6" }
 objc2-core-foundation = { version = "0.3", default-features = false, features = ["CFArray", "CFCGTypes", "CFData", "CFDate", "CFDictionary", "CFRunLoop", "CFString", "CFURL", "objc2", "std"] }
 objc2-foundation = { version = "0.3", default-features = false, features = ["NSArray", "NSAttributedString", "NSBundle", "NSCoder", "NSData", "NSDate", "NSDictionary", "NSEnumerator", "NSError", "NSGeometry", "NSNotification", "NSNull", "NSObjCRuntime", "NSObject", "NSProcessInfo", "NSRange", "NSRunLoop", "NSString", "NSURL", "NSUndoManager", "NSValue", "objc2-core-foundation", "std"] }
 objc2-metal = { version = "0.3" }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "termios", "time"] }
 rustix-dff4ba8e3ae991db = { package = "rustix", version = "1", default-features = false, features = ["process", "termios", "time"] }
@@ -417,7 +433,6 @@ getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-f
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
 inout = { version = "0.1", default-features = false, features = ["block-padding"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
 linux-raw-sys-274715c4dabd11b0 = { package = "linux-raw-sys", version = "0.9", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"] }
 linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "system", "xdp"] }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
@@ -429,6 +444,7 @@ nix-fa1f6196edfd7249 = { package = "nix", version = "0.30", features = ["fs", "s
 num-bigint-dig = { version = "0.8", features = ["i128", "prime", "zeroize"] }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 quote = { version = "1" }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
@@ -440,7 +456,6 @@ sync_wrapper = { version = "1", default-features = false, features = ["futures"]
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
 tokio-socks = { version = "0.5", features = ["futures-io"] }
 tokio-stream = { version = "0.1", features = ["fs"] }
-toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 tower = { version = "0.5", default-features = false, features = ["timeout", "util"] }
 zeroize = { version = "1", features = ["zeroize_derive"] }
 zvariant = { version = "5", features = ["enumflags2", "gvariant", "url"] }
@@ -459,7 +474,7 @@ getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-f
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
 inout = { version = "0.1", default-features = false, features = ["block-padding"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
+itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" }
 linux-raw-sys-274715c4dabd11b0 = { package = "linux-raw-sys", version = "0.9", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"] }
 linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "system", "xdp"] }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
@@ -471,6 +486,7 @@ nix-fa1f6196edfd7249 = { package = "nix", version = "0.30", features = ["fs", "s
 num-bigint-dig = { version = "0.8", features = ["i128", "prime", "zeroize"] }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
@@ -480,7 +496,6 @@ sync_wrapper = { version = "1", default-features = false, features = ["futures"]
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
 tokio-socks = { version = "0.5", features = ["futures-io"] }
 tokio-stream = { version = "0.1", features = ["fs"] }
-toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 tower = { version = "0.5", default-features = false, features = ["timeout", "util"] }
 zeroize = { version = "1", features = ["zeroize_derive"] }
 zvariant = { version = "5", features = ["enumflags2", "gvariant", "url"] }
@@ -499,7 +514,6 @@ getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-f
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
 inout = { version = "0.1", default-features = false, features = ["block-padding"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
 linux-raw-sys-274715c4dabd11b0 = { package = "linux-raw-sys", version = "0.9", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"] }
 linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "system", "xdp"] }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
@@ -511,6 +525,7 @@ nix-fa1f6196edfd7249 = { package = "nix", version = "0.30", features = ["fs", "s
 num-bigint-dig = { version = "0.8", features = ["i128", "prime", "zeroize"] }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 quote = { version = "1" }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
@@ -522,7 +537,6 @@ sync_wrapper = { version = "1", default-features = false, features = ["futures"]
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
 tokio-socks = { version = "0.5", features = ["futures-io"] }
 tokio-stream = { version = "0.1", features = ["fs"] }
-toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 tower = { version = "0.5", default-features = false, features = ["timeout", "util"] }
 zeroize = { version = "1", features = ["zeroize_derive"] }
 zvariant = { version = "5", features = ["enumflags2", "gvariant", "url"] }
@@ -541,7 +555,7 @@ getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-f
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
 inout = { version = "0.1", default-features = false, features = ["block-padding"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
+itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" }
 linux-raw-sys-274715c4dabd11b0 = { package = "linux-raw-sys", version = "0.9", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"] }
 linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "system", "xdp"] }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
@@ -553,6 +567,7 @@ nix-fa1f6196edfd7249 = { package = "nix", version = "0.30", features = ["fs", "s
 num-bigint-dig = { version = "0.8", features = ["i128", "prime", "zeroize"] }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
@@ -562,7 +577,6 @@ sync_wrapper = { version = "1", default-features = false, features = ["futures"]
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
 tokio-socks = { version = "0.5", features = ["futures-io"] }
 tokio-stream = { version = "0.1", features = ["fs"] }
-toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 tower = { version = "0.5", default-features = false, features = ["timeout", "util"] }
 zeroize = { version = "1", features = ["zeroize_derive"] }
 zvariant = { version = "5", features = ["enumflags2", "gvariant", "url"] }
@@ -574,8 +588,9 @@ foldhash = { version = "0.1", default-features = false, features = ["std"] }
 getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] }
 getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-features = false, features = ["js", "rdrand"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
+num = { version = "0.4" }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "fs", "net"] }
 scopeguard = { version = "1" }
@@ -587,7 +602,8 @@ tower = { version = "0.5", default-features = false, features = ["timeout", "uti
 winapi = { version = "0.3", default-features = false, features = ["cfg", "commapi", "consoleapi", "evntrace", "fileapi", "handleapi", "impl-debug", "impl-default", "in6addr", "inaddr", "ioapiset", "knownfolders", "minwinbase", "minwindef", "namedpipeapi", "ntsecapi", "objbase", "processenv", "processthreadsapi", "shlobj", "std", "synchapi", "sysinfoapi", "timezoneapi", "winbase", "windef", "winerror", "winioctl", "winnt", "winreg", "winsock2", "winuser"] }
 windows-core = { version = "0.61" }
 windows-numerics = { version = "0.2" }
-windows-sys-73dcd821b1037cfd = { package = "windows-sys", version = "0.59", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Win32_Globalization", "Win32_NetworkManagement_IpHelper", "Win32_Networking_WinSock", "Win32_Security_Authentication_Identity", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_Ioctl", "Win32_System_Kernel", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Performance", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_Time", "Win32_System_WindowsProgramming", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
+windows-sys-4db8c43aad08e7ae = { package = "windows-sys", version = "0.60", features = ["Win32_Globalization", "Win32_System_Com", "Win32_UI_Shell"] }
+windows-sys-73dcd821b1037cfd = { package = "windows-sys", version = "0.59", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Win32_NetworkManagement_IpHelper", "Win32_Networking_WinSock", "Win32_Security_Authentication_Identity", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_Ioctl", "Win32_System_Kernel", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Performance", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_Time", "Win32_System_WindowsProgramming", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
 windows-sys-b21d60becc0929df = { package = "windows-sys", version = "0.52", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Wdk_System_IO", "Win32_Foundation", "Win32_Networking_WinSock", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming"] }
 windows-sys-c8eced492e86ede7 = { package = "windows-sys", version = "0.48", features = ["Win32_Foundation", "Win32_Globalization", "Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_Threading", "Win32_System_Time", "Win32_System_WindowsProgramming", "Win32_UI_Shell"] }
 
@@ -598,9 +614,11 @@ foldhash = { version = "0.1", default-features = false, features = ["std"] }
 getrandom-468e82937335b1c9 = { package = "getrandom", version = "0.3", default-features = false, features = ["std"] }
 getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-features = false, features = ["js", "rdrand"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
+itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
+num = { version = "0.4" }
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "fs", "net"] }
 scopeguard = { version = "1" }
@@ -612,7 +630,8 @@ tower = { version = "0.5", default-features = false, features = ["timeout", "uti
 winapi = { version = "0.3", default-features = false, features = ["cfg", "commapi", "consoleapi", "evntrace", "fileapi", "handleapi", "impl-debug", "impl-default", "in6addr", "inaddr", "ioapiset", "knownfolders", "minwinbase", "minwindef", "namedpipeapi", "ntsecapi", "objbase", "processenv", "processthreadsapi", "shlobj", "std", "synchapi", "sysinfoapi", "timezoneapi", "winbase", "windef", "winerror", "winioctl", "winnt", "winreg", "winsock2", "winuser"] }
 windows-core = { version = "0.61" }
 windows-numerics = { version = "0.2" }
-windows-sys-73dcd821b1037cfd = { package = "windows-sys", version = "0.59", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Win32_Globalization", "Win32_NetworkManagement_IpHelper", "Win32_Networking_WinSock", "Win32_Security_Authentication_Identity", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_Ioctl", "Win32_System_Kernel", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Performance", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_Time", "Win32_System_WindowsProgramming", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
+windows-sys-4db8c43aad08e7ae = { package = "windows-sys", version = "0.60", features = ["Win32_Globalization", "Win32_System_Com", "Win32_UI_Shell"] }
+windows-sys-73dcd821b1037cfd = { package = "windows-sys", version = "0.59", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Win32_NetworkManagement_IpHelper", "Win32_Networking_WinSock", "Win32_Security_Authentication_Identity", "Win32_Security_Credentials", "Win32_Security_Cryptography", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Console", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_Ioctl", "Win32_System_Kernel", "Win32_System_LibraryLoader", "Win32_System_Memory", "Win32_System_Performance", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_SystemInformation", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_Time", "Win32_System_WindowsProgramming", "Win32_UI_Input_KeyboardAndMouse", "Win32_UI_Shell", "Win32_UI_WindowsAndMessaging"] }
 windows-sys-b21d60becc0929df = { package = "windows-sys", version = "0.52", features = ["Wdk_Foundation", "Wdk_Storage_FileSystem", "Wdk_System_IO", "Win32_Foundation", "Win32_Networking_WinSock", "Win32_Security_Authorization", "Win32_Storage_FileSystem", "Win32_System_Console", "Win32_System_IO", "Win32_System_Memory", "Win32_System_Pipes", "Win32_System_SystemServices", "Win32_System_Threading", "Win32_System_WindowsProgramming"] }
 windows-sys-c8eced492e86ede7 = { package = "windows-sys", version = "0.48", features = ["Win32_Foundation", "Win32_Globalization", "Win32_Networking_WinSock", "Win32_Security", "Win32_Storage_FileSystem", "Win32_System_Com", "Win32_System_Diagnostics_Debug", "Win32_System_IO", "Win32_System_Pipes", "Win32_System_Registry", "Win32_System_Threading", "Win32_System_Time", "Win32_System_WindowsProgramming", "Win32_UI_Shell"] }
 
@@ -630,7 +649,6 @@ getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-f
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
 inout = { version = "0.1", default-features = false, features = ["block-padding"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
 linux-raw-sys-274715c4dabd11b0 = { package = "linux-raw-sys", version = "0.9", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"] }
 linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "system", "xdp"] }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
@@ -642,6 +660,7 @@ nix-fa1f6196edfd7249 = { package = "nix", version = "0.30", features = ["fs", "s
 num-bigint-dig = { version = "0.8", features = ["i128", "prime", "zeroize"] }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 quote = { version = "1" }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
@@ -653,7 +672,6 @@ sync_wrapper = { version = "1", default-features = false, features = ["futures"]
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
 tokio-socks = { version = "0.5", features = ["futures-io"] }
 tokio-stream = { version = "0.1", features = ["fs"] }
-toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 tower = { version = "0.5", default-features = false, features = ["timeout", "util"] }
 zeroize = { version = "1", features = ["zeroize_derive"] }
 zvariant = { version = "5", features = ["enumflags2", "gvariant", "url"] }
@@ -672,7 +690,7 @@ getrandom-6f8ce4dd05d13bba = { package = "getrandom", version = "0.2", default-f
 gimli = { version = "0.31", default-features = false, features = ["read", "std", "write"] }
 hyper-rustls = { version = "0.27", default-features = false, features = ["http1", "http2", "native-tokio", "ring", "tls12"] }
 inout = { version = "0.1", default-features = false, features = ["block-padding"] }
-itertools-5ef9efb8ec2df382 = { package = "itertools", version = "0.12" }
+itertools-a6292c17cd707f01 = { package = "itertools", version = "0.11" }
 linux-raw-sys-274715c4dabd11b0 = { package = "linux-raw-sys", version = "0.9", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "xdp"] }
 linux-raw-sys-9fbad63c4bcf4a8f = { package = "linux-raw-sys", version = "0.4", default-features = false, features = ["elf", "errno", "general", "if_ether", "ioctl", "net", "netlink", "no_std", "prctl", "system", "xdp"] }
 livekit-runtime = { git = "https://github.com/zed-industries/livekit-rust-sdks", rev = "5f04705ac3f356350ae31534ffbc476abc9ea83d" }
@@ -684,6 +702,7 @@ nix-fa1f6196edfd7249 = { package = "nix", version = "0.30", features = ["fs", "s
 num-bigint-dig = { version = "0.8", features = ["i128", "prime", "zeroize"] }
 object = { version = "0.36", default-features = false, features = ["archive", "read_core", "unaligned", "write"] }
 proc-macro2 = { version = "1", default-features = false, features = ["span-locations"] }
+prost-5ef9efb8ec2df382 = { package = "prost", version = "0.12", features = ["prost-derive"] }
 rand-274715c4dabd11b0 = { package = "rand", version = "0.9" }
 ring = { version = "0.17", features = ["std"] }
 rustix-d585fab2519d2d1 = { package = "rustix", version = "0.38", features = ["event", "mm", "net", "param", "pipe", "process", "pty", "shm", "stdio", "system", "termios", "time"] }
@@ -693,7 +712,6 @@ sync_wrapper = { version = "1", default-features = false, features = ["futures"]
 tokio-rustls = { version = "0.26", default-features = false, features = ["logging", "ring"] }
 tokio-socks = { version = "0.5", features = ["futures-io"] }
 tokio-stream = { version = "0.1", features = ["fs"] }
-toml_datetime = { version = "0.6", default-features = false, features = ["serde"] }
 tower = { version = "0.5", default-features = false, features = ["timeout", "util"] }
 zeroize = { version = "1", features = ["zeroize_derive"] }
 zvariant = { version = "5", features = ["enumflags2", "gvariant", "url"] }