From 80f4ed11aa85e629f7f96d48116eb6d9f93745b6 Mon Sep 17 00:00:00 2001 From: Polochon-street Date: Thu, 17 Feb 2022 18:42:05 +0100 Subject: [PATCH 1/2] Add some words about windows cross-compilation --- .github/workflows/rust.yml | 44 +++++++++++++++++++++++++++++++++++++- Cargo.lock | 8 +++---- Cargo.toml | 2 +- README.md | 36 +++++++++++++++++++++++++++++++ 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index a18d49a..0798944 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -10,7 +10,7 @@ env: CARGO_TERM_COLOR: always jobs: - build: + build-test-lint-linux: runs-on: ubuntu-latest @@ -34,3 +34,45 @@ jobs: run: cargo +nightly-2022-02-16 bench --verbose --features=bench --no-run - name: Build examples run: cargo build --examples --verbose --features=serde + + build-test-lint-windows: + name: Windows - build, test and lint + runs-on: windows-latest + strategy: + matrix: + include: + - ffmpeg_version: latest + ffmpeg_download_url: https://www.gyan.dev/ffmpeg/builds/ffmpeg-release-full-shared.7z + fail-fast: false + env: + FFMPEG_DOWNLOAD_URL: ${{ matrix.ffmpeg_download_url }} + steps: + - uses: actions/checkout@v2 + - name: Install dependencies + run: | + $VCINSTALLDIR = $(& "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath) + Add-Content $env:GITHUB_ENV "LIBCLANG_PATH=${VCINSTALLDIR}\VC\Tools\LLVM\x64\bin`n" + Invoke-WebRequest "${env:FFMPEG_DOWNLOAD_URL}" -OutFile ffmpeg-release-full-shared.7z + 7z x ffmpeg-release-full-shared.7z + mkdir ffmpeg + mv ffmpeg-*/* ffmpeg/ + Add-Content $env:GITHUB_ENV "FFMPEG_DIR=${pwd}\ffmpeg`n" + Add-Content $env:GITHUB_PATH "${pwd}\ffmpeg\bin`n" + - name: Set up Rust + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + components: rustfmt, clippy + - name: Build + run: | + cargo build --examples + - name: Test + run: | + cargo test --examples + - name: Lint + run: | + cargo clippy --examples -- -D warnings + - name: Check format + run: | + cargo fmt -- --check diff --git a/Cargo.lock b/Cargo.lock index 79f9b64..4321d03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -376,9 +376,9 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" [[package]] name = "ffmpeg-next" -version = "5.0.0" +version = "5.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "154799d4348e5105d775d72fe53eb32ebb31e7019d963914c687633e894ded92" +checksum = "70a1fc87054b079ade0b081b023c5fef309cd4bbcb569c09eed2aa39b25a0a11" dependencies = [ "bitflags", "ffmpeg-sys-next", @@ -387,9 +387,9 @@ dependencies = [ [[package]] name = "ffmpeg-sys-next" -version = "5.0.0" +version = "5.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f81bd9adbcd2903847d680e0d2b0df95f0d514ad5f037a5504e1be1706bd98e0" +checksum = "6ba12dea33516e30c160ce557c7e43dd857276368eb1cd0eef4fce6529f2dee5" dependencies = [ "bindgen", "cc", diff --git a/Cargo.toml b/Cargo.toml index 0337efb..ff47cfb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -35,7 +35,7 @@ lazy_static = "1.4.0" rayon = "1.5.0" crossbeam = "0.8.0" noisy_float = "0.2.0" -ffmpeg-next = "5.0.0" +ffmpeg-next = "5.0.2" log = "0.4.14" env_logger = "0.8.3" thiserror = "1.0.24" diff --git a/README.md b/README.md index b3b8a95..51820d8 100644 --- a/README.md +++ b/README.md @@ -97,6 +97,42 @@ library (with multithreading), and to make playlists easily. See [blissify](https://crates.io/crates/blissify) for a reference implementation. +## Cross-compilation + +To cross-compile bliss-rs from linux to x86_64 windows, install the +`x86_64-pc-windows-gnu` target via: + + rustup target add x86_64-pc-windows-gnu + +Make sure you have `x86_64-w64-mingw32-gcc` installed on your computer. + +Then after downloading and extracting [ffmpeg's prebuilt binaries](https://www.gyan.dev/ffmpeg/builds/), +running: + + FFMPEG_DIR=/path/to/prebuilt/ffmpeg cargo build --target x86_64-pc-windows-gnu --release + +Will produce a `.rlib` library file. If you want to generate a shared `.dll` +library, add: + + [lib] + crate-type = ["cdylib"] + +to `Cargo.toml` before compiling, and if you want to generate a `.lib` static +library, add: + + [lib] + crate-type = ["staticlib"] + +You can of course test the examples yourself by compiling them as .exe: + + FFMPEG_DIR=/path/to/prebuilt/ffmpeg cargo build --target x86_64-pc-windows-gnu --release --examples + +WARNING: Doing all of the above and making it work on windows requires to have +ffmpeg's dll on your Windows `%PATH%` (`avcodec-59.dll`, etc). +Usually installing ffmpeg on the target windows is enough, but you can also just +extract them from `/path/to/prebuilt/ffmpeg/bin` and put them next to the thing +you generated from cargo (either bliss' dll or executable). + ## Acknowledgements * This library relies heavily on [aubio](https://aubio.org/)'s From 51e8cf9344f296b5218047bc9694b69ed3a6d164 Mon Sep 17 00:00:00 2001 From: Polochon-street Date: Thu, 17 Feb 2022 22:43:28 +0100 Subject: [PATCH 2/2] Some fixes for the new CI --- .github/workflows/rust.yml | 16 ++++++++-------- examples/playlist.rs | 11 +++++++++-- src/chroma.rs | 8 ++++---- src/temporal.rs | 10 ++-------- src/timbral.rs | 13 +++++-------- 5 files changed, 28 insertions(+), 30 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 0798944..035244c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -34,6 +34,10 @@ jobs: run: cargo +nightly-2022-02-16 bench --verbose --features=bench --no-run - name: Build examples run: cargo build --examples --verbose --features=serde + - name: Lint + run: cargo clippy --examples --features=serde -- -D warnings + - name: Check format + run: cargo fmt -- --check build-test-lint-windows: name: Windows - build, test and lint @@ -65,14 +69,10 @@ jobs: override: true components: rustfmt, clippy - name: Build - run: | - cargo build --examples + run: cargo build --examples - name: Test - run: | - cargo test --examples + run: cargo test --examples --features=serde - name: Lint - run: | - cargo clippy --examples -- -D warnings + run: cargo clippy --examples --features=serde -- -D warnings - name: Check format - run: | - cargo fmt -- --check + run: cargo fmt -- --check diff --git a/examples/playlist.rs b/examples/playlist.rs index 99e009f..7b81d59 100644 --- a/examples/playlist.rs +++ b/examples/playlist.rs @@ -1,13 +1,20 @@ +#[cfg(feature = "serde")] use anyhow::Result; +#[cfg(feature = "serde")] use bliss_audio::distance::{closest_to_first_song, dedup_playlist, euclidean_distance}; +#[cfg(feature = "serde")] use bliss_audio::{library::analyze_paths_streaming, Song}; +#[cfg(feature = "serde")] use clap::{App, Arg}; +#[cfg(feature = "serde")] use glob::glob; -use mime_guess; -use serde_json; +#[cfg(feature = "serde")] use std::env; +#[cfg(feature = "serde")] use std::fs; +#[cfg(feature = "serde")] use std::io::BufReader; +#[cfg(feature = "serde")] use std::path::{Path, PathBuf}; /* Analyzes a folder recursively, and make a playlist out of the file diff --git a/src/chroma.rs b/src/chroma.rs index 75bf619..7ca6ce3 100644 --- a/src/chroma.rs +++ b/src/chroma.rs @@ -207,13 +207,13 @@ fn chroma_filter( wts *= &freq_bins; // np.roll(), np bro - let mut uninit: Vec = Vec::with_capacity((&wts).len()); + let mut uninit: Vec = vec![0.; (&wts).len()]; unsafe { uninit.set_len(wts.len()); } let mut b = Array::from(uninit) .into_shape(wts.dim()) - .map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e.to_string())))?; + .map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e)))?; b.slice_mut(s![-3.., ..]).assign(&wts.slice(s![..3, ..])); b.slice_mut(s![..-3, ..]).assign(&wts.slice(s![3.., ..])); @@ -308,7 +308,7 @@ fn pitch_tuning( } let max_index = counts .argmax() - .map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e.to_string())))?; + .map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e)))?; // Return the bin with the most reoccuring frequency. Ok((-50. + (100. * resolution * max_index as f64)) / 100.) @@ -332,7 +332,7 @@ fn estimate_tuning( let threshold: N64 = Array::from(filtered_mag.to_vec()) .quantile_axis_mut(Axis(0), n64(0.5), &Midpoint) - .map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e.to_string())))? + .map_err(|e| BlissError::AnalysisError(format!("in chroma: {}", e)))? .into_scalar(); let mut pitch = filtered_pitch diff --git a/src/temporal.rs b/src/temporal.rs index d054508..3c10866 100644 --- a/src/temporal.rs +++ b/src/temporal.rs @@ -48,10 +48,7 @@ impl BPMDesc { sample_rate, ) .map_err(|e| { - BlissError::AnalysisError(format!( - "error while loading aubio tempo object: {}", - e.to_string() - )) + BlissError::AnalysisError(format!("error while loading aubio tempo object: {}", e)) })?, bpms: Vec::new(), }) @@ -59,10 +56,7 @@ impl BPMDesc { pub fn do_(&mut self, chunk: &[f32]) -> BlissResult<()> { let result = self.aubio_obj.do_result(chunk).map_err(|e| { - BlissError::AnalysisError(format!( - "aubio error while computing tempo {}", - e.to_string() - )) + BlissError::AnalysisError(format!("aubio error while computing tempo {}", e)) })?; if result > 0. { diff --git a/src/timbral.rs b/src/timbral.rs index 2624207..a8ed6e2 100644 --- a/src/timbral.rs +++ b/src/timbral.rs @@ -126,21 +126,21 @@ impl SpectralDesc { .map_err(|e| { BlissError::AnalysisError(format!( "error while loading aubio centroid object: {}", - e.to_string() + e )) })?, rolloff_aubio_desc: SpecDesc::new(SpecShape::Rolloff, SpectralDesc::WINDOW_SIZE) .map_err(|e| { BlissError::AnalysisError(format!( "error while loading aubio rolloff object: {}", - e.to_string() + e )) })?, phase_vocoder: PVoc::new(SpectralDesc::WINDOW_SIZE, SpectralDesc::HOP_SIZE).map_err( |e| { BlissError::AnalysisError(format!( "error while loading aubio pvoc object: {}", - e.to_string() + e )) }, )?, @@ -163,10 +163,7 @@ impl SpectralDesc { self.phase_vocoder .do_(chunk, fftgrain.as_mut_slice()) .map_err(|e| { - BlissError::AnalysisError(format!( - "error while processing aubio pv object: {}", - e.to_string() - )) + BlissError::AnalysisError(format!("error while processing aubio pv object: {}", e)) })?; let bin = self @@ -175,7 +172,7 @@ impl SpectralDesc { .map_err(|e| { BlissError::AnalysisError(format!( "error while processing aubio centroid object: {}", - e.to_string() + e )) })?;