diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bc68b83..7c9b727 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -45,9 +45,6 @@ jobs: with: toolchain: 1.96.0 - - name: Rust Cache - uses: swatinem/rust-cache@v2 - - name: Run tests run: cargo test --locked @@ -138,9 +135,6 @@ jobs: with: toolchain: 1.96.0 - - name: Rust Cache - uses: swatinem/rust-cache@v2 - - name: Build all binaries (debug-speed compilation into target/release) env: CARGO_PROFILE_RELEASE_OPT_LEVEL: 0 diff --git a/.github/workflows/flatter.yml b/.github/workflows/flatter.yml index 2ab39b6..b526122 100644 --- a/.github/workflows/flatter.yml +++ b/.github/workflows/flatter.yml @@ -60,9 +60,9 @@ jobs: echo "default-branch: ${{ steps.set_branch.outputs.branch }}" >> packages/flatpak/ru.arabianq.pwsp.yaml - name: Install SDK Extensions - run: | + run: flatpak install -y flathub org.freedesktop.Sdk.Extension.rust-stable//25.08 - flatpak install -y flathub org.freedesktop.Sdk.Extension.llvm20//25.08 + org.freedesktop.Sdk.Extension.llvm20//25.08 - name: Build Flatpak uses: andyholmes/flatter@main @@ -72,7 +72,6 @@ jobs: upload-bundles: false upload-pages-artifact: false arch: x86_64 - cache: true flatter-arm64: name: Flatter (aarch64) @@ -114,9 +113,9 @@ jobs: echo "default-branch: ${{ steps.set_branch.outputs.branch }}" >> packages/flatpak/ru.arabianq.pwsp.yaml - name: Install SDK Extensions - run: | + run: flatpak install -y flathub org.freedesktop.Sdk.Extension.rust-stable//25.08 - flatpak install -y flathub org.freedesktop.Sdk.Extension.llvm20//25.08 + org.freedesktop.Sdk.Extension.llvm20//25.08 - name: Build Flatpak uses: andyholmes/flatter@main @@ -126,7 +125,6 @@ jobs: upload-bundles: false upload-pages-artifact: true arch: aarch64 - cache: true deploy: name: Deploy to GitHub Pages diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 970c785..013472a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,9 +97,6 @@ jobs: with: toolchain: 1.96.0 - - name: Rust Cache - uses: swatinem/rust-cache@v2 - - name: Extract all binary names id: cargo-meta run: | @@ -183,9 +180,6 @@ jobs: with: toolchain: 1.96.0 - - name: Rust Cache - uses: swatinem/rust-cache@v2 - - name: Build all release binaries run: cargo build --release --locked @@ -260,8 +254,7 @@ jobs: run: | mkdir -p ~/.config echo "$COPR_CONFIG" > ~/.config/copr - copr-cli buildscm --nowait \ - --clone-url https://github.com/arabianq/pipewire-soundpad.git \ + copr-cli buildscm --clone-url https://github.com/arabianq/pipewire-soundpad.git \ --commit ${{ needs.prepare.outputs.tag }} \ --spec packages/rpm/pwsp.spec \ arabianq/pwsp diff --git a/Cargo.lock b/Cargo.lock index 784e6ac..a98365f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -151,9 +151,9 @@ dependencies = [ [[package]] name = "arrayvec" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" +checksum = "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe" [[package]] name = "as-raw-xcb-connection" @@ -386,9 +386,9 @@ checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" [[package]] name = "bitvec" -version = "1.0.1" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +checksum = "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837" dependencies = [ "funty", "radium", @@ -429,13 +429,13 @@ dependencies = [ [[package]] name = "bstr" -version = "1.12.1" +version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab" +checksum = "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79" dependencies = [ "memchr", "regex-automata", - "serde", + "serde_core", ] [[package]] @@ -472,9 +472,9 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" [[package]] name = "bytes" -version = "1.11.1" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" +checksum = "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593" [[package]] name = "calloop" @@ -529,9 +529,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.64" +version = "1.2.65" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f" +checksum = "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96" dependencies = [ "find-msvc-tools", "jobserver", @@ -776,7 +776,7 @@ dependencies = [ [[package]] name = "cpal" version = "0.18.1" -source = "git+https://github.com/RustAudio/cpal#6ea4fcd74e002cfe660158a33014d7bb499de94c" +source = "git+https://github.com/RustAudio/cpal#e22fb7ecb4800649b7790bcbe8422ca347a62cd0" dependencies = [ "alsa", "block2 0.6.2", @@ -878,7 +878,7 @@ dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1227,7 +1227,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -1513,11 +1513,22 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.3.0", "wasip2", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", +] + [[package]] name = "gl_generator" version = "0.14.0" @@ -1639,9 +1650,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.14" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733" +checksum = "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155" dependencies = [ "atomic-waker", "bytes", @@ -2104,9 +2115,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31" +checksum = "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102" dependencies = [ "cfg-if", "futures-util", @@ -2263,9 +2274,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.32" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" +checksum = "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad" [[package]] name = "lru-slab" @@ -2287,9 +2298,9 @@ checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" [[package]] name = "memmap2" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" +checksum = "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0" dependencies = [ "libc", ] @@ -3314,9 +3325,9 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.9" +version = "0.11.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20" +checksum = "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8" dependencies = [ "bytes", "cfg_aliases", @@ -3334,9 +3345,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.14" +version = "0.11.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" +checksum = "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e" dependencies = [ "aws-lc-rs", "bytes", @@ -3370,9 +3381,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.45" +version = "1.0.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368" dependencies = [ "proc-macro2", ] @@ -3383,6 +3394,12 @@ version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "radium" version = "0.7.0" @@ -3735,14 +3752,14 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] name = "rustls" -version = "0.23.40" +version = "0.23.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" +checksum = "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f" dependencies = [ "aws-lc-rs", "once_cell", @@ -3792,7 +3809,7 @@ dependencies = [ "security-framework", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4141,7 +4158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4376,9 +4393,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.117" +version = "2.0.118" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +checksum = "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422" dependencies = [ "proc-macro2", "quote", @@ -4478,10 +4495,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.4", + "getrandom 0.4.3", "once_cell", "rustix 1.1.4", - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] @@ -4826,7 +4843,7 @@ checksum = "f2f6fb2847f6742cd76af783a2a2c49e9375d0a111c7bef6f71cd9e738c72d6e" dependencies = [ "memoffset", "tempfile", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -4886,9 +4903,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.23.3" +version = "1.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7" +checksum = "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53" dependencies = [ "js-sys", "serde_core", @@ -4969,9 +4986,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a" +checksum = "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4" dependencies = [ "cfg-if", "once_cell", @@ -4982,9 +4999,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.75" +version = "0.4.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280" +checksum = "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d" dependencies = [ "js-sys", "wasm-bindgen", @@ -4992,9 +5009,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d" +checksum = "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -5002,9 +5019,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd" +checksum = "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e" dependencies = [ "bumpalo", "proc-macro2", @@ -5015,9 +5032,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.125" +version = "0.2.126" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f" +checksum = "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24" dependencies = [ "unicode-ident", ] @@ -5072,9 +5089,9 @@ dependencies = [ [[package]] name = "wayland-protocols" -version = "0.32.12" +version = "0.32.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f" +checksum = "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6" dependencies = [ "bitflags 2.13.0", "wayland-backend", @@ -5159,9 +5176,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.102" +version = "0.3.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d" +checksum = "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141" dependencies = [ "js-sys", "wasm-bindgen", @@ -5195,9 +5212,9 @@ dependencies = [ [[package]] name = "webpki-root-certs" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c" +checksum = "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267" dependencies = [ "rustls-pki-types", ] @@ -5327,7 +5344,7 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.61.2", ] [[package]] diff --git a/packages/flatpak/cargo-sources.json b/packages/flatpak/cargo-sources.json index ec61420..8f41572 100644 --- a/packages/flatpak/cargo-sources.json +++ b/packages/flatpak/cargo-sources.json @@ -2,8 +2,8 @@ { "type": "git", "url": "https://github.com/rustaudio/cpal", - "commit": "6ea4fcd74e002cfe660158a33014d7bb499de94c", - "dest": "flatpak-cargo/git/cpal-6ea4fcd" + "commit": "e22fb7ecb4800649b7790bcbe8422ca347a62cd0", + "dest": "flatpak-cargo/git/cpal-e22fb7e" }, { "type": "git", @@ -209,14 +209,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/arrayvec/arrayvec-0.7.6.crate", - "sha256": "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50", - "dest": "cargo/vendor/arrayvec-0.7.6" + "url": "https://static.crates.io/crates/arrayvec/arrayvec-0.7.7.crate", + "sha256": "f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe", + "dest": "cargo/vendor/arrayvec-0.7.7" }, { "type": "inline", - "contents": "{\"package\": \"7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50\", \"files\": {}}", - "dest": "cargo/vendor/arrayvec-0.7.6", + "contents": "{\"package\": \"f02882884d3e1bc524fb12c79f107f6ad0e1cfd498c536ffb494301740995dfe\", \"files\": {}}", + "dest": "cargo/vendor/arrayvec-0.7.7", "dest-filename": ".cargo-checksum.json" }, { @@ -508,14 +508,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/bitvec/bitvec-1.0.1.crate", - "sha256": "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c", - "dest": "cargo/vendor/bitvec-1.0.1" + "url": "https://static.crates.io/crates/bitvec/bitvec-1.1.1.crate", + "sha256": "ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837", + "dest": "cargo/vendor/bitvec-1.1.1" }, { "type": "inline", - "contents": "{\"package\": \"1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c\", \"files\": {}}", - "dest": "cargo/vendor/bitvec-1.0.1", + "contents": "{\"package\": \"ddcec3d12c579d40898fe0a9a358a803c23e9c52ca3c425707f81c9436211837\", \"files\": {}}", + "dest": "cargo/vendor/bitvec-1.1.1", "dest-filename": ".cargo-checksum.json" }, { @@ -560,14 +560,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/bstr/bstr-1.12.1.crate", - "sha256": "63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab", - "dest": "cargo/vendor/bstr-1.12.1" + "url": "https://static.crates.io/crates/bstr/bstr-1.12.3.crate", + "sha256": "5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79", + "dest": "cargo/vendor/bstr-1.12.3" }, { "type": "inline", - "contents": "{\"package\": \"63044e1ae8e69f3b5a92c736ca6269b8d12fa7efe39bf34ddb06d102cf0e2cab\", \"files\": {}}", - "dest": "cargo/vendor/bstr-1.12.1", + "contents": "{\"package\": \"5cee35f73844aa3014bb606320a6c1f010249dbdf43342fe54b5a4f6a8ed4b79\", \"files\": {}}", + "dest": "cargo/vendor/bstr-1.12.3", "dest-filename": ".cargo-checksum.json" }, { @@ -625,14 +625,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/bytes/bytes-1.11.1.crate", - "sha256": "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33", - "dest": "cargo/vendor/bytes-1.11.1" + "url": "https://static.crates.io/crates/bytes/bytes-1.12.0.crate", + "sha256": "8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593", + "dest": "cargo/vendor/bytes-1.12.0" }, { "type": "inline", - "contents": "{\"package\": \"1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33\", \"files\": {}}", - "dest": "cargo/vendor/bytes-1.11.1", + "contents": "{\"package\": \"8ae3f5d315924270530207e2a68396c3cc547f6dca3fbdca317cfb1a51edb593\", \"files\": {}}", + "dest": "cargo/vendor/bytes-1.12.0", "dest-filename": ".cargo-checksum.json" }, { @@ -690,14 +690,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/cc/cc-1.2.64.crate", - "sha256": "dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f", - "dest": "cargo/vendor/cc-1.2.64" + "url": "https://static.crates.io/crates/cc/cc-1.2.65.crate", + "sha256": "e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96", + "dest": "cargo/vendor/cc-1.2.65" }, { "type": "inline", - "contents": "{\"package\": \"dad887fd958be91b5098c0248def011f4523ab786cd411be668777e55063501f\", \"files\": {}}", - "dest": "cargo/vendor/cc-1.2.64", + "contents": "{\"package\": \"e228eec9be7c17ccb640b59b36a5cd805ea2a564a4c5e162c2f659fea30d3b96\", \"files\": {}}", + "dest": "cargo/vendor/cc-1.2.65", "dest-filename": ".cargo-checksum.json" }, { @@ -1028,12 +1028,12 @@ { "type": "shell", "commands": [ - "cp -r --reflink=auto \"flatpak-cargo/git/cpal-6ea4fcd/.\" \"cargo/vendor/cpal\"" + "cp -r --reflink=auto \"flatpak-cargo/git/cpal-e22fb7e/.\" \"cargo/vendor/cpal\"" ] }, { "type": "inline", - "contents": "[package]\nname = \"cpal\"\nversion = \"0.18.1\"\ndescription = \"Low-level cross-platform audio I/O library.\"\nrepository = \"https://github.com/RustAudio/cpal\"\ndocumentation = \"https://docs.rs/cpal\"\nlicense = \"Apache-2.0\"\nkeywords = [\"audio\", \"sound\"]\nedition = \"2021\"\nrust-version = \"1.85\"\n\n[package.metadata.docs.rs]\nfeatures = [\"asio\", \"audioworklet\", \"custom\", \"jack\", \"pulseaudio\", \"realtime\", \"realtime-dbus\", \"wasm-bindgen\"]\nrustdoc-args = [\"--cfg\", \"docsrs\"]\ntargets = [\"x86_64-unknown-linux-gnu\", \"x86_64-pc-windows-msvc\", \"x86_64-apple-darwin\", \"aarch64-apple-darwin\", \"aarch64-apple-ios\", \"wasm32-unknown-unknown\", \"aarch64-linux-android\", \"x86_64-unknown-freebsd\", \"x86_64-unknown-netbsd\", \"x86_64-unknown-dragonfly\"]\n\n[badges.maintenance]\nstatus = \"actively-developed\"\n\n[features]\ndefault = []\nrealtime = [\"dep:audio_thread_priority\", \"dep:alsa-sys\"]\nrealtime-dbus = [\"realtime\", \"audio_thread_priority/with_dbus\"]\nasio = [\"dep:asio-sys\", \"dep:num-traits\"]\naudioworklet = [\"wasm-bindgen\", \"web-sys/Blob\", \"web-sys/BlobPropertyBag\", \"web-sys/Url\", \"web-sys/AudioWorklet\", \"web-sys/AudioWorkletNode\", \"web-sys/AudioWorkletNodeOptions\"]\ncustom = []\njack = [\"dep:jack\"]\npipewire = [\"dep:pipewire\"]\npulseaudio = [\"dep:pulseaudio\", \"dep:futures\"]\nwasm-bindgen = [\"dep:wasm-bindgen\", \"dep:wasm-bindgen-futures\"]\n\n[dependencies]\ndasp_sample = \"0.11\"\n\n[dev-dependencies]\nanyhow = \"1.0\"\nhound = \"3.5\"\nringbuf = \"0.4\"\n\n[dev-dependencies.clap]\nversion = \">=4.6, <5\"\nfeatures = [\"derive\"]\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies]\nwindows-core = \"0.62\"\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.windows]\nversion = \"0.62\"\nfeatures = [\"Win32_Media\", \"Win32_Media_Audio\", \"Win32_Foundation\", \"Win32_Devices_Properties\", \"Win32_Media_KernelStreaming\", \"Win32_System_Com_StructuredStorage\", \"Win32_System_Threading\", \"Win32_System_Performance\", \"Win32_Security\", \"Win32_System_SystemServices\", \"Win32_System_Variant\", \"Win32_Media_Multimedia\", \"Win32_UI_Shell_PropertiesSystem\"]\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.audio_thread_priority]\nversion = \"0.35\"\noptional = true\ndefault-features = false\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.asio-sys]\nversion = \"0.3.0\"\npath = \"asio-sys\"\noptional = true\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.num-traits]\nversion = \"0.2\"\noptional = true\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.jack]\nversion = \"0.13.5\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies]\nalsa = \"0.11\"\nlibc = \"0.2\"\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.alsa-sys]\nversion = \"0.4\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.audio_thread_priority]\nversion = \"0.35\"\noptional = true\ndefault-features = false\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.jack]\nversion = \"0.13.5\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.pulseaudio]\nversion = \"0.3\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.futures]\nversion = \"0.3\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.pipewire]\nversion = \"0.10\"\noptional = true\nfeatures = [\"v0_3_53\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies]\nmach2 = \"0.6\"\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.coreaudio-rs]\nversion = \"0.14.2\"\ndefault-features = false\nfeatures = [\"core_audio\", \"audio_toolbox\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-core-audio]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"AudioHardware\", \"AudioHardwareDeprecated\", \"objc2\", \"objc2-foundation\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-audio-toolbox]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"AUComponent\", \"AudioUnitProperties\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-core-audio-types]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"CoreAudioBaseTypes\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-core-foundation]\nversion = \"0.3\"\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-foundation]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"NSArray\", \"NSString\", \"NSValue\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2]\nversion = \"0.6\"\n\n[target.\"cfg(target_os = \\\"macos\\\")\".dependencies.jack]\nversion = \"0.13.5\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"tvos\\\"))\".dependencies]\nblock2 = \"0.6\"\n\n[target.\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"tvos\\\"))\".dependencies.objc2-foundation]\nversion = \"0.3\"\nfeatures = [\"block2\", \"NSDictionary\", \"NSNotification\", \"NSOperation\"]\n\n[target.\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"tvos\\\"))\".dependencies.objc2-avf-audio]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"AVAudioSession\", \"AVAudioSessionTypes\"]\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.wasm-bindgen]\nversion = \"0.2\"\noptional = true\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.wasm-bindgen-futures]\nversion = \"0.4\"\noptional = true\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.js-sys]\nversion = \"0.3\"\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.web-sys]\nversion = \"0.3\"\nfeatures = [\"AudioContext\", \"AudioContextOptions\", \"AudioBuffer\", \"AudioBufferSourceNode\", \"AudioNode\", \"AudioDestinationNode\", \"Window\", \"AudioContextState\"]\n\n[target.\"cfg(target_os = \\\"android\\\")\".dependencies]\nndk-context = \"0.1\"\njni = \"0.22\"\nlibc = \"0.2\"\nnum-derive = \"0.4\"\nnum-traits = \"0.2\"\n\n[target.\"cfg(target_os = \\\"android\\\")\".dependencies.audio_thread_priority]\nversion = \"0.35\"\noptional = true\ndefault-features = false\n\n[target.\"cfg(target_os = \\\"android\\\")\".dependencies.ndk]\nversion = \"0.9\"\ndefault-features = false\nfeatures = [\"audio\", \"api-level-26\"]\n\n[[example]]\nname = \"beep\"\n\n[[example]]\nname = \"enumerate\"\n\n[[example]]\nname = \"feedback\"\n\n[[example]]\nname = \"record_wav\"\n\n[[example]]\nname = \"synth_tones\"\n", + "contents": "[package]\nname = \"cpal\"\nversion = \"0.18.1\"\ndescription = \"Low-level cross-platform audio I/O library.\"\nrepository = \"https://github.com/RustAudio/cpal\"\ndocumentation = \"https://docs.rs/cpal\"\nlicense = \"Apache-2.0\"\nkeywords = [\"audio\", \"sound\"]\nedition = \"2021\"\nrust-version = \"1.85\"\n\n[package.metadata.docs.rs]\nfeatures = [\"asio\", \"audioworklet\", \"custom\", \"jack\", \"pulseaudio\", \"realtime\", \"realtime-dbus\", \"wasm-bindgen\"]\nrustdoc-args = [\"--cfg\", \"docsrs\"]\ntargets = [\"x86_64-unknown-linux-gnu\", \"x86_64-pc-windows-msvc\", \"x86_64-apple-darwin\", \"aarch64-apple-darwin\", \"aarch64-apple-ios\", \"wasm32-unknown-unknown\", \"aarch64-linux-android\", \"x86_64-unknown-freebsd\", \"x86_64-unknown-netbsd\", \"x86_64-unknown-dragonfly\"]\n\n[badges.maintenance]\nstatus = \"actively-developed\"\n\n[features]\ndefault = []\nrealtime = [\"dep:audio_thread_priority\", \"dep:alsa-sys\"]\nrealtime-dbus = [\"realtime\", \"audio_thread_priority/with_dbus\"]\nasio = [\"dep:asio-sys\", \"dep:num-traits\"]\naudioworklet = [\"wasm-bindgen\", \"web-sys/Blob\", \"web-sys/BlobPropertyBag\", \"web-sys/Url\", \"web-sys/AudioWorklet\", \"web-sys/AudioWorkletNode\", \"web-sys/AudioWorkletNodeOptions\"]\ncustom = []\njack = [\"dep:jack\"]\npipewire = [\"dep:pipewire\"]\npulseaudio = [\"dep:pulseaudio\", \"dep:futures\"]\nwasm-bindgen = [\"dep:wasm-bindgen\", \"dep:wasm-bindgen-futures\"]\n\n[dependencies]\ndasp_sample = \"0.11\"\n\n[dev-dependencies]\nanyhow = \"1.0\"\nhound = \"3.5\"\nringbuf = \"0.4\"\n\n[dev-dependencies.clap]\nversion = \">=4.6, <5\"\nfeatures = [\"derive\"]\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies]\nwindows-core = \"0.62\"\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.windows]\nversion = \"0.62\"\nfeatures = [\"Win32_Media\", \"Win32_Media_Audio\", \"Win32_Foundation\", \"Win32_Devices_Properties\", \"Win32_Media_KernelStreaming\", \"Win32_System_Com_StructuredStorage\", \"Win32_System_Threading\", \"Win32_System_Performance\", \"Win32_Security\", \"Win32_System_SystemServices\", \"Win32_System_Variant\", \"Win32_Media_Multimedia\", \"Win32_UI_Shell_PropertiesSystem\"]\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.audio_thread_priority]\nversion = \"0.35\"\noptional = true\ndefault-features = false\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.asio-sys]\nversion = \"0.3.0\"\npath = \"asio-sys\"\noptional = true\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.num-traits]\nversion = \"0.2\"\noptional = true\n\n[target.\"cfg(target_os = \\\"windows\\\")\".dependencies.jack]\nversion = \"0.13.5\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies]\nalsa = \"0.11\"\nlibc = \"0.2\"\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.alsa-sys]\nversion = \"0.4\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.audio_thread_priority]\nversion = \"0.35\"\noptional = true\ndefault-features = false\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.jack]\nversion = \"0.13.5\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.pulseaudio]\nversion = \"0.3\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.futures]\nversion = \"0.3\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"linux\\\", target_os = \\\"dragonfly\\\", target_os = \\\"freebsd\\\", target_os = \\\"netbsd\\\"))\".dependencies.pipewire]\nversion = \"0.10\"\noptional = true\nfeatures = [\"v0_3_53\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies]\nmach2 = \"0.6\"\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.coreaudio-rs]\nversion = \"0.14.2\"\ndefault-features = false\nfeatures = [\"core_audio\", \"audio_toolbox\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-core-audio]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"AudioHardware\", \"AudioHardwareDeprecated\", \"objc2\", \"objc2-foundation\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-audio-toolbox]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"AUComponent\", \"AudioUnitProperties\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-core-audio-types]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"CoreAudioBaseTypes\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-core-foundation]\nversion = \"0.3.1\"\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2-foundation]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"NSArray\", \"NSString\", \"NSValue\"]\n\n[target.\"cfg(target_vendor = \\\"apple\\\")\".dependencies.objc2]\nversion = \"0.6\"\n\n[target.\"cfg(target_os = \\\"macos\\\")\".dependencies.jack]\nversion = \"0.13.5\"\noptional = true\n\n[target.\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"tvos\\\"))\".dependencies]\nblock2 = \"0.6\"\n\n[target.\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"tvos\\\"))\".dependencies.objc2-foundation]\nversion = \"0.3\"\nfeatures = [\"block2\", \"NSDictionary\", \"NSNotification\", \"NSOperation\"]\n\n[target.\"cfg(any(target_os = \\\"ios\\\", target_os = \\\"tvos\\\"))\".dependencies.objc2-avf-audio]\nversion = \"0.3\"\ndefault-features = false\nfeatures = [\"std\", \"AVAudioSession\", \"AVAudioSessionTypes\"]\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.wasm-bindgen]\nversion = \"0.2\"\noptional = true\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.wasm-bindgen-futures]\nversion = \"0.4\"\noptional = true\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.js-sys]\nversion = \"0.3\"\n\n[target.\"cfg(all(target_arch = \\\"wasm32\\\", target_os = \\\"unknown\\\"))\".dependencies.web-sys]\nversion = \"0.3\"\nfeatures = [\"AudioContext\", \"AudioContextOptions\", \"AudioBuffer\", \"AudioBufferSourceNode\", \"AudioNode\", \"AudioDestinationNode\", \"Window\", \"AudioContextState\"]\n\n[target.\"cfg(target_os = \\\"android\\\")\".dependencies]\nndk-context = \"0.1\"\njni = \"0.22\"\nlibc = \"0.2\"\nnum-derive = \"0.4\"\nnum-traits = \"0.2\"\n\n[target.\"cfg(target_os = \\\"android\\\")\".dependencies.audio_thread_priority]\nversion = \"0.35\"\noptional = true\ndefault-features = false\n\n[target.\"cfg(target_os = \\\"android\\\")\".dependencies.ndk]\nversion = \"0.9\"\ndefault-features = false\nfeatures = [\"audio\", \"api-level-26\"]\n\n[[example]]\nname = \"beep\"\n\n[[example]]\nname = \"enumerate\"\n\n[[example]]\nname = \"feedback\"\n\n[[example]]\nname = \"record_wav\"\n\n[[example]]\nname = \"synth_tones\"\n", "dest": "cargo/vendor/cpal", "dest-filename": "Cargo.toml" }, @@ -1992,6 +1992,19 @@ "dest": "cargo/vendor/getrandom-0.3.4", "dest-filename": ".cargo-checksum.json" }, + { + "type": "archive", + "archive-type": "tar-gzip", + "url": "https://static.crates.io/crates/getrandom/getrandom-0.4.3.crate", + "sha256": "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099", + "dest": "cargo/vendor/getrandom-0.4.3" + }, + { + "type": "inline", + "contents": "{\"package\": \"300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099\", \"files\": {}}", + "dest": "cargo/vendor/getrandom-0.4.3", + "dest-filename": ".cargo-checksum.json" + }, { "type": "archive", "archive-type": "tar-gzip", @@ -2125,14 +2138,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/h2/h2-0.4.14.crate", - "sha256": "171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733", - "dest": "cargo/vendor/h2-0.4.14" + "url": "https://static.crates.io/crates/h2/h2-0.4.15.crate", + "sha256": "6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155", + "dest": "cargo/vendor/h2-0.4.15" }, { "type": "inline", - "contents": "{\"package\": \"171fefbc92fe4a4de27e0698d6a5b392d6a0e333506bc49133760b3bcf948733\", \"files\": {}}", - "dest": "cargo/vendor/h2-0.4.14", + "contents": "{\"package\": \"6cb093c84e8bd9b188d4c4a8cb6579fc016968d14c99882163cd3ff402a4f155\", \"files\": {}}", + "dest": "cargo/vendor/h2-0.4.15", "dest-filename": ".cargo-checksum.json" }, { @@ -2671,14 +2684,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/js-sys/js-sys-0.3.102.crate", - "sha256": "03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31", - "dest": "cargo/vendor/js-sys-0.3.102" + "url": "https://static.crates.io/crates/js-sys/js-sys-0.3.103.crate", + "sha256": "53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102", + "dest": "cargo/vendor/js-sys-0.3.103" }, { "type": "inline", - "contents": "{\"package\": \"03d04c30968dffe80775bd4d7fb676131cd04a1fb46d2686dbffbaec2d9dfd31\", \"files\": {}}", - "dest": "cargo/vendor/js-sys-0.3.102", + "contents": "{\"package\": \"53b44bfcdb3f8d5837a46dae1ca9660a837176eee74a28b229bc626816589102\", \"files\": {}}", + "dest": "cargo/vendor/js-sys-0.3.103", "dest-filename": ".cargo-checksum.json" }, { @@ -2905,14 +2918,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/log/log-0.4.32.crate", - "sha256": "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a", - "dest": "cargo/vendor/log-0.4.32" + "url": "https://static.crates.io/crates/log/log-0.4.33.crate", + "sha256": "0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad", + "dest": "cargo/vendor/log-0.4.33" }, { "type": "inline", - "contents": "{\"package\": \"953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a\", \"files\": {}}", - "dest": "cargo/vendor/log-0.4.32", + "contents": "{\"package\": \"0ceec5bc11778974d1bcb055b18002eba7f4b3518b6a0081b3af5f21666da9ad\", \"files\": {}}", + "dest": "cargo/vendor/log-0.4.33", "dest-filename": ".cargo-checksum.json" }, { @@ -2957,14 +2970,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/memmap2/memmap2-0.9.10.crate", - "sha256": "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3", - "dest": "cargo/vendor/memmap2-0.9.10" + "url": "https://static.crates.io/crates/memmap2/memmap2-0.9.11.crate", + "sha256": "d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0", + "dest": "cargo/vendor/memmap2-0.9.11" }, { "type": "inline", - "contents": "{\"package\": \"714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3\", \"files\": {}}", - "dest": "cargo/vendor/memmap2-0.9.10", + "contents": "{\"package\": \"d1219ed1b7f229ee7104d281dd01d6802fe28bb6e95d292942c4daacdeb798c0\", \"files\": {}}", + "dest": "cargo/vendor/memmap2-0.9.11", "dest-filename": ".cargo-checksum.json" }, { @@ -4166,27 +4179,27 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/quinn/quinn-0.11.9.crate", - "sha256": "b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20", - "dest": "cargo/vendor/quinn-0.11.9" + "url": "https://static.crates.io/crates/quinn/quinn-0.11.11.crate", + "sha256": "0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8", + "dest": "cargo/vendor/quinn-0.11.11" }, { "type": "inline", - "contents": "{\"package\": \"b9e20a958963c291dc322d98411f541009df2ced7b5a4f2bd52337638cfccf20\", \"files\": {}}", - "dest": "cargo/vendor/quinn-0.11.9", + "contents": "{\"package\": \"0c1a41e437b6bbd489372cd4971de128e85c855f56c57f283d20ff016cf7c0a8\", \"files\": {}}", + "dest": "cargo/vendor/quinn-0.11.11", "dest-filename": ".cargo-checksum.json" }, { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/quinn-proto/quinn-proto-0.11.14.crate", - "sha256": "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098", - "dest": "cargo/vendor/quinn-proto-0.11.14" + "url": "https://static.crates.io/crates/quinn-proto/quinn-proto-0.11.15.crate", + "sha256": "4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e", + "dest": "cargo/vendor/quinn-proto-0.11.15" }, { "type": "inline", - "contents": "{\"package\": \"434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098\", \"files\": {}}", - "dest": "cargo/vendor/quinn-proto-0.11.14", + "contents": "{\"package\": \"4fcb935c5bec503c2f0e306bdd3e58bb9029dcb14fa8d9ac76e3a5256ac0763e\", \"files\": {}}", + "dest": "cargo/vendor/quinn-proto-0.11.15", "dest-filename": ".cargo-checksum.json" }, { @@ -4205,14 +4218,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/quote/quote-1.0.45.crate", - "sha256": "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924", - "dest": "cargo/vendor/quote-1.0.45" + "url": "https://static.crates.io/crates/quote/quote-1.0.46.crate", + "sha256": "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368", + "dest": "cargo/vendor/quote-1.0.46" }, { "type": "inline", - "contents": "{\"package\": \"41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924\", \"files\": {}}", - "dest": "cargo/vendor/quote-1.0.45", + "contents": "{\"package\": \"dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368\", \"files\": {}}", + "dest": "cargo/vendor/quote-1.0.46", "dest-filename": ".cargo-checksum.json" }, { @@ -4228,6 +4241,19 @@ "dest": "cargo/vendor/r-efi-5.3.0", "dest-filename": ".cargo-checksum.json" }, + { + "type": "archive", + "archive-type": "tar-gzip", + "url": "https://static.crates.io/crates/r-efi/r-efi-6.0.0.crate", + "sha256": "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf", + "dest": "cargo/vendor/r-efi-6.0.0" + }, + { + "type": "inline", + "contents": "{\"package\": \"f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf\", \"files\": {}}", + "dest": "cargo/vendor/r-efi-6.0.0", + "dest-filename": ".cargo-checksum.json" + }, { "type": "archive", "archive-type": "tar-gzip", @@ -4652,14 +4678,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/rustls/rustls-0.23.40.crate", - "sha256": "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b", - "dest": "cargo/vendor/rustls-0.23.40" + "url": "https://static.crates.io/crates/rustls/rustls-0.23.41.crate", + "sha256": "6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f", + "dest": "cargo/vendor/rustls-0.23.41" }, { "type": "inline", - "contents": "{\"package\": \"ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b\", \"files\": {}}", - "dest": "cargo/vendor/rustls-0.23.40", + "contents": "{\"package\": \"6b92b125634d9b795e7beca796cc790df15a7fb38323bf3196fda83292d06b1f\", \"files\": {}}", + "dest": "cargo/vendor/rustls-0.23.41", "dest-filename": ".cargo-checksum.json" }, { @@ -5458,14 +5484,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/syn/syn-2.0.117.crate", - "sha256": "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99", - "dest": "cargo/vendor/syn-2.0.117" + "url": "https://static.crates.io/crates/syn/syn-2.0.118.crate", + "sha256": "1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422", + "dest": "cargo/vendor/syn-2.0.118" }, { "type": "inline", - "contents": "{\"package\": \"e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99\", \"files\": {}}", - "dest": "cargo/vendor/syn-2.0.117", + "contents": "{\"package\": \"1b9ae57f904213ebb649ce6895b8a66c66f0203b9319718f69a5612a065b1422\", \"files\": {}}", + "dest": "cargo/vendor/syn-2.0.118", "dest-filename": ".cargo-checksum.json" }, { @@ -6134,14 +6160,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/uuid/uuid-1.23.3.crate", - "sha256": "144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7", - "dest": "cargo/vendor/uuid-1.23.3" + "url": "https://static.crates.io/crates/uuid/uuid-1.23.4.crate", + "sha256": "bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53", + "dest": "cargo/vendor/uuid-1.23.4" }, { "type": "inline", - "contents": "{\"package\": \"144d6b123cef80b301b8f72a9e2ca4370ddec21950d0a103dd22c437006d2db7\", \"files\": {}}", - "dest": "cargo/vendor/uuid-1.23.3", + "contents": "{\"package\": \"bf80a72845275afea99e7f2b434723d3bc7e38470fcd1c7ed39a599c73319a53\", \"files\": {}}", + "dest": "cargo/vendor/uuid-1.23.4", "dest-filename": ".cargo-checksum.json" }, { @@ -6251,66 +6277,66 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/wasm-bindgen/wasm-bindgen-0.2.125.crate", - "sha256": "8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a", - "dest": "cargo/vendor/wasm-bindgen-0.2.125" + "url": "https://static.crates.io/crates/wasm-bindgen/wasm-bindgen-0.2.126.crate", + "sha256": "4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4", + "dest": "cargo/vendor/wasm-bindgen-0.2.126" }, { "type": "inline", - "contents": "{\"package\": \"8ddb3f79143bced6de84270411622a2699cee572fc0875aeaf1e7867cf9fca1a\", \"files\": {}}", - "dest": "cargo/vendor/wasm-bindgen-0.2.125", + "contents": "{\"package\": \"4b067c0c11094aef6b7a801c1e34a26affafdf3d051dba08456b868789aaf9a4\", \"files\": {}}", + "dest": "cargo/vendor/wasm-bindgen-0.2.126", "dest-filename": ".cargo-checksum.json" }, { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/wasm-bindgen-futures/wasm-bindgen-futures-0.4.75.crate", - "sha256": "503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280", - "dest": "cargo/vendor/wasm-bindgen-futures-0.4.75" + "url": "https://static.crates.io/crates/wasm-bindgen-futures/wasm-bindgen-futures-0.4.76.crate", + "sha256": "c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d", + "dest": "cargo/vendor/wasm-bindgen-futures-0.4.76" }, { "type": "inline", - "contents": "{\"package\": \"503b14d284f2c8dac03b819967e155ea753f573586193b2b2c95990cb5d69280\", \"files\": {}}", - "dest": "cargo/vendor/wasm-bindgen-futures-0.4.75", + "contents": "{\"package\": \"c62df1340f32221cb9c54d6a27b030e3dba64361d4a95bed55f9aacb44da291d\", \"files\": {}}", + "dest": "cargo/vendor/wasm-bindgen-futures-0.4.76", "dest-filename": ".cargo-checksum.json" }, { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/wasm-bindgen-macro/wasm-bindgen-macro-0.2.125.crate", - "sha256": "4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d", - "dest": "cargo/vendor/wasm-bindgen-macro-0.2.125" + "url": "https://static.crates.io/crates/wasm-bindgen-macro/wasm-bindgen-macro-0.2.126.crate", + "sha256": "167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1", + "dest": "cargo/vendor/wasm-bindgen-macro-0.2.126" }, { "type": "inline", - "contents": "{\"package\": \"4e21a184b13fb19e157296e2c46056aec9092264fab83e4ba59e68c61b323c3d\", \"files\": {}}", - "dest": "cargo/vendor/wasm-bindgen-macro-0.2.125", + "contents": "{\"package\": \"167ce5e579f6bcf889c4f7175a8a5a585de84e8ff93976ce393efa5f2837aab1\", \"files\": {}}", + "dest": "cargo/vendor/wasm-bindgen-macro-0.2.126", "dest-filename": ".cargo-checksum.json" }, { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/wasm-bindgen-macro-support/wasm-bindgen-macro-support-0.2.125.crate", - "sha256": "fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd", - "dest": "cargo/vendor/wasm-bindgen-macro-support-0.2.125" + "url": "https://static.crates.io/crates/wasm-bindgen-macro-support/wasm-bindgen-macro-support-0.2.126.crate", + "sha256": "f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e", + "dest": "cargo/vendor/wasm-bindgen-macro-support-0.2.126" }, { "type": "inline", - "contents": "{\"package\": \"fecefd9c35bd935a20fc3fc344b5f29138961e4f47fb03297d88f2587afb5ebd\", \"files\": {}}", - "dest": "cargo/vendor/wasm-bindgen-macro-support-0.2.125", + "contents": "{\"package\": \"f3997c7839262f4ef12cf90b818d6340c18e80f263f1a94bf157d0ec4420380e\", \"files\": {}}", + "dest": "cargo/vendor/wasm-bindgen-macro-support-0.2.126", "dest-filename": ".cargo-checksum.json" }, { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/wasm-bindgen-shared/wasm-bindgen-shared-0.2.125.crate", - "sha256": "23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f", - "dest": "cargo/vendor/wasm-bindgen-shared-0.2.125" + "url": "https://static.crates.io/crates/wasm-bindgen-shared/wasm-bindgen-shared-0.2.126.crate", + "sha256": "dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24", + "dest": "cargo/vendor/wasm-bindgen-shared-0.2.126" }, { "type": "inline", - "contents": "{\"package\": \"23939e44bb9a5d7576fa2b563dc2e136628f1224e88a8deed09e04858b77871f\", \"files\": {}}", - "dest": "cargo/vendor/wasm-bindgen-shared-0.2.125", + "contents": "{\"package\": \"dc1b4cb0cc549fcf58d7dfc081778139b3d283a081644e833e84682ad71cea24\", \"files\": {}}", + "dest": "cargo/vendor/wasm-bindgen-shared-0.2.126", "dest-filename": ".cargo-checksum.json" }, { @@ -6368,14 +6394,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/wayland-protocols/wayland-protocols-0.32.12.crate", - "sha256": "563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f", - "dest": "cargo/vendor/wayland-protocols-0.32.12" + "url": "https://static.crates.io/crates/wayland-protocols/wayland-protocols-0.32.13.crate", + "sha256": "23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6", + "dest": "cargo/vendor/wayland-protocols-0.32.13" }, { "type": "inline", - "contents": "{\"package\": \"563a85523cade2429938e790815fd7319062103b9f4a2dc806e9b53b95982d8f\", \"files\": {}}", - "dest": "cargo/vendor/wayland-protocols-0.32.12", + "contents": "{\"package\": \"23d0c813de3daa2ed6520af85a3bd49b0e722a3078506899aa9686fea58dc4b6\", \"files\": {}}", + "dest": "cargo/vendor/wayland-protocols-0.32.13", "dest-filename": ".cargo-checksum.json" }, { @@ -6459,14 +6485,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/web-sys/web-sys-0.3.102.crate", - "sha256": "a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d", - "dest": "cargo/vendor/web-sys-0.3.102" + "url": "https://static.crates.io/crates/web-sys/web-sys-0.3.103.crate", + "sha256": "8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141", + "dest": "cargo/vendor/web-sys-0.3.103" }, { "type": "inline", - "contents": "{\"package\": \"a6430a72df5eb332242960fe84b3002a241163998241eb596d4f739b9757061d\", \"files\": {}}", - "dest": "cargo/vendor/web-sys-0.3.102", + "contents": "{\"package\": \"8622dcb61c0bcc9fffa6938bed81210af2da9a7e4a1a834b2e37a59b6dfb6141\", \"files\": {}}", + "dest": "cargo/vendor/web-sys-0.3.103", "dest-filename": ".cargo-checksum.json" }, { @@ -6498,14 +6524,14 @@ { "type": "archive", "archive-type": "tar-gzip", - "url": "https://static.crates.io/crates/webpki-root-certs/webpki-root-certs-1.0.7.crate", - "sha256": "f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c", - "dest": "cargo/vendor/webpki-root-certs-1.0.7" + "url": "https://static.crates.io/crates/webpki-root-certs/webpki-root-certs-1.0.8.crate", + "sha256": "0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267", + "dest": "cargo/vendor/webpki-root-certs-1.0.8" }, { "type": "inline", - "contents": "{\"package\": \"f31141ce3fc3e300ae89b78c0dd67f9708061d1d2eda54b8209346fd6be9a92c\", \"files\": {}}", - "dest": "cargo/vendor/webpki-root-certs-1.0.7", + "contents": "{\"package\": \"0d46a5a140e6f7afeccd8eae97eff335163939eac8b929834875168b29b3d267\", \"files\": {}}", + "dest": "cargo/vendor/webpki-root-certs-1.0.8", "dest-filename": ".cargo-checksum.json" }, { diff --git a/pwsp-daemon/src/main.rs b/pwsp-daemon/src/main.rs index 1129806..87cc27e 100644 --- a/pwsp-daemon/src/main.rs +++ b/pwsp-daemon/src/main.rs @@ -28,10 +28,7 @@ async fn main() -> Result<()> { } get_daemon_config(); // Initialize daemon config - - // Virtual mic object must be kept alive by some variable until daemon exits - let _virtual_mic = create_virtual_mic().await?; - + create_virtual_mic()?; if let Err(err) = get_audio_player().await { eprintln!("Failed to initialize audio player: {}", err); } // Initialize audio player diff --git a/pwsp-gui/src/gui/views/body.rs b/pwsp-gui/src/gui/views/body.rs index 0893543..fae49d5 100644 --- a/pwsp-gui/src/gui/views/body.rs +++ b/pwsp-gui/src/gui/views/body.rs @@ -316,10 +316,9 @@ impl SoundpadGui { .unwrap_or_default() .to_str() .unwrap_or_default(), - ) - { - continue; - } + ) { + continue; + } read.push(child_path); } } @@ -343,16 +342,17 @@ impl SoundpadGui { let search_query = search_query.trim(); for child in children { - if !child.is_dir() && !search_query.is_empty() { - let file_name = child - .file_name() - .unwrap_or_default() - .to_string_lossy() - .to_string(); - if !file_name.to_lowercase().contains(search_query) { - continue; + if !child.is_dir() + && !search_query.is_empty() { + let file_name = child + .file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(); + if !file_name.to_lowercase().contains(search_query) { + continue; + } } - } Self::draw_tree_node(ui, child, config, app_state, audio_player_state, actions); } }); diff --git a/pwsp-lib/src/types/audio_player.rs b/pwsp-lib/src/types/audio_player.rs index f03fd93..0f74193 100644 --- a/pwsp-lib/src/types/audio_player.rs +++ b/pwsp-lib/src/types/audio_player.rs @@ -1,8 +1,8 @@ use crate::{ - types::pipewire::DeviceType, + types::pipewire::{DeviceType, Terminate}, utils::{ daemon::get_daemon_config, - pipewire::{PwTerminator, create_link, get_device, link_player_to_virtual_mic}, + pipewire::{create_link, get_device, link_player_to_virtual_mic}, }, }; use anyhow::{Result, anyhow}; @@ -58,8 +58,8 @@ pub struct AudioPlayer { pub tracks: HashMap, pub next_id: u32, - input_link_sender: Option, - player_link_sender: Option, + input_link_sender: Option>, + player_link_sender: Option>, pub input_device_name: Option, pub volume: f32, // Master volume @@ -108,16 +108,24 @@ impl AudioPlayer { } fn abort_link_thread(&mut self) { - if self.input_link_sender.is_some() { - println!("Sent terminate signal to input link thread"); - self.input_link_sender = None; + if let Some(sender) = &self.input_link_sender { + if sender.send(Terminate {}).is_ok() { + println!("Sent terminate signal to input link thread"); + self.input_link_sender = None; + } else { + eprintln!("Failed to send terminate signal to input link thread"); + } } } fn abort_player_link_thread(&mut self) { - if self.player_link_sender.is_some() { - println!("Sent terminate signal to player link thread"); - self.player_link_sender = None; + if let Some(sender) = &self.player_link_sender { + if sender.send(Terminate {}).is_ok() { + println!("Sent terminate signal to player link thread"); + self.player_link_sender = None; + } else { + eprintln!("Failed to send terminate signal to player link thread"); + } } } @@ -179,7 +187,7 @@ impl AudioPlayer { return Ok(()); }; - self.input_link_sender = Some(create_link(output_fl, output_fr, input_fl, input_fr).await?); + self.input_link_sender = Some(create_link(output_fl, output_fr, input_fl, input_fr)?); Ok(()) } diff --git a/pwsp-lib/src/utils/pipewire.rs b/pwsp-lib/src/utils/pipewire.rs index db9f485..289493d 100644 --- a/pwsp-lib/src/utils/pipewire.rs +++ b/pwsp-lib/src/utils/pipewire.rs @@ -1,224 +1,14 @@ -use crate::types::pipewire::{AudioDevice, DeviceType, Port}; +use crate::types::pipewire::{AudioDevice, DeviceType, Port, Terminate}; use anyhow::{Result, anyhow}; use pipewire::{ context::ContextRc, link::Link, main_loop::MainLoopRc, properties::properties, registry::GlobalObject, spa::utils::dict::DictRef, }; -use std::{cell::RefCell, collections::HashMap, rc::Rc, sync::OnceLock, thread}; -use tokio::sync::oneshot; - -pub enum PwCommand { - GetDevices { - resp: oneshot::Sender<(Vec, Vec)>, - }, - CreateVirtualMic { - resp: oneshot::Sender>, - }, - CreateLink { - output_fl: Port, - output_fr: Port, - input_fl: Port, - input_fr: Port, - resp: oneshot::Sender>, - }, - DestroyObject { - id: u32, - }, -} - -struct AppState { - input_devices: HashMap, - output_devices: HashMap, - ports: HashMap, - proxies: HashMap>, - proxy_id_counter: u32, - ready_tx: Option>, -} - -pub struct PipewireManager { - pub sender: pipewire::channel::Sender, -} - -static MANAGER: OnceLock = OnceLock::new(); - -pub fn get_manager() -> &'static PipewireManager { - MANAGER.get_or_init(|| { - let (pw_sender, pw_receiver) = pipewire::channel::channel::(); - let (ready_tx, ready_rx) = std::sync::mpsc::channel(); - - thread::spawn(move || { - let (main_loop, context) = setup_pipewire_context().expect("Failed to setup pipewire"); - - // Leak main_loop and context so their borrows can be 'static - let main_loop = Box::leak(Box::new(main_loop)); - let context = Box::leak(Box::new(context)); - - // Leak to fix lifetime issues since this thread lives forever - let core = Box::leak(Box::new( - context - .connect(None) - .expect("Failed to connect to pipewire"), - )); - let registry = Box::leak(Box::new( - core.get_registry().expect("Failed to get registry"), - )); - - let state = Rc::new(RefCell::new(AppState { - input_devices: HashMap::new(), - output_devices: HashMap::new(), - ports: HashMap::new(), - proxies: HashMap::new(), - proxy_id_counter: 10000, - ready_tx: Some(ready_tx), - })); - - let state_for_registry_add = state.clone(); - let state_for_registry_remove = state.clone(); - - let _listener = registry - .add_listener_local() - .global(move |global| { - let (device, port) = parse_global_object(global); - let mut s = state_for_registry_add.borrow_mut(); - if let Some(device) = device { - match device.device_type { - DeviceType::Input => { - s.input_devices.insert(device.id, device); - } - DeviceType::Output => { - s.output_devices.insert(device.id, device); - } - } - } else if let Some(port) = port { - let node_id = port.node_id; - s.ports.insert(port.port_id, port.clone()); - if let Some(d) = s.input_devices.get_mut(&node_id) { - d.add_port(port.clone()); - } else if let Some(d) = s.output_devices.get_mut(&node_id) { - d.add_port(port); - } - } - }) - .global_remove(move |id| { - let mut s = state_for_registry_remove.borrow_mut(); - s.input_devices.remove(&id); - s.output_devices.remove(&id); - s.ports.retain(|_, port| port.node_id != id); - s.ports.remove(&id); - }) - .register(); - - // sync to signal ready - let state_for_sync = state.clone(); - let _core_listener = core - .add_listener_local() - .done(move |id, _seq| { - if id == 0 { - let mut s = state_for_sync.borrow_mut(); - if let Some(tx) = s.ready_tx.take() { - let _ = tx.send(()); - } - } - }) - .register(); - - let _pending = core.sync(0).expect("sync failed"); - - let state_for_cmd = state.clone(); - let _receiver = pw_receiver.attach(main_loop.loop_(), move |cmd| { - let mut s = state_for_cmd.borrow_mut(); - match cmd { - PwCommand::GetDevices { resp } => { - let mut inputs: Vec = - s.input_devices.values().cloned().collect(); - let mut outputs: Vec = - s.output_devices.values().cloned().collect(); - inputs.sort_by_key(|a| a.id); - outputs.sort_by_key(|a| a.id); - let _ = resp.send((inputs, outputs)); - } - PwCommand::CreateVirtualMic { resp } => { - let props = properties!( - "factory.name" => "support.null-audio-sink", - "node.name" => "pwsp-virtual-mic", - "node.description" => "PWSP Virtual Mic", - "media.class" => "Audio/Source/Virtual", - "audio.position" => "[ FL FR ]", - "audio.channels" => "2", - "object.linger" => "false", - ); - match core.create_object::("adapter", &props) { - Ok(node) => { - s.proxy_id_counter += 1; - let id = s.proxy_id_counter; - s.proxies.insert(id, Box::new(node)); - let _ = resp.send(Ok(id)); - } - Err(e) => { - let _ = resp.send(Err(e.to_string())); - } - } - } - PwCommand::CreateLink { - output_fl, - output_fr, - input_fl, - input_fr, - resp, - } => { - let props_fl = properties! { - "link.output.node" => format!("{}", output_fl.node_id).as_str(), - "link.output.port" => format!("{}", output_fl.port_id).as_str(), - "link.input.node" => format!("{}", input_fl.node_id).as_str(), - "link.input.port" => format!("{}", input_fl.port_id).as_str(), - }; - let props_fr = properties! { - "link.output.node" => format!("{}", output_fr.node_id).as_str(), - "link.output.port" => format!("{}", output_fr.port_id).as_str(), - "link.input.node" => format!("{}", input_fr.node_id).as_str(), - "link.input.port" => format!("{}", input_fr.port_id).as_str(), - }; - - let link_fl = match core.create_object::("link-factory", &props_fl) { - Ok(link) => link, - Err(e) => { - let _ = resp.send(Err(e.to_string())); - return; - } - }; - let link_fr = match core.create_object::("link-factory", &props_fr) { - Ok(link) => link, - Err(e) => { - let _ = resp.send(Err(e.to_string())); - return; - } - }; - - s.proxy_id_counter += 1; - let id_fl = s.proxy_id_counter; - s.proxies.insert(id_fl, Box::new(link_fl)); - - s.proxy_id_counter += 1; - let id_fr = s.proxy_id_counter; - s.proxies.insert(id_fr, Box::new(link_fr)); - - let _ = resp.send(Ok((id_fl, id_fr))); - } - PwCommand::DestroyObject { id } => { - s.proxies.remove(&id); - } - } - }); - - main_loop.run(); - }); - - // Wait for the pipewire thread to be fully up and processed initial events - let _ = ready_rx.recv(); - - PipewireManager { sender: pw_sender } - }) -} +use std::{collections::HashMap, thread}; +use tokio::{ + sync::mpsc, + time::{Duration, timeout}, +}; pub fn setup_pipewire_context() -> Result<(MainLoopRc, ContextRc), String> { pipewire::init(); @@ -281,17 +71,127 @@ fn parse_global_object( (None, None) } +async fn pw_get_global_objects_thread( + main_sender: mpsc::Sender<(Option, Option)>, + pw_receiver: pipewire::channel::Receiver, + init_sender: tokio::sync::oneshot::Sender>, +) { + let (main_loop, context) = match setup_pipewire_context() { + Ok(res) => res, + Err(e) => { + let _ = init_sender.send(Err(e)); + return; + } + }; + + // Stop main loop on Terminate message + let _receiver = pw_receiver.attach(main_loop.loop_(), { + let _main_loop = main_loop.clone(); + move |_| _main_loop.quit() + }); + + let core = match context.connect(None) { + Ok(core) => core, + Err(e) => { + let _ = init_sender.send(Err(format!("Failed to connect to pipewire context: {}", e))); + return; + } + }; + + let registry = match core.get_registry() { + Ok(registry) => registry, + Err(e) => { + let _ = init_sender.send(Err(format!( + "Failed to get registry from pipewire context: {}", + e + ))); + return; + } + }; + + let _listener = registry + .add_listener_local() + .global(move |global| { + // Try to parse every global object pipewire finds + let (device, port) = parse_global_object(global); + + // Send message to the main thread + let sender_clone = main_sender.clone(); + tokio::task::spawn(async move { + sender_clone.send((device, port)).await.ok(); + }); + }) + .register(); + + // Signal successful initialization + if init_sender.send(Ok(())).is_err() { + return; + } + + main_loop.run(); +} + pub async fn get_all_devices() -> Result<(Vec, Vec)> { - let (tx, rx) = oneshot::channel(); - let manager = get_manager(); - manager - .sender - .send(PwCommand::GetDevices { resp: tx }) - .map_err(|_| anyhow!("Failed to send GetDevices to manager"))?; - let res = rx - .await - .map_err(|e| anyhow!("Failed to receive response: {}", e))?; - Ok(res) + // Channels to communicate with pipewire thread + let (main_sender, mut main_receiver) = mpsc::channel(10); + let (pw_sender, pw_receiver) = pipewire::channel::channel(); + let (init_sender, init_receiver) = tokio::sync::oneshot::channel(); + + // Spawn pipewire thread in background + let _pw_thread = tokio::spawn(async move { + pw_get_global_objects_thread(main_sender, pw_receiver, init_sender).await + }); + + // Wait for initialization to complete + if let Err(e) = init_receiver.await { + return Err(anyhow!(e)); + } + + let mut input_devices: HashMap = HashMap::new(); + let mut output_devices: HashMap = HashMap::new(); + let mut ports: Vec = vec![]; + + loop { + // If we don't receive a message in 100ms, we can assume that pipewire thread is finished + match timeout(Duration::from_millis(100), main_receiver.recv()).await { + Ok(Some((device, port))) => { + if let Some(device) = device { + match device.device_type { + DeviceType::Input => { + input_devices.insert(device.id, device); + } + DeviceType::Output => { + output_devices.insert(device.id, device); + } + } + } else if let Some(port) = port { + ports.push(port); + } + } + Ok(None) | Err(_) => { + // Pipewire thread is finished and we can collect our devices + let _ = pw_sender.send(Terminate {}); + + for port in ports { + let node_id = port.node_id; + + if let Some(input_device) = input_devices.get_mut(&node_id) { + input_device.add_port(port); + } else if let Some(output_device) = output_devices.get_mut(&node_id) { + output_device.add_port(port); + } + } + + let mut input_devices: Vec = input_devices.into_values().collect(); + let mut output_devices: Vec = output_devices.into_values().collect(); + + input_devices.sort_by_key(|a| a.id); + output_devices.sort_by_key(|a| a.id); + + return Ok((input_devices, output_devices)); + } + } + } } pub async fn get_device(device_name: &str) -> Result { @@ -309,36 +209,65 @@ pub async fn get_device(device_name: &str) -> Result { .ok_or_else(|| anyhow!("Device not found")) } -pub struct PwTerminator { - ids: Vec, -} +pub fn create_virtual_mic() -> Result> { + let (pw_sender, pw_receiver) = pipewire::channel::channel::(); + let (init_sender, init_receiver) = std::sync::mpsc::sync_channel(0); -impl Drop for PwTerminator { - fn drop(&mut self) { - let manager = get_manager(); - for id in &self.ids { - let _ = manager.sender.send(PwCommand::DestroyObject { id: *id }); + let _pw_thread = thread::spawn(move || { + let (main_loop, context) = match setup_pipewire_context() { + Ok(res) => res, + Err(e) => { + let _ = init_sender.send(Err(e)); + return; + } + }; + let core = match context.connect(None) { + Ok(core) => core, + Err(e) => { + let _ = + init_sender.send(Err(format!("Failed to connect to pipewire context: {}", e))); + return; + } + }; + + let props = properties!( + "factory.name" => "support.null-audio-sink", + "node.name" => "pwsp-virtual-mic", + "node.description" => "PWSP Virtual Mic", + "media.class" => "Audio/Source/Virtual", + "audio.position" => "[ FL FR ]", + "audio.channels" => "2", + "object.linger" => "false", // Destroy the node on app exit + ); + + let _node = match core.create_object::("adapter", &props) { + Ok(node) => node, + Err(e) => { + let _ = init_sender.send(Err(format!("Failed to create virtual mic: {}", e))); + return; + } + }; + + let _receiver = pw_receiver.attach(main_loop.loop_(), { + let _main_loop = main_loop.clone(); + move |_| _main_loop.quit() + }); + + println!("Virtual mic created"); + if init_sender.send(Ok(())).is_err() { + return; } + main_loop.run(); + }); + + if let Err(e) = init_receiver.recv()? { + return Err(anyhow!(e)); } + + Ok(pw_sender) } -pub async fn create_virtual_mic() -> Result { - let (tx, rx) = oneshot::channel(); - let manager = get_manager(); - manager - .sender - .send(PwCommand::CreateVirtualMic { resp: tx }) - .map_err(|_| anyhow!("Failed to send CreateVirtualMic to manager"))?; - - let res = rx - .await - .map_err(|e| anyhow!("Failed to receive response: {}", e))?; - - let id = res.map_err(|e| anyhow!(e))?; - Ok(PwTerminator { ids: vec![id] }) -} - -pub async fn link_player_to_virtual_mic() -> Result { +pub async fn link_player_to_virtual_mic() -> Result> { let pwsp_daemon_output = match get_device("pwsp-daemon").await { Ok(device) => device, Err(_) => { @@ -374,34 +303,81 @@ pub async fn link_player_to_virtual_mic() -> Result { None => return Err(anyhow!("Failed to get pwsp-virtual-mic input_fr")), }; - create_link(output_fl, output_fr, input_fl, input_fr).await + create_link(output_fl, output_fr, input_fl, input_fr) } -pub async fn create_link( +pub fn create_link( output_fl: Port, output_fr: Port, input_fl: Port, input_fr: Port, -) -> Result { - let (tx, rx) = oneshot::channel(); - let manager = get_manager(); - manager - .sender - .send(PwCommand::CreateLink { - output_fl, - output_fr, - input_fl, - input_fr, - resp: tx, - }) - .map_err(|_| anyhow!("Failed to send CreateLink to manager"))?; +) -> Result> { + let (pw_sender, pw_receiver) = pipewire::channel::channel::(); + let (init_sender, init_receiver) = std::sync::mpsc::sync_channel(0); - let res = rx - .await - .map_err(|e| anyhow!("Failed to receive response: {}", e))?; + let _pw_thread = thread::spawn(move || { + let (main_loop, context) = match setup_pipewire_context() { + Ok(res) => res, + Err(e) => { + let _ = init_sender.send(Err(e)); + return; + } + }; + let core = match context.connect(None) { + Ok(core) => core, + Err(e) => { + let _ = + init_sender.send(Err(format!("Failed to connect to pipewire context: {}", e))); + return; + } + }; - let (id_fl, id_fr) = res.map_err(|e| anyhow!(e))?; - Ok(PwTerminator { - ids: vec![id_fl, id_fr], - }) + let props_fl = properties! { + "link.output.node" => format!("{}", output_fl.node_id).as_str(), + "link.output.port" => format!("{}", output_fl.port_id).as_str(), + "link.input.node" => format!("{}", input_fl.node_id).as_str(), + "link.input.port" => format!("{}", input_fl.port_id).as_str(), + }; + let props_fr = properties! { + "link.output.node" => format!("{}", output_fr.node_id).as_str(), + "link.output.port" => format!("{}", output_fr.port_id).as_str(), + "link.input.node" => format!("{}", input_fr.node_id).as_str(), + "link.input.port" => format!("{}", input_fr.port_id).as_str(), + }; + + let _link_fl = match core.create_object::("link-factory", &props_fl) { + Ok(link) => link, + Err(e) => { + let _ = init_sender.send(Err(format!("Failed to create link FL: {}", e))); + return; + } + }; + let _link_fr = match core.create_object::("link-factory", &props_fr) { + Ok(link) => link, + Err(e) => { + let _ = init_sender.send(Err(format!("Failed to create link FR: {}", e))); + return; + } + }; + + let _receiver = pw_receiver.attach(main_loop.loop_(), { + let _main_loop = main_loop.clone(); + move |_| _main_loop.quit() + }); + + println!( + "Link created: FL: {}-{} FR: {}-{}", + output_fl.node_id, input_fl.node_id, output_fr.node_id, input_fr.node_id + ); + if init_sender.send(Ok(())).is_err() { + return; + } + main_loop.run(); + }); + + if let Err(e) = init_receiver.recv()? { + return Err(anyhow!(e)); + } + + Ok(pw_sender) }