From b9f71fdb13ac1016c5974472af602781126bd176 Mon Sep 17 00:00:00 2001 From: Tomasz Andrzejak Date: Wed, 16 Oct 2024 01:12:50 +0200 Subject: [PATCH] Add opening SOFA from memory --- libmysofa-sys/Cargo.toml | 2 +- libmysofa-sys/src/lib.rs | 29 +++++++++++++++++++++- src/lib.rs | 13 ++++++++++ src/reader.rs | 52 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 2 deletions(-) diff --git a/libmysofa-sys/Cargo.toml b/libmysofa-sys/Cargo.toml index e1e733d..25859a0 100644 --- a/libmysofa-sys/Cargo.toml +++ b/libmysofa-sys/Cargo.toml @@ -20,7 +20,7 @@ cc = "1.0.101" system-deps = "7.0" [package.metadata.system-deps] -libmysofa = "1" +libmysofa = "1.3" [package.metadata.cargo-machete] ignored = ["libz-sys"] diff --git a/libmysofa-sys/src/lib.rs b/libmysofa-sys/src/lib.rs index 92ff1b4..13c07f6 100644 --- a/libmysofa-sys/src/lib.rs +++ b/libmysofa-sys/src/lib.rs @@ -2,7 +2,7 @@ #![allow(non_camel_case_types)] #![allow(non_snake_case)] -use std::os::raw::{c_char, c_int, c_short, c_uint, c_ulong, c_void}; +use std::os::raw::{c_char, c_int, c_long, c_short, c_uint, c_ulong, c_void}; pub const MYSOFA_DEFAULT_NEIGH_STEP_ANGLE: f64 = 0.5; pub const MYSOFA_DEFAULT_NEIGH_STEP_RADIUS: f64 = 0.01; @@ -173,6 +173,33 @@ extern "C" { neighbor_radius_step: f32, ) -> *mut MYSOFA_EASY; + pub fn mysofa_open_data( + data: *const c_char, + size: c_long, + samplerate: f32, + filterlength: *mut c_int, + err: *mut c_int, + ) -> *mut MYSOFA_EASY; + + pub fn mysofa_open_data_no_norm( + data: *const c_char, + size: c_long, + samplerate: f32, + filterlength: *mut c_int, + err: *mut c_int, + ) -> *mut MYSOFA_EASY; + + pub fn mysofa_open_data_advanced( + data: *const c_char, + size: c_long, + samplerate: f32, + filterlength: *mut c_int, + err: *mut c_int, + norm: bool, + neighbor_angle_step: f32, + neighbor_radius_step: f32, + ) -> *mut MYSOFA_EASY; + pub fn mysofa_open_cached( filename: *const c_char, samplerate: f32, diff --git a/src/lib.rs b/src/lib.rs index 83b5505..d64ecbc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -68,4 +68,17 @@ mod tests { let mut filter = Filter::new(filt_len); sofa.filter(0.0, 1.0, 0.0, &mut filter); } + + #[test] + fn open_data_test() { + let cwd = std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")); + std::env::set_current_dir(cwd).unwrap(); + + let data = std::fs::read("libmysofa-sys/libmysofa/tests/tester.sofa").unwrap(); + let sofa = Sofar::open_data(&data).unwrap(); + let filt_len = sofa.filter_len(); + + let mut filter = Filter::new(filt_len); + sofa.filter(0.0, 1.0, 0.0, &mut filter); + } } diff --git a/src/reader.rs b/src/reader.rs index 8cc46d9..b76d436 100644 --- a/src/reader.rs +++ b/src/reader.rs @@ -173,6 +173,46 @@ impl OpenOptions { cached: self.cached, }) } + + /// Open a SOFA file using provided bytes and open options specified in `self` + /// + /// ```no_run + /// use sofar::reader::OpenOptions; + /// let data: Vec = std::fs::read("my/sofa/file.sofa").unwrap(); + /// + /// let sofa = OpenOptions::new() + /// .normalized(false) + /// .sample_rate(44100.0) + /// .open_data(&data) + /// .unwrap(); + /// ``` + pub fn open_data>(&self, bytes: B) -> Result { + let mut filter_len = 0; + let mut err = 0; + + let raw = unsafe { + ffi::mysofa_open_data_advanced( + bytes.as_ref().as_ptr() as _, + bytes.as_ref().len() as _, + self.sample_rate, + &mut filter_len, + &mut err, + self.normalized, + self.neighbor_angle_step, + self.neighbor_radius_step, + ) + }; + + if raw.is_null() || err != ffi::MYSOFA_OK { + return Err(Error::from_raw(err)); + } + + Ok(Sofar { + raw, + filter_len: filter_len as usize, + cached: self.cached, + }) + } } impl Default for OpenOptions { @@ -227,6 +267,18 @@ impl Sofar { OpenOptions::new().open(path) } + /// Open a SOFA using provided bytes and the default open options + /// + /// ```no_run + /// use sofar::reader::Sofar; + /// let data: Vec = std::fs::read("my/sofa/file.sofa").unwrap(); + /// + /// let sofa = Sofar::open_data(&data).unwrap(); + /// ``` + pub fn open_data>(bytes: B) -> Result { + OpenOptions::new().open_data(bytes) + } + pub fn filter_len(&self) -> usize { self.filter_len }