diff --git a/Cargo.toml b/Cargo.toml index 0d52702..6ed4a39 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "lasprs" -version = "0.6.1" +version = "0.6.2" edition = "2021" authors = ["J.A. de Jong "] description = "Library for Acoustic Signal Processing (Rust edition, with optional Python bindings via pyo3)" diff --git a/src/filter/octave.rs b/src/filter/octave.rs index d388784..dfc61e2 100644 --- a/src/filter/octave.rs +++ b/src/filter/octave.rs @@ -1,5 +1,5 @@ use crate::{config::*, ZPKModel}; -use anyhow::{anyhow, bail, Result}; +use anyhow::{anyhow, bail, Error, Result}; use num::{traits::float, Float}; use rayon::iter::Filter; use softfloat::F64; @@ -497,6 +497,38 @@ impl StandardFilterDescriptor { Ok(Self::genThirdOctaveFilterSet(fmin, fmax)?) } + #[staticmethod] + #[pyo3(name = "genFilterSetInRangeWithStartStopDescriptors")] + fn genFilterSet_range( + start: StandardFilterDescriptor, + stop: StandardFilterDescriptor, + include_overall: bool, + ) -> PyResult> { + if start.b == 0 { + return Err(PyValueError::new_err( + "Overall band designator cannot be used to define range", + )); + } + if start.b != stop.b { + return Err(PyValueError::new_err( + "Start and stop filter are not of same type", + )); + } + if start.x > stop.x { + return Err(PyValueError::new_err( + "Start filter has higher midband frequency than stop frequency", + )); + } + + let mut res = (start.x..=stop.x) + .map(|x| StandardFilterDescriptor { b: start.b, x: x }) + .collect::>(); + if include_overall { + res.push(StandardFilterDescriptor::Overall().expect("Overall should not err")) + } + Ok(res) + } + #[staticmethod] #[pyo3(name = "genOctaveFilterSet")] fn genOctaveFilterSetFromFreq(fmin: Flt, fmax: Flt) -> PyResult> { @@ -527,8 +559,14 @@ impl StandardFilterDescriptor { fmax: Flt, append_overall: bool, ) -> PyResult> { + if b == 0 { + return Err(PyValueError::new_err( + "Overall band designator cannot be used to define range", + )); + } Ok(Self::genFilterSetForRange(b, fmin, fmax, append_overall)?) } + } #[cfg(test)] diff --git a/src/slm/mod.rs b/src/slm/mod.rs index 597e0e3..b52f450 100644 --- a/src/slm/mod.rs +++ b/src/slm/mod.rs @@ -60,11 +60,11 @@ //! //! ``` //! -mod settings; +mod slmsettings; mod tw; mod slm; pub use slm::SLM; -pub use settings::{SLMSettings, SLMSettingsBuilder}; +pub use slmsettings::{SLMSettings, SLMSettingsBuilder}; pub use tw::TimeWeighting; pub use crate::ps::FreqWeighting; diff --git a/src/slm/slm.rs b/src/slm/slm.rs index 14c3b8f..776b537 100644 --- a/src/slm/slm.rs +++ b/src/slm/slm.rs @@ -6,7 +6,7 @@ use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; use rayon::prelude::*; use smallvec::SmallVec; -use super::{settings::SLMSettings, SLM_MAX_CHANNELS}; +use super::{slmsettings::SLMSettings, SLM_MAX_CHANNELS}; use crate::{config::*, filter::Filter}; use crate::{Biquad, Dcol, Flt, FreqWeighting, PoleOrZero, SeriesBiquad, ZPKModel}; #[derive(Debug, Clone)] @@ -205,7 +205,7 @@ impl SLM { } } -#[cfg(feature="python-bindings")] +#[cfg(feature = "python-bindings")] #[cfg_attr(feature = "python-bindings", pymethods)] impl SLM { #[new] @@ -214,8 +214,18 @@ impl SLM { } #[pyo3(name = "run", signature=(dat, provide_output=true))] - fn run_py(&mut self, dat: PyArrayLike1, provide_output: bool) -> Option>> { - self.run(dat.as_array().as_slice()?, provide_output) + fn run_py<'py>( + &mut self, + py: Python<'py>, + dat: PyArrayLike1, + provide_output: bool, + ) -> Option>>> { + if let Some(res) = self.run(dat.as_array().as_slice()?, provide_output) { + let vec_py_iter = res.into_iter().map(|v| PyArray1::from_vec_bound(py, v)); + let vec_py = vec_py_iter.collect::>>>(); + return Some(vec_py); + } + None } #[pyo3(name = "Lmax")] diff --git a/src/slm/settings.rs b/src/slm/slmsettings.rs similarity index 100% rename from src/slm/settings.rs rename to src/slm/slmsettings.rs