Add a default noise floor. (#13)
Build Mumble Web 2 / linux_build (push) Successful in 1m29s
Build Mumble Web 2 / android_build (push) Has been cancelled
Build Mumble Web 2 / windows_build (push) Has been cancelled

(Turns out not) Pretty simple, if the average amplitude is under a certain value clear
out the buffer! The value I chose (.001) was an arbitrary value I got
from printf debugging. I was able to show that this worked pretty well
on the desktop session. Hopefully we'll add this to the settings page at
some point.

Once the app has been under that threshold for more than 200ms, we stop transmitting and send a terminator packet.

Reviewed-on: #13
Reviewed-by: restitux <restitux@ohea.xyz>
This commit was merged in pull request #13.
This commit is contained in:
2026-01-19 22:07:06 +00:00
parent c8119d0efa
commit 65883917b0
5 changed files with 249 additions and 432 deletions
Generated
+122 -403
View File
@@ -188,50 +188,6 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "ashpd"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df"
dependencies = [
"enumflags2",
"futures-channel",
"futures-util",
"rand 0.9.2",
"raw-window-handle 0.6.2",
"serde",
"serde_repr",
"tokio",
"url",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"zbus",
]
[[package]]
name = "async-broadcast"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532"
dependencies = [
"event-listener",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-recursion"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
]
[[package]] [[package]]
name = "async-stream" name = "async-stream"
version = "0.3.6" version = "0.3.6"
@@ -898,15 +854,6 @@ dependencies = [
"static_assertions", "static_assertions",
] ]
[[package]]
name = "concurrent-queue"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973"
dependencies = [
"crossbeam-utils",
]
[[package]] [[package]]
name = "console_error_panic_hook" name = "console_error_panic_hook"
version = "0.1.7" version = "0.1.7"
@@ -949,7 +896,17 @@ version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ad7154afa56de2f290e3c82c2c6dc4f5b282b6870903f56ef3509aba95866edc" checksum = "ad7154afa56de2f290e3c82c2c6dc4f5b282b6870903f56ef3509aba95866edc"
dependencies = [ dependencies = [
"const-serialize-macro", "const-serialize-macro 0.7.2",
]
[[package]]
name = "const-serialize"
version = "0.8.0-alpha.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e42cd5aabba86f128b3763da1fec1491c0f728ce99245062cd49b6f9e6d235b"
dependencies = [
"const-serialize 0.7.2",
"const-serialize-macro 0.8.0-alpha.0",
"serde", "serde",
] ]
@@ -964,6 +921,17 @@ dependencies = [
"syn 2.0.108", "syn 2.0.108",
] ]
[[package]]
name = "const-serialize-macro"
version = "0.8.0-alpha.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42571ed01eb46d2e1adcf99c8ca576f081e46f2623d13500eba70d1d99a4c439"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.108",
]
[[package]] [[package]]
name = "const-str" name = "const-str"
version = "0.7.0" version = "0.7.0"
@@ -1510,9 +1478,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus" name = "dioxus"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a115f9dbe5900c6044ee6a791e1b160c29989c6a8721eec099e01a964e5dae4" checksum = "92b583b48ac77158495e6678fe3a2b5954fc8866fc04cb9695dd146e88bc329d"
dependencies = [ dependencies = [
"dioxus-asset-resolver", "dioxus-asset-resolver",
"dioxus-cli-config", "dioxus-cli-config",
@@ -1538,9 +1506,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-asset-resolver" name = "dioxus-asset-resolver"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6851ae49ba3988f1b77f6ef826eb142e811602129841c24bf5a4e103708d9844" checksum = "c0161af1d3cfc8ff31503ff1b7ee0068c97771fc38d0cc6566e23483142ddf4f"
dependencies = [ dependencies = [
"dioxus-cli-config", "dioxus-cli-config",
"http", "http",
@@ -1559,18 +1527,18 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-cli-config" name = "dioxus-cli-config"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59e9d9da2e7334fdae5d77e3989207aa549062f74ff1ca2171393bbdd7fda90" checksum = "ccd67ab405e1915a47df9769cd5408545d1b559d5c01ce7a0f442caef520d1f3"
dependencies = [ dependencies = [
"wasm-bindgen", "wasm-bindgen",
] ]
[[package]] [[package]]
name = "dioxus-config-macro" name = "dioxus-config-macro"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd56be5ea6c9f416b25e9e3adc910c02127be75b6d1ecd567661f31920b27ba" checksum = "f040ec7c41aa5428283f56bb0670afba9631bfe3ffd885f4814807f12c8c9d91"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1578,15 +1546,15 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-config-macros" name = "dioxus-config-macros"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c49327465c2d434d00fb4c86bd35ae72155b479622e09352b950d9ab4807bf23" checksum = "10c41b47b55a433b61f7c12327c85ba650572bacbcc42c342ba2e87a57975264"
[[package]] [[package]]
name = "dioxus-core" name = "dioxus-core"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7400cbd21a98e585a13f8c29574da9b8afb2fd343f712618042b6c71761f0933" checksum = "b389b0e3cc01c7da292ad9b884b088835fdd1671d45fbd2f737506152b22eef0"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"const_format", "const_format",
@@ -1606,9 +1574,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-core-macro" name = "dioxus-core-macro"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51c0eb7eb76dd5a0b9a116d94d29ca78924a1ed1fcb7ea072eda5045d3ac056" checksum = "6a82d65f0024fc86f01911a16156d280eea583be5a82a3bed85e7e8e4194302d"
dependencies = [ dependencies = [
"convert_case 0.8.0", "convert_case 0.8.0",
"dioxus-rsx", "dioxus-rsx",
@@ -1619,15 +1587,15 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-core-types" name = "dioxus-core-types"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0652ab5f9c2c32261d44a3155debbfd909ed03d03434d7f70f5a796bf255c519" checksum = "bfc4b8cdc440a55c17355542fc2089d97949bba674255d84cac77805e1db8c9f"
[[package]] [[package]]
name = "dioxus-desktop" name = "dioxus-desktop"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b24aa7e4aa87fce202c5e67d560cddd9ed67ad533f16b7d922916c04993766ff" checksum = "7e6ec66749d1556636c5b4f661495565c155a7f78a46d4d007d7478c6bdc288c"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"base64", "base64",
@@ -1661,7 +1629,7 @@ dependencies = [
"objc_id", "objc_id",
"percent-encoding", "percent-encoding",
"rand 0.9.2", "rand 0.9.2",
"rfd 0.15.4", "rfd 0.17.2",
"rustc-hash 2.1.1", "rustc-hash 2.1.1",
"serde", "serde",
"serde_json", "serde_json",
@@ -1680,9 +1648,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-devtools" name = "dioxus-devtools"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9748128bcd102b10e58c765939807053ccab542206a939b8bab228077455c259" checksum = "dcf89488bad8fb0f18b9086ee2db01f95f709801c10c68be42691a36378a0f2d"
dependencies = [ dependencies = [
"dioxus-cli-config", "dioxus-cli-config",
"dioxus-core", "dioxus-core",
@@ -1698,9 +1666,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-devtools-types" name = "dioxus-devtools-types"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48540ca8a0ab1ec81cd4db35f0c9713d43b158647fc1dcb0d79965fc3b41d96c" checksum = "6e7381d9d7d0a0f66b9d5082d584853c3d53be21d34007073daca98ddf26fc4d"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"serde", "serde",
@@ -1709,9 +1677,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-document" name = "dioxus-document"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "501a189b391d091c9aa02c05f5b25f5d0d17fa0e1016e000b0fdbb073d77cd6a" checksum = "6ba0aeeff26d9d06441f59fd8d7f4f76098ba30ca9728e047c94486161185ceb"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"dioxus-core-macro", "dioxus-core-macro",
@@ -1728,9 +1696,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-fullstack" name = "dioxus-fullstack"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54150804265defdb21a6f2d8914a45316a1e7fb70ab22c30cf836e8fe2f8081b" checksum = "7db1f8b70338072ec408b48d09c96559cf071f87847465d8161294197504c498"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"async-stream", "async-stream",
@@ -1785,9 +1753,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-fullstack-core" name = "dioxus-fullstack-core"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a9be2ef4d701520eefef284d218fb35b159dccd6bccc02b5bad42945e2599d" checksum = "cda8b152e85121243741b9d5f2a3d8cb3c47a7b2299e902f98b6a7719915b0a2"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"axum-core", "axum-core",
@@ -1813,9 +1781,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-fullstack-macro" name = "dioxus-fullstack-macro"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31ea4451fe8c9d2af24fb718a94966d5fd7e11325777e5b5a59085c5c85e5fb" checksum = "255104d4a4f278f1a8482fa30536c91d22260c561c954b753e72987df8d65b2e"
dependencies = [ dependencies = [
"const_format", "const_format",
"convert_case 0.8.0", "convert_case 0.8.0",
@@ -1827,9 +1795,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-history" name = "dioxus-history"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55d704b3ba9504cb3c9cde49499b75546d1faaff2736f4c368aca6c061c48ac3" checksum = "8d00ba43bfe6e5ca226fef6128f240ca970bea73cac0462416188026360ccdcf"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"tracing", "tracing",
@@ -1837,9 +1805,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-hooks" name = "dioxus-hooks"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79c6d68be372eca8186a1c57ec49be67a6ea46022150b5e85ab6a6acde52d272" checksum = "dab2da4f038c33cb38caa37ffc3f5d6dfbc018f05da35b238210a533bb075823"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"dioxus-signals", "dioxus-signals",
@@ -1853,9 +1821,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-html" name = "dioxus-html"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3aa87ecfa0f38ec286be25789a7f2d6c30778111f1fbff563da4bae41d171496" checksum = "eded5fa6d2e677b7442a93f4228bf3c0ad2597a8bd3292cae50c869d015f3a99"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"bytes", "bytes",
@@ -1880,9 +1848,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-html-internal-macro" name = "dioxus-html-internal-macro"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49301d0e389378e8070b8b704110339a0d3358efad9f5ad483ffab3a8d406dae" checksum = "45462ab85fe059a36841508d40545109fd0e25855012d22583a61908eb5cd02a"
dependencies = [ dependencies = [
"convert_case 0.8.0", "convert_case 0.8.0",
"proc-macro2", "proc-macro2",
@@ -1892,9 +1860,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-interpreter-js" name = "dioxus-interpreter-js"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5437a89d3ef7edfebc0f10acb065f1709cb7ffb678e3a4bb1416706d71f7c67" checksum = "a42a7f73ad32a5054bd8c1014f4ac78cca3b7f6889210ee2b57ea31b33b6d32f"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"dioxus-core-types", "dioxus-core-types",
@@ -1912,9 +1880,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-logger" name = "dioxus-logger"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b25ebfbc193cebcf5af5e19b8ee7c6adee486fbd1c12f11aea058b464da16f9" checksum = "f1eeab114cb009d9e6b85ea10639a18cfc54bb342f3b837770b004c4daeb89c2"
dependencies = [ dependencies = [
"dioxus-cli-config", "dioxus-cli-config",
"tracing", "tracing",
@@ -1924,9 +1892,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-rsx" name = "dioxus-rsx"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d97c02689beff55767ba5f6e185ffd204c6a193e372f0fead8a3722c6f7eea" checksum = "53128858f0ccca9de54292a4d48409fda1df75fd5012c6243f664042f0225d68"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"proc-macro2-diagnostics", "proc-macro2-diagnostics",
@@ -1937,9 +1905,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-signals" name = "dioxus-signals"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27fc4df7a31a7f02e5a0b40884bb66ee165226a05d75fce03baa44029e438762" checksum = "2f48020bc23bc9766e7cce986c0fd6de9af0b8cbfd432652ec6b1094439c1ec6"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"futures-channel", "futures-channel",
@@ -1953,9 +1921,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-stores" name = "dioxus-stores"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2dec3cd677078824a733de25ddbe8e987cfc8d98aec29b7d199e1fdb8452b96" checksum = "77aaa9ac56d781bb506cf3c0d23bea96b768064b89fe50d3b4d4659cc6bd8058"
dependencies = [ dependencies = [
"dioxus-core", "dioxus-core",
"dioxus-signals", "dioxus-signals",
@@ -1965,9 +1933,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-stores-macro" name = "dioxus-stores-macro"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9b7f085e374aaaa78403227b9bd83675c4078388d41a41b67dfbe4aa0bb64d5" checksum = "5b1a728622e7b63db45774f75e71504335dd4e6115b235bbcff272980499493a"
dependencies = [ dependencies = [
"convert_case 0.8.0", "convert_case 0.8.0",
"proc-macro2", "proc-macro2",
@@ -1977,9 +1945,9 @@ dependencies = [
[[package]] [[package]]
name = "dioxus-web" name = "dioxus-web"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "315009f3a77c3c813415b3b8a8ea62a4d7a32dde9a666664b30862d4386e8456" checksum = "3b33fe739fed4e8143dac222a9153593f8e2451662ce8fc4c9d167a9d6ec0923"
dependencies = [ dependencies = [
"dioxus-cli-config", "dioxus-cli-config",
"dioxus-core", "dioxus-core",
@@ -2058,15 +2026,6 @@ dependencies = [
"syn 2.0.108", "syn 2.0.108",
] ]
[[package]]
name = "dlib"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading 0.8.9",
]
[[package]] [[package]]
name = "dlopen2" name = "dlopen2"
version = "0.8.0" version = "0.8.0"
@@ -2227,12 +2186,6 @@ dependencies = [
"cfg-if", "cfg-if",
] ]
[[package]]
name = "endi"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf"
[[package]] [[package]]
name = "enumflags2" name = "enumflags2"
version = "0.7.12" version = "0.7.12"
@@ -2240,7 +2193,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef" checksum = "1027f7680c853e056ebcec683615fb6fbbc07dbaa13b4d5d9442b146ded4ecef"
dependencies = [ dependencies = [
"enumflags2_derive", "enumflags2_derive",
"serde",
] ]
[[package]] [[package]]
@@ -2332,27 +2284,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "event-listener"
version = "5.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab"
dependencies = [
"concurrent-queue",
"parking",
"pin-project-lite",
]
[[package]]
name = "event-listener-strategy"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93"
dependencies = [
"event-listener",
"pin-project-lite",
]
[[package]] [[package]]
name = "eyre" name = "eyre"
version = "0.6.12" version = "0.6.12"
@@ -2565,19 +2496,6 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
[[package]]
name = "futures-lite"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"parking",
"pin-project-lite",
]
[[package]] [[package]]
name = "futures-macro" name = "futures-macro"
version = "0.3.31" version = "0.3.31"
@@ -2715,9 +2633,9 @@ dependencies = [
[[package]] [[package]]
name = "generational-box" name = "generational-box"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e658d10252a15200ca4a1c67c7180fc0baffa3f92869bbd903025daf6f70fd65" checksum = "cc4ed190b9de8e734d47a70be59b1e7588b9e8e0d0036e332f4c014e8aed1bc5"
dependencies = [ dependencies = [
"parking_lot", "parking_lot",
"tracing", "tracing",
@@ -3729,9 +3647,9 @@ dependencies = [
[[package]] [[package]]
name = "lazy-js-bundle" name = "lazy-js-bundle"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21972afec4627b7ba0de60b5269585b5ac2f56d559b0696f57eee6daf8a51b68" checksum = "c7b88b715ab1496c6e6b8f5e927be961c4235196121b6ae59bcb51077a21dd36"
[[package]] [[package]]
name = "lazy_static" name = "lazy_static"
@@ -4034,32 +3952,35 @@ dependencies = [
[[package]] [[package]]
name = "manganis" name = "manganis"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97c63ae68d25457a579b7714806088c5cb44c536cf624a53a17184878f9f0bcd" checksum = "6cce7d688848bf9d034168513b9a2ffbfe5f61df2ff14ae15e6cfc866efdd344"
dependencies = [ dependencies = [
"const-serialize", "const-serialize 0.7.2",
"const-serialize 0.8.0-alpha.0",
"manganis-core", "manganis-core",
"manganis-macro", "manganis-macro",
] ]
[[package]] [[package]]
name = "manganis-core" name = "manganis-core"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d071660b149f985cbab8b23f2004ea6dd5cf947b63a0843f0e2f46e6af7229" checksum = "84ce917b978268fe8a7db49e216343ec7c8f471f7e686feb70940d67293f19d4"
dependencies = [ dependencies = [
"const-serialize", "const-serialize 0.7.2",
"const-serialize 0.8.0-alpha.0",
"dioxus-cli-config", "dioxus-cli-config",
"dioxus-core-types", "dioxus-core-types",
"serde", "serde",
"winnow 0.7.14",
] ]
[[package]] [[package]]
name = "manganis-macro" name = "manganis-macro"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9793d1d33778245b4240c330a8f575d208ce077c7e7bab1c79064252ddd4a162" checksum = "ad513e990f7c0bca86aa68659a7a3dc4c705572ed4c22fd6af32ccf261334cc2"
dependencies = [ dependencies = [
"dunce", "dunce",
"macro-string", "macro-string",
@@ -4481,7 +4402,6 @@ dependencies = [
"cfg-if", "cfg-if",
"cfg_aliases", "cfg_aliases",
"libc", "libc",
"memoffset",
] ]
[[package]] [[package]]
@@ -4862,16 +4782,6 @@ dependencies = [
"hashbrown 0.14.5", "hashbrown 0.14.5",
] ]
[[package]]
name = "ordered-stream"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9aa2b01e1d916879f73a53d01d1d6cee68adbb31d6d9177a8cfce093cced1d50"
dependencies = [
"futures-core",
"pin-project-lite",
]
[[package]] [[package]]
name = "ordermap" name = "ordermap"
version = "0.5.12" version = "0.5.12"
@@ -4936,12 +4846,6 @@ dependencies = [
"system-deps", "system-deps",
] ]
[[package]]
name = "parking"
version = "2.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba"
[[package]] [[package]]
name = "parking_lot" name = "parking_lot"
version = "0.12.5" version = "0.12.5"
@@ -5514,15 +5418,6 @@ dependencies = [
"psl-types", "psl-types",
] ]
[[package]]
name = "quick-xml"
version = "0.37.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "quinn" name = "quinn"
version = "0.11.9" version = "0.11.9"
@@ -5878,30 +5773,6 @@ dependencies = [
"subtle", "subtle",
] ]
[[package]]
name = "rfd"
version = "0.15.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef2bee61e6cffa4635c72d7d81a84294e28f0930db0ddcb0f66d10244674ebed"
dependencies = [
"ashpd",
"block2",
"dispatch2",
"js-sys",
"log",
"objc2",
"objc2-app-kit",
"objc2-core-foundation",
"objc2-foundation",
"pollster",
"raw-window-handle 0.6.2",
"urlencoding",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.59.0",
]
[[package]] [[package]]
name = "rfd" name = "rfd"
version = "0.16.0" version = "0.16.0"
@@ -5924,6 +5795,30 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "rfd"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20dafead71c16a34e1ff357ddefc8afc11e7d51d6d2b9fbd07eaa48e3e540220"
dependencies = [
"block2",
"dispatch2",
"js-sys",
"libc",
"log",
"objc2",
"objc2-app-kit",
"objc2-core-foundation",
"objc2-foundation",
"percent-encoding",
"pollster",
"raw-window-handle 0.6.2",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.14" version = "0.17.14"
@@ -7059,9 +6954,9 @@ dependencies = [
[[package]] [[package]]
name = "subsecond" name = "subsecond"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c09bc2c9ef0381b403ab8b58122961cb83266d16b1f55f9486d5857ba4a9ae26" checksum = "8438668e545834d795d04c4335aafc332ce046106521a29f0a5c6501de34187c"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"libc", "libc",
@@ -7078,9 +6973,9 @@ dependencies = [
[[package]] [[package]]
name = "subsecond-types" name = "subsecond-types"
version = "0.7.2" version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d07aa455c66ddfdbb51507537402b961e027846468954ef8d974bce65dff9eb0" checksum = "1e72f747606fc19fe81d6c59e491af93ed7dcbcb6aad9d1d18b05129914ec298"
dependencies = [ dependencies = [
"serde", "serde",
] ]
@@ -7400,7 +7295,6 @@ dependencies = [
"signal-hook-registry", "signal-hook-registry",
"socket2", "socket2",
"tokio-macros", "tokio-macros",
"tracing",
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
@@ -7524,7 +7418,7 @@ dependencies = [
"indexmap", "indexmap",
"toml_datetime 0.7.3", "toml_datetime 0.7.3",
"toml_parser", "toml_parser",
"winnow 0.7.13", "winnow 0.7.14",
] ]
[[package]] [[package]]
@@ -7533,7 +7427,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
dependencies = [ dependencies = [
"winnow 0.7.13", "winnow 0.7.14",
] ]
[[package]] [[package]]
@@ -7910,17 +7804,6 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971"
[[package]]
name = "uds_windows"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
dependencies = [
"memoffset",
"tempfile",
"winapi",
]
[[package]] [[package]]
name = "ulid" name = "ulid"
version = "1.2.1" version = "1.2.1"
@@ -7998,12 +7881,6 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "urlencoding"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
[[package]] [[package]]
name = "utf-8" name = "utf-8"
version = "0.7.6" version = "0.7.6"
@@ -8023,7 +7900,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2"
dependencies = [ dependencies = [
"js-sys", "js-sys",
"serde",
"wasm-bindgen", "wasm-bindgen",
] ]
@@ -8184,66 +8060,6 @@ dependencies = [
"web-sys", "web-sys",
] ]
[[package]]
name = "wayland-backend"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673a33c33048a5ade91a6b139580fa174e19fb0d23f396dca9fa15f2e1e49b35"
dependencies = [
"cc",
"downcast-rs",
"rustix",
"scoped-tls",
"smallvec",
"wayland-sys",
]
[[package]]
name = "wayland-client"
version = "0.31.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c66a47e840dc20793f2264eb4b3e4ecb4b75d91c0dd4af04b456128e0bdd449d"
dependencies = [
"bitflags 2.10.0",
"rustix",
"wayland-backend",
"wayland-scanner",
]
[[package]]
name = "wayland-protocols"
version = "0.32.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efa790ed75fbfd71283bd2521a1cfdc022aabcc28bdcff00851f9e4ae88d9901"
dependencies = [
"bitflags 2.10.0",
"wayland-backend",
"wayland-client",
"wayland-scanner",
]
[[package]]
name = "wayland-scanner"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54cb1e9dc49da91950bdfd8b848c49330536d9d1fb03d4bfec8cae50caa50ae3"
dependencies = [
"proc-macro2",
"quick-xml",
"quote",
]
[[package]]
name = "wayland-sys"
version = "0.31.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34949b42822155826b41db8e5d0c1be3a2bd296c747577a43a3e6daefc296142"
dependencies = [
"dlib",
"log",
"pkg-config",
]
[[package]] [[package]]
name = "web-sys" name = "web-sys"
version = "0.3.82" version = "0.3.82"
@@ -8808,9 +8624,9 @@ dependencies = [
[[package]] [[package]]
name = "winnow" name = "winnow"
version = "0.7.13" version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" checksum = "5a5364e9d77fcdeeaa6062ced926ee3381faa2ee02d3eb83a5c27a8825540829"
dependencies = [ dependencies = [
"memchr", "memchr",
] ]
@@ -8984,62 +8800,6 @@ dependencies = [
"synstructure", "synstructure",
] ]
[[package]]
name = "zbus"
version = "5.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b622b18155f7a93d1cd2dc8c01d2d6a44e08fb9ebb7b3f9e6ed101488bad6c91"
dependencies = [
"async-broadcast",
"async-recursion",
"async-trait",
"enumflags2",
"event-listener",
"futures-core",
"futures-lite",
"hex",
"nix",
"ordered-stream",
"serde",
"serde_repr",
"tokio",
"tracing",
"uds_windows",
"uuid",
"windows-sys 0.61.2",
"winnow 0.7.13",
"zbus_macros",
"zbus_names",
"zvariant",
]
[[package]]
name = "zbus_macros"
version = "5.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1cdb94821ca8a87ca9c298b5d1cbd80e2a8b67115d99f6e4551ac49e42b6a314"
dependencies = [
"proc-macro-crate 3.4.0",
"proc-macro2",
"quote",
"syn 2.0.108",
"zbus_names",
"zvariant",
"zvariant_utils",
]
[[package]]
name = "zbus_names"
version = "4.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97"
dependencies = [
"serde",
"static_assertions",
"winnow 0.7.13",
"zvariant",
]
[[package]] [[package]]
name = "zerocopy" name = "zerocopy"
version = "0.8.27" version = "0.8.27"
@@ -9147,44 +8907,3 @@ dependencies = [
"cc", "cc",
"pkg-config", "pkg-config",
] ]
[[package]]
name = "zvariant"
version = "5.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2be61892e4f2b1772727be11630a62664a1826b62efa43a6fe7449521cb8744c"
dependencies = [
"endi",
"enumflags2",
"serde",
"url",
"winnow 0.7.13",
"zvariant_derive",
"zvariant_utils",
]
[[package]]
name = "zvariant_derive"
version = "5.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da58575a1b2b20766513b1ec59d8e2e68db2745379f961f86650655e862d2006"
dependencies = [
"proc-macro-crate 3.4.0",
"proc-macro2",
"quote",
"syn 2.0.108",
"zvariant_utils",
]
[[package]]
name = "zvariant_utils"
version = "3.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c6949d142f89f6916deca2232cf26a8afacf2b9fdc35ce766105e104478be599"
dependencies = [
"proc-macro2",
"quote",
"serde",
"syn 2.0.108",
"winnow 0.7.13",
]
+59 -1
View File
@@ -10,6 +10,21 @@ use tracing::{error, info};
use crate::imp; use crate::imp;
static DF_MODEL: Asset = asset!("/assets/DeepFilterNet3_ll_onnx.tar.gz"); static DF_MODEL: Asset = asset!("/assets/DeepFilterNet3_ll_onnx.tar.gz");
// TODO: make this user configurable.
static DEFAULT_NOISE_FLOOR: f32 = 0.001;
// 200ms hold at 48kHz sample rate
static HOLD_SAMPLES_MAX: usize = 48000 / 5; // 9600 samples = 200ms
/// Indicates the transmission state after processing audio.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TransmitState {
/// Audio is above threshold, or below but within hold period - transmit normally
Transmitting,
/// Hold period expired - send this frame as terminator (end_bit = true)
Terminator,
/// Silent and not transmitting - don't send anything
Silent,
}
enum DenoisingModelState { enum DenoisingModelState {
Nothing, Nothing,
@@ -76,6 +91,11 @@ pub struct AudioProcessor {
denoise: bool, denoise: bool,
spawn: imp::SpawnHandle, spawn: imp::SpawnHandle,
buffer: Vec<f32>, buffer: Vec<f32>,
noise_floor: f32,
/// Whether we were transmitting in the previous frame
was_transmitting: bool,
/// Number of samples we've been below threshold (for hold period)
hold_samples: usize,
} }
impl AudioProcessor { impl AudioProcessor {
@@ -84,6 +104,9 @@ impl AudioProcessor {
denoise: false, denoise: false,
spawn: imp::SpawnHandle::current(), spawn: imp::SpawnHandle::current(),
buffer: Vec::new(), buffer: Vec::new(),
noise_floor: DEFAULT_NOISE_FLOOR,
was_transmitting: false,
hold_samples: 0,
} }
} }
@@ -92,12 +115,15 @@ impl AudioProcessor {
denoise: true, denoise: true,
spawn: imp::SpawnHandle::current(), spawn: imp::SpawnHandle::current(),
buffer: Vec::new(), buffer: Vec::new(),
noise_floor: DEFAULT_NOISE_FLOOR,
was_transmitting: false,
hold_samples: 0,
} }
} }
} }
impl AudioProcessor { impl AudioProcessor {
pub fn process(&mut self, audio: &[f32], channels: usize, output: &mut Vec<f32>) { pub fn process(&mut self, audio: &[f32], channels: usize, output: &mut Vec<f32>) -> TransmitState {
let mut include_raw = true; let mut include_raw = true;
if self.denoise { if self.denoise {
with_denoising_model(&self.spawn, |df| { with_denoising_model(&self.spawn, |df| {
@@ -132,6 +158,38 @@ impl AudioProcessor {
if include_raw { if include_raw {
output.extend(audio.iter().step_by(channels).copied()); output.extend(audio.iter().step_by(channels).copied());
} }
// Calculate average amplitude for VAD
let avg: f32 = if output.is_empty() {
0.0
} else {
output.iter().map(|x| x.abs()).sum::<f32>() / output.len() as f32
};
let above_threshold = avg >= self.noise_floor;
let samples_in_frame = output.len();
let state = if above_threshold {
// Above threshold - reset hold counter and transmit
self.hold_samples = 0;
self.was_transmitting = true;
TransmitState::Transmitting
} else if self.was_transmitting && self.hold_samples < HOLD_SAMPLES_MAX {
// Below threshold but in hold period - keep transmitting
self.hold_samples += samples_in_frame;
TransmitState::Transmitting
} else if self.was_transmitting {
// Hold period expired - send terminator
self.was_transmitting = false;
self.hold_samples = 0;
TransmitState::Terminator
} else {
// Not transmitting and below threshold - stay silent
output.clear(); // Don't accumulate stale audio during silence
TransmitState::Silent
};
state
} }
} }
+29 -16
View File
@@ -1,4 +1,4 @@
use crate::effects::{AudioProcessor, AudioProcessorSender}; use crate::effects::{AudioProcessor, AudioProcessorSender, TransmitState};
use color_eyre::eyre::{eyre, Error}; use color_eyre::eyre::{eyre, Error};
use cpal::traits::{DeviceTrait, HostTrait, StreamTrait as _}; use cpal::traits::{DeviceTrait, HostTrait, StreamTrait as _};
use futures::io::{AsyncRead, AsyncWrite}; use futures::io::{AsyncRead, AsyncWrite};
@@ -23,6 +23,31 @@ pub struct AudioSystem {
const SAMPLE_RATE: u32 = 48_000; const SAMPLE_RATE: u32 = 48_000;
const PACKET_SAMPLES: u32 = 960; const PACKET_SAMPLES: u32 = 960;
fn encode_and_send(
state: TransmitState,
output_buffer: &mut Vec<f32>,
encoder: &mut opus::Encoder,
each: &mut impl FnMut(Vec<u8>, bool),
) {
let (is_terminator, should_encode) = match state {
TransmitState::Silent => return,
TransmitState::Transmitting => (false, output_buffer.len() >= PACKET_SAMPLES as usize),
TransmitState::Terminator => {
output_buffer.resize(PACKET_SAMPLES as usize, 0.0);
(true, true)
}
};
if should_encode {
let remainder = output_buffer.split_off(PACKET_SAMPLES as usize);
let frame = replace(output_buffer, remainder);
match encoder.encode_vec_float(&frame, frame.len() * 2) {
Ok(encoded) => each(encoded, is_terminator),
Err(e) => error!("error encoding {} samples: {e:?}", frame.len()),
}
}
}
type Buffer = Arc<Mutex<dasp_ring_buffer::Bounded<Vec<i16>>>>; type Buffer = Arc<Mutex<dasp_ring_buffer::Bounded<Vec<i16>>>>;
impl AudioSystem { impl AudioSystem {
@@ -79,7 +104,7 @@ impl AudioSystem {
pub fn start_recording( pub fn start_recording(
&mut self, &mut self,
mut each: impl FnMut(Vec<u8>) + Send + 'static, mut each: impl FnMut(Vec<u8>, bool) + Send + 'static,
) -> Result<(), Error> { ) -> Result<(), Error> {
let config = self.choose_config(self.input.supported_input_configs()?)?; let config = self.choose_config(self.input.supported_input_configs()?)?;
info!( info!(
@@ -97,20 +122,8 @@ impl AudioSystem {
if let Some(new_processor) = processors.take() { if let Some(new_processor) = processors.take() {
current_processor = new_processor; current_processor = new_processor;
} }
current_processor.process(frame, config.channels as usize, &mut output_buffer); let state = current_processor.process(frame, config.channels as usize, &mut output_buffer);
if output_buffer.len() < PACKET_SAMPLES as usize { encode_and_send(state, &mut output_buffer, &mut encoder, &mut each);
return;
}
let remainder = output_buffer.split_off(PACKET_SAMPLES as usize);
let frame = replace(&mut output_buffer, remainder);
match encoder.encode_vec_float(&frame, frame.len() * 2) {
Ok(buf) => {
each(buf);
}
Err(e) => {
error!("error encoding {} samples: {e:?}", frame.len());
}
}
}; };
match self match self
+37 -10
View File
@@ -1,6 +1,7 @@
use crate::app::Command; use crate::app::Command;
use crate::effects::{AudioProcessor, AudioProcessorSender}; use crate::effects::{AudioProcessor, AudioProcessorSender, TransmitState};
use color_eyre::eyre::{bail, eyre, Error}; use color_eyre::eyre::{bail, eyre, Error};
use crossbeam::atomic::AtomicCell;
use dioxus::prelude::*; use dioxus::prelude::*;
use futures::{AsyncRead, AsyncWrite}; use futures::{AsyncRead, AsyncWrite};
use gloo_timers::future::TimeoutFuture; use gloo_timers::future::TimeoutFuture;
@@ -9,6 +10,7 @@ use mumble_protocol::control::ClientControlCodec;
use mumble_web2_common::{ClientConfig, ServerStatus}; use mumble_web2_common::{ClientConfig, ServerStatus};
use reqwest::Url; use reqwest::Url;
use std::future::Future; use std::future::Future;
use std::sync::Arc;
use std::time::Duration; use std::time::Duration;
use tracing::level_filters::LevelFilter; use tracing::level_filters::LevelFilter;
use tracing::{debug, error, info, instrument}; use tracing::{debug, error, info, instrument};
@@ -118,7 +120,10 @@ impl AudioSystem {
self.processors.store(Some(processor)) self.processors.store(Some(processor))
} }
pub fn start_recording(&mut self, each: impl FnMut(Vec<u8>) + 'static) -> Result<(), Error> { pub fn start_recording(
&mut self,
each: impl FnMut(Vec<u8>, bool) + 'static,
) -> Result<(), Error> {
let audio_context_worklet = self.webctx.clone(); let audio_context_worklet = self.webctx.clone();
let processors = self.processors.clone(); let processors = self.processors.clone();
spawn(async move { spawn(async move {
@@ -222,22 +227,26 @@ impl PromiseExt for Promise {
} }
} }
fn process_audio(frame: &JsValue, processor: &mut AudioProcessor) { fn process_audio(frame: &JsValue, processor: &mut AudioProcessor) -> TransmitState {
let Ok(samples) = Reflect::get(&frame, &"data".into()) else { let Ok(samples) = Reflect::get(&frame, &"data".into()) else {
return; return TransmitState::Silent;
}; };
let Ok(samples) = samples.dyn_into::<Float32Array>() else { let Ok(samples) = samples.dyn_into::<Float32Array>() else {
return; return TransmitState::Silent;
}; };
let input = samples.to_vec(); let input = samples.to_vec();
let mut output = Vec::with_capacity(input.len()); let mut output = Vec::with_capacity(input.len());
processor.process(&input, 1, &mut output); let state = processor.process(&input, 1, &mut output);
samples.copy_from(&output); if !output.is_empty() {
samples.copy_from(&output);
}
state
} }
async fn run_encoder_worklet( async fn run_encoder_worklet(
audio_context: &AudioContext, audio_context: &AudioContext,
mut each: impl FnMut(Vec<u8>) + 'static, mut each: impl FnMut(Vec<u8>, bool) + 'static,
processors: AudioProcessorSender, processors: AudioProcessorSender,
) -> Result<AudioWorkletNode, Error> { ) -> Result<AudioWorkletNode, Error> {
let constraints = MediaStreamConstraints::new(); let constraints = MediaStreamConstraints::new();
@@ -262,12 +271,19 @@ async fn run_encoder_worklet(
let encoder_error: Closure<dyn FnMut(JsValue)> = let encoder_error: Closure<dyn FnMut(JsValue)> =
Closure::new(|e| error!("error encoding audio {:?}", e)); Closure::new(|e| error!("error encoding audio {:?}", e));
// Shared state to signal terminator between onmessage and output closures
// The output closure runs asynchronously after encoding completes
let pending_terminator = Arc::new(AtomicCell::new(false));
let pending_terminator_output = pending_terminator.clone();
// This knows what MediaStreamTrackGenerator to use as it closes around it // This knows what MediaStreamTrackGenerator to use as it closes around it
let output: Closure<dyn FnMut(EncodedAudioChunk)> = let output: Closure<dyn FnMut(EncodedAudioChunk)> =
Closure::new(move |audio_data: EncodedAudioChunk| { Closure::new(move |audio_data: EncodedAudioChunk| {
let mut array = vec![0u8; audio_data.byte_length() as usize]; let mut array = vec![0u8; audio_data.byte_length() as usize];
audio_data.copy_to_with_u8_slice(&mut array); audio_data.copy_to_with_u8_slice(&mut array);
each(array); // Check if this frame was marked as a terminator
let is_terminator = pending_terminator_output.swap(false);
each(array, is_terminator);
}); });
let audio_encoder = AudioEncoder::new(&AudioEncoderInit::new( let audio_encoder = AudioEncoder::new(&AudioEncoderInit::new(
@@ -294,8 +310,19 @@ async fn run_encoder_worklet(
} }
let frame = event.data(); let frame = event.data();
process_audio(&frame, &mut current_processor); let state = process_audio(&frame, &mut current_processor);
match state {
TransmitState::Silent => {
// Don't encode or send anything
return;
}
TransmitState::Transmitting => (), // Normal transmission
TransmitState::Terminator => {
// Mark this as a terminator before encoding
pending_terminator.store(true);
}
}
match AudioData::new(frame.unchecked_ref()) { match AudioData::new(frame.unchecked_ref()) {
Ok(data) => { Ok(data) => {
let _ = audio_encoder.encode(&data); let _ = audio_encoder.encode(&data);
+2 -2
View File
@@ -114,14 +114,14 @@ pub async fn network_loop<R: imp::ImpRead, W: imp::ImpWrite>(
{ {
let send_chan = send_chan.clone(); let send_chan = send_chan.clone();
let mut sequence_num = 0; let mut sequence_num = 0;
audio.start_recording(move |opus_frame| { audio.start_recording(move |opus_frame, is_terminator| {
let _ = let _ =
send_chan.unbounded_send(ControlPacket::UDPTunnel(Box::new(VoicePacket::Audio { send_chan.unbounded_send(ControlPacket::UDPTunnel(Box::new(VoicePacket::Audio {
_dst: std::marker::PhantomData, _dst: std::marker::PhantomData,
target: 0, target: 0,
session_id: (), session_id: (),
seq_num: sequence_num, seq_num: sequence_num,
payload: VoicePacketPayload::Opus(opus_frame.into(), false), payload: VoicePacketPayload::Opus(opus_frame.into(), is_terminator),
position_info: None, position_info: None,
}))); })));
sequence_num = sequence_num.wrapping_add(2); sequence_num = sequence_num.wrapping_add(2);