use super::*;
use crate::*;
use anyhow::{Error, Result, bail};
use derive_builder::Builder;
#[derive(Builder, Clone, Copy, Debug, PartialEq, Hash, serde::Serialize, serde::Deserialize)]
#[builder(
pattern = "owned",
build_fn(validate = "Self::validate", error = "Error")
)]
#[cfg_attr(
feature = "python-bindings",
gen_stub_pyclass,
pyclass(get_all, from_py_object)
)]
pub struct CPSSettings {
pub nfft: usize,
pub overlap: Overlap,
#[builder(default)]
pub window: WindowType,
#[builder(default)]
pub istart: Option<usize>,
#[builder(default)]
pub istop: Option<usize>,
}
impl Default for CPSSettings {
fn default() -> Self {
Self {
nfft: 2048,
overlap: Default::default(),
window: Default::default(),
istart: Default::default(),
istop: Default::default(),
}
}
}
impl CPSSettingsBuilder {
fn validate(&self) -> Result<()> {
if self.nfft.is_none() {
bail!("nfft not specified")
};
let nfft = self.nfft.unwrap();
if !nfft.is_multiple_of(2) {
bail!("NFFT should be even")
}
if nfft == 0 {
bail!("Invalid NFFT, should be > 0.")
}
if let Some(overlap) = self.overlap {
overlap.validate(nfft)?;
}
if let (Some(istart), Some(istop)) = (self.istart, self.istop)
&& let (Some(start), Some(stop)) = (istart, istop)
&& start >= stop
{
bail!("istart should be less than istop")
}
Ok(())
}
}
#[cfg(feature = "python-bindings")]
#[cfg_attr(feature = "python-bindings", gen_stub_pymethods, pymethods)]
impl CPSSettings {
#[new]
fn new(
nfft: usize,
overlap: Overlap,
window: WindowType,
istart: Option<usize>,
istop: Option<usize>,
) -> PyResult<CPSSettings> {
let builder = CPSSettingsBuilder::default()
.nfft(nfft)
.overlap(overlap)
.window(window)
.istart(istart)
.istop(istop);
Ok(builder.build()?)
}
#[staticmethod]
#[pyo3(name = "default")]
fn default_py() -> CPSSettings {
CPSSettings::default()
}
fn get_overlap_samples_py(&self) -> usize {
self.get_overlap_samples()
}
fn get_hop_size_py(&self) -> usize {
self.get_hop_size()
}
}
impl CPSSettings {
pub fn get_overlap_samples(&self) -> usize {
self.overlap.get_overlap_samples(self.nfft) as usize
}
pub fn get_hop_size(&self) -> usize {
self.overlap.get_hop_size(self.nfft) as usize
}
pub fn to_aps_settings(&self, fs: StrictlyPositive) -> ApsSettings {
ApsSettings {
mode: ApsMode::AllAveraging {},
overlap: self.overlap,
windowType: self.window,
freqWeightingType: FreqWeighting::Z, nfft: self.nfft,
fs,
}
}
}