From 00b8f69701feabf4494e8d49c8af4891aeeb1daf Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sun, 8 Dec 2024 08:52:59 +0200 Subject: [PATCH 1/6] setup wasm --- BUILDING.md | 10 +++++++ Cargo.lock | 61 ++++++++++++++++++++++++++++++++++++++ Cargo.toml | 8 +++++ crates/aec-rs-sys/build.rs | 4 +++ src/lib.rs | 7 +++++ 5 files changed, 90 insertions(+) diff --git a/BUILDING.md b/BUILDING.md index 1fc5488..82f4a24 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -43,3 +43,13 @@ Build ```console cargo build --release --target aarch64-apple-ios ``` + +## Build for wasm + +```console +rustup target add wasm32-unknown-unknown +rustup target add --toolchain nightly wasm32-unknown-unknown +cargo build --target wasm32-unknown-unknown --features wasm +export RUSTFLAGS="--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec" +cargo +nightly build --target=wasm32-unknown-unknown --release --features wasm +``` diff --git a/Cargo.lock b/Cargo.lock index 48ba09f..cb59ed5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,7 @@ version = "1.0.0" dependencies = [ "aec-rs-sys", "hound", + "wasm-bindgen", ] [[package]] @@ -79,6 +80,12 @@ version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + [[package]] name = "cbindgen" version = "0.26.0" @@ -528,6 +535,60 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.90", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.90", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + [[package]] name = "which" version = "4.4.2" diff --git a/Cargo.toml b/Cargo.toml index b79e5e8..d1a8e4d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,6 +13,14 @@ homepage = "https://github.com/thewh1teagle/aec-rs" [dependencies] aec-rs-sys = { path = "crates/aec-rs-sys", version = "1.0.0" } +wasm-bindgen = { version = "0.2.99", optional = true } + +[lib] +# For wasm +crate-type = ["cdylib", "rlib"] [dev-dependencies] hound = { version = "3.5.1" } + +[features] +wasm = ["dep:wasm-bindgen"] diff --git a/crates/aec-rs-sys/build.rs b/crates/aec-rs-sys/build.rs index 05efca2..e5aa62f 100644 --- a/crates/aec-rs-sys/build.rs +++ b/crates/aec-rs-sys/build.rs @@ -36,9 +36,13 @@ fn main() { copy_folder(&lib_src, &lib_dst); } + let clang_target = env::var("TARGET").unwrap(); let bindings = bindgen::Builder::default() .header("wrapper.h") .clang_arg(format!("-I{}", lib_dst.display())) + // Explicitly set target in case we are cross-compiling. + // See https://github.com/rust-lang/rust-bindgen/issues/1780 for context. + .clang_arg(format!("--target={}", clang_target)) .parse_callbacks(Box::new(bindgen::CargoCallbacks::new())) .generate() .expect("Failed to generate bindings"); diff --git a/src/lib.rs b/src/lib.rs index 5629d6e..89eec44 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,11 @@ +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; + use std::os::raw::c_void; /// See https://www.speex.org/docs/api/speex-api-reference/speex__echo_8h.html #[derive(Debug, Clone)] +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub struct AecConfig { pub frame_size: usize, pub filter_length: i32, @@ -21,12 +25,14 @@ impl Default for AecConfig { } } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub struct Aec { echo_state: *mut aec_rs_sys::SpeexEchoState, preprocess_state: Option<*mut aec_rs_sys::SpeexPreprocessState>, } impl Aec { + #[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub fn new(config: &AecConfig) -> Self { let echo_state = unsafe { aec_rs_sys::speex_echo_state_init(config.frame_size as i32, config.filter_length) @@ -54,6 +60,7 @@ impl Aec { } } + #[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub fn cancel_echo(&self, rec_buffer: &[i16], echo_buffer: &[i16], out_buffer: &mut [i16]) { unsafe { aec_rs_sys::speex_echo_cancellation( From 57e619ac46598164d716b81858f24d2fb267f1d7 Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sun, 8 Dec 2024 19:17:18 +0200 Subject: [PATCH 2/6] misc --- BUILDING.md | 11 ++++++----- src/lib.rs | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index 31f2874..d9eadc7 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -58,12 +58,13 @@ cargo build --release --target aarch64-apple-ios ## Build for wasm +Use [wasm-pack](https://rustwasm.github.io/docs/wasm-pack) with [emscripten.org](https://emscripten.org) + ```console -rustup target add wasm32-unknown-unknown -rustup target add --toolchain nightly wasm32-unknown-unknown -cargo build --target wasm32-unknown-unknown --features wasm -export RUSTFLAGS="--cfg=web_sys_unstable_apis --Z wasm_c_abi=spec" -cargo +nightly build --target=wasm32-unknown-unknown --release --features wasm +brew install emscripten +rustup target add wasm32-unknown-emscripten +cargo build --release --target wasm32-unknown-emscripten +wasm-pack build ``` ## Build pyaec (Python) diff --git a/src/lib.rs b/src/lib.rs index 89eec44..26929f4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -31,6 +31,7 @@ pub struct Aec { preprocess_state: Option<*mut aec_rs_sys::SpeexPreprocessState>, } +#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] impl Aec { #[cfg_attr(target_arch = "wasm32", wasm_bindgen)] pub fn new(config: &AecConfig) -> Self { From 74e23450ef8c88212ff712db181d27295a0bc77d Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sun, 8 Dec 2024 19:30:13 +0200 Subject: [PATCH 3/6] fix wasm --- Cargo.toml | 7 +++---- crates/aec-rs-sys/build.rs | 11 +++++++++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d1a8e4d..e5a5d83 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,9 @@ homepage = "https://github.com/thewh1teagle/aec-rs" [dependencies] aec-rs-sys = { path = "crates/aec-rs-sys", version = "1.0.0" } -wasm-bindgen = { version = "0.2.99", optional = true } + +[target.'cfg(target_arch = "wasm32")'.dependencies] +wasm-bindgen = { version = "0.2.99" } [lib] # For wasm @@ -21,6 +23,3 @@ crate-type = ["cdylib", "rlib"] [dev-dependencies] hound = { version = "3.5.1" } - -[features] -wasm = ["dep:wasm-bindgen"] diff --git a/crates/aec-rs-sys/build.rs b/crates/aec-rs-sys/build.rs index 5adabb3..54ca3f6 100644 --- a/crates/aec-rs-sys/build.rs +++ b/crates/aec-rs-sys/build.rs @@ -41,8 +41,15 @@ fn main() { if target.contains("android") { clang_target = "armv8-linux-androideabi".to_string(); } - let bindings = bindgen::Builder::default() - .header("wrapper.h") + + let mut bindings = bindgen::Builder::default().header("wrapper.h"); + + if target.contains("wasm") { + // See https://github.com/rust-lang/rust-bindgen/issues/2624#issuecomment-1708117271 + bindings = bindings.clang_arg("-fvisibility=default"); + } + + let bindings = bindings .clang_arg(format!("-I{}", lib_dst.display())) // Explicitly set target in case we are cross-compiling. // See https://github.com/rust-lang/rust-bindgen/issues/1780 for context. From f4a0e1339dc4ff43ef3590f76bcc977b97799e43 Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sun, 8 Dec 2024 19:38:35 +0200 Subject: [PATCH 4/6] misc --- BUILDING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/BUILDING.md b/BUILDING.md index d9eadc7..9d758e5 100644 --- a/BUILDING.md +++ b/BUILDING.md @@ -64,7 +64,7 @@ Use [wasm-pack](https://rustwasm.github.io/docs/wasm-pack) with [emscripten.org] brew install emscripten rustup target add wasm32-unknown-emscripten cargo build --release --target wasm32-unknown-emscripten -wasm-pack build +CC=emcc AR=emar wasm-pack build ``` ## Build pyaec (Python) diff --git a/README.md b/README.md index f58caae..8516375 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@ Acoustic echo cancellation in Rust based on [speexdsp](https://github.com/xiph/s - 🦀 Rust and 🐍 Python support - 🔗 Easy integration with C/C++ (or any other language) via C API - 📦 Precompiled library and C header files available in the [releases](https://github.com/thewh1teagle/aec-rs/releases/latest) -- 🖥️ Support for Windows (x86/arm64), Linux (x86/arm64), macOS (x86/arm64), Android (arm64), IOS (arm64) +- 🖥️ Support for Windows (x86/arm64), Linux (x86/arm64), macOS (x86/arm64), Android (arm64), IOS (arm64), and WASM! - 🖥️ Run on Raspberry PI as well # Install From 5a756a597268ce9e48fe11c82e4b53e3662ac1df Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sun, 8 Dec 2024 19:55:49 +0200 Subject: [PATCH 5/6] feat: add wasm ci --- .github/workflows/publish-libaec.yml | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/.github/workflows/publish-libaec.yml b/.github/workflows/publish-libaec.yml index cd12ab5..ef677c2 100644 --- a/.github/workflows/publish-libaec.yml +++ b/.github/workflows/publish-libaec.yml @@ -10,31 +10,37 @@ jobs: fail-fast: false matrix: include: - - platform: "macos-latest" # for Arm-based Macs (M1 and above) + - platform: "macos-latest" # Wasm32-emscripten + args: "--target wasm32-unknown-emscripten" + build-dir: "libaec-wasm32-unknown-emscripten" + archive: "tar" + target: "wasm32-unknown-emscripten" + + - platform: "macos-latest" # macOS arm64 args: "--target aarch64-apple-darwin" build-dir: "libaec-osx-aarch64" archive: "tar" target: "aarch64-apple-darwin" - - platform: "macos-latest" # for Apple IOS + - platform: "macos-latest" # IOS args: "--target aarch64-apple-ios" build-dir: "libaec-ios-aarch64" archive: "tar" target: "aarch64-apple-ios" - - platform: "macos-latest" # for Intel-based Macs + - platform: "macos-latest" # macOS x86-64 args: "--target x86_64-apple-darwin" build-dir: "libaec-osx-x86-64" archive: "tar" target: "x86_64-apple-darwin" - - platform: "ubuntu-22.04" # Linux 22.04 x86_64 + - platform: "ubuntu-22.04" # Linux x86_64 args: "" build-dir: "libaec-linux-x86-64" archive: "tar" target: "x86_64-unknown-linux-gnu" - - platform: "macos-latest" # Linux Android arm64 + - platform: "macos-latest" # Linux arm64 args: "" build-dir: "libaec-android-aarch64" archive: "tar" @@ -47,13 +53,13 @@ jobs: archive: "zip" target: "x86_64-pc-windows-msvc" - - platform: "windows-latest" # Windows ARM (aarch64) + - platform: "windows-latest" # Windows arm64 args: "--target aarch64-pc-windows-msvc" build-dir: "libaec-win-aarch64" archive: "zip" target: "aarch64-pc-windows-msvc" - - platform: "ubuntu-22.04" # Raspberry Pi 4 (64-bit ARM) + - platform: "ubuntu-22.04" # Linux arm64 args: "--target aarch64-unknown-linux-gnu" build-dir: "libaec-linux-aarch64" archive: "tar" From 4ad2fad20a3302cf3f83025ce77a4360cf34b720 Mon Sep 17 00:00:00 2001 From: thewh1teagle <61390950+thewh1teagle@users.noreply.github.com> Date: Sun, 8 Dec 2024 19:58:10 +0200 Subject: [PATCH 6/6] add compiler --- .github/workflows/publish-libaec.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish-libaec.yml b/.github/workflows/publish-libaec.yml index ef677c2..9c4b933 100644 --- a/.github/workflows/publish-libaec.yml +++ b/.github/workflows/publish-libaec.yml @@ -89,6 +89,10 @@ jobs: local-cache: true if: matrix.target == 'aarch64-linux-android' + - name: Setup emsdk + uses: mymindstorm/setup-emsdk@v14 + if: contains(matrix.target, 'wasm') + - name: Install Rust stable uses: dtolnay/rust-toolchain@stable with: