Let SLM::run output a vec of pyarrays, instead of vec of vecs

This commit is contained in:
Anne de Jong 2024-09-30 14:26:10 +02:00
parent 2efb610caa
commit 96187bfcf9
5 changed files with 56 additions and 8 deletions

View File

@ -1,6 +1,6 @@
[package] [package]
name = "lasprs" name = "lasprs"
version = "0.6.1" version = "0.6.2"
edition = "2021" edition = "2021"
authors = ["J.A. de Jong <j.a.dejong@ascee.nl>"] authors = ["J.A. de Jong <j.a.dejong@ascee.nl>"]
description = "Library for Acoustic Signal Processing (Rust edition, with optional Python bindings via pyo3)" description = "Library for Acoustic Signal Processing (Rust edition, with optional Python bindings via pyo3)"

View File

@ -1,5 +1,5 @@
use crate::{config::*, ZPKModel}; use crate::{config::*, ZPKModel};
use anyhow::{anyhow, bail, Result}; use anyhow::{anyhow, bail, Error, Result};
use num::{traits::float, Float}; use num::{traits::float, Float};
use rayon::iter::Filter; use rayon::iter::Filter;
use softfloat::F64; use softfloat::F64;
@ -497,6 +497,38 @@ impl StandardFilterDescriptor {
Ok(Self::genThirdOctaveFilterSet(fmin, fmax)?) Ok(Self::genThirdOctaveFilterSet(fmin, fmax)?)
} }
#[staticmethod]
#[pyo3(name = "genFilterSetInRangeWithStartStopDescriptors")]
fn genFilterSet_range(
start: StandardFilterDescriptor,
stop: StandardFilterDescriptor,
include_overall: bool,
) -> PyResult<Vec<StandardFilterDescriptor>> {
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::<Vec<StandardFilterDescriptor>>();
if include_overall {
res.push(StandardFilterDescriptor::Overall().expect("Overall should not err"))
}
Ok(res)
}
#[staticmethod] #[staticmethod]
#[pyo3(name = "genOctaveFilterSet")] #[pyo3(name = "genOctaveFilterSet")]
fn genOctaveFilterSetFromFreq(fmin: Flt, fmax: Flt) -> PyResult<Vec<StandardFilterDescriptor>> { fn genOctaveFilterSetFromFreq(fmin: Flt, fmax: Flt) -> PyResult<Vec<StandardFilterDescriptor>> {
@ -527,8 +559,14 @@ impl StandardFilterDescriptor {
fmax: Flt, fmax: Flt,
append_overall: bool, append_overall: bool,
) -> PyResult<Vec<StandardFilterDescriptor>> { ) -> PyResult<Vec<StandardFilterDescriptor>> {
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)?) Ok(Self::genFilterSetForRange(b, fmin, fmax, append_overall)?)
} }
} }
#[cfg(test)] #[cfg(test)]

View File

@ -60,11 +60,11 @@
//! //!
//! ``` //! ```
//! //!
mod settings; mod slmsettings;
mod tw; mod tw;
mod slm; mod slm;
pub use slm::SLM; pub use slm::SLM;
pub use settings::{SLMSettings, SLMSettingsBuilder}; pub use slmsettings::{SLMSettings, SLMSettingsBuilder};
pub use tw::TimeWeighting; pub use tw::TimeWeighting;
pub use crate::ps::FreqWeighting; pub use crate::ps::FreqWeighting;

View File

@ -6,7 +6,7 @@ use rayon::iter::{IntoParallelRefIterator, ParallelIterator};
use rayon::prelude::*; use rayon::prelude::*;
use smallvec::SmallVec; use smallvec::SmallVec;
use super::{settings::SLMSettings, SLM_MAX_CHANNELS}; use super::{slmsettings::SLMSettings, SLM_MAX_CHANNELS};
use crate::{config::*, filter::Filter}; use crate::{config::*, filter::Filter};
use crate::{Biquad, Dcol, Flt, FreqWeighting, PoleOrZero, SeriesBiquad, ZPKModel}; use crate::{Biquad, Dcol, Flt, FreqWeighting, PoleOrZero, SeriesBiquad, ZPKModel};
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
@ -214,8 +214,18 @@ impl SLM {
} }
#[pyo3(name = "run", signature=(dat, provide_output=true))] #[pyo3(name = "run", signature=(dat, provide_output=true))]
fn run_py(&mut self, dat: PyArrayLike1<Flt>, provide_output: bool) -> Option<Vec<Vec<Flt>>> { fn run_py<'py>(
self.run(dat.as_array().as_slice()?, provide_output) &mut self,
py: Python<'py>,
dat: PyArrayLike1<Flt>,
provide_output: bool,
) -> Option<Vec<Bound<'py, PyArray1<Flt>>>> {
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::<Vec<Bound<'py, PyArray1<Flt>>>>();
return Some(vec_py);
}
None
} }
#[pyo3(name = "Lmax")] #[pyo3(name = "Lmax")]