diff --git a/src/rt/ppm.rs b/src/rt/ppm.rs index c469c8f..2612fb1 100644 --- a/src/rt/ppm.rs +++ b/src/rt/ppm.rs @@ -1,6 +1,6 @@ use crate::daq::InStreamMsg; use crate::math::maxabs; -use crate::slm::{self, SLMSettingsBuilder, SLM}; +use crate::slm::{self, SLMSettingsBuilder, TimeWeighting, SLM}; use crate::{config::*, FreqWeighting, StandardFilterDescriptor}; use crate::{daq::StreamMgr, Dcol}; use crossbeam::channel::{unbounded, Receiver, Sender}; @@ -17,7 +17,7 @@ use std::time::{Duration, Instant}; const ALMOST_CLIPPED_REL_AMP: Flt = 0.95; /// If clipping occured, this is the time it keeps saying 'signal is clipped' -const CLIP_INDICATOR_WAIT_S: Duration = Duration::from_secs(2); +const CLIP_INDICATOR_WAIT_S: Duration = Duration::from_secs(4); /// If the signal level falls below this value, we indicate that the signal level is low. const LEVEL_THRESHOLD_FOR_LOW_LEVEL: Flt = -50.; @@ -42,10 +42,23 @@ impl PPM { pub fn new(mgr: &mut StreamMgr) -> Self { let (sender, rxmsg) = unbounded(); let (tx, rxstream) = unbounded(); + + // Add queue sender part of queue to stream manager mgr.addInQueue(tx); - let status2: SharedPPMStatus = Arc::new(Mutex::new(vec![])); - let status = status2.clone(); + // Shared status object + let status: SharedPPMStatus = Arc::new(Mutex::new(vec![])); + + // Start the thread that calculates PPM and clip values + Self::startThread(status.clone(), rxstream, rxmsg); + + PPM { status, sender } + } + fn startThread( + status: SharedPPMStatus, + rxstream: Receiver, + rxmsg: Receiver, + ) { rayon::spawn(move || { let mut slms: Vec = vec![]; @@ -120,6 +133,7 @@ impl PPM { .fs(meta.samplerate) .freqWeighting(FreqWeighting::Z) .Lref(1.0) + .timeWeighting(TimeWeighting::Impulse {}) .filterDescriptors([ StandardFilterDescriptor::Overall().unwrap() ]) @@ -132,7 +146,7 @@ impl PPM { s.push(PPMChannelStatus { clip: ClipState::LowLevels, level: -300., - clip_time: None + clip_time: None, }); }); } @@ -159,24 +173,18 @@ impl PPM { } } }); - - PPM { - status: status2, - sender, - } } - /// Return array of instantaneous PPM level per channel - pub fn getLevels(&self) -> Dcol { - Dcol::from_iter(self.status.lock().iter().map(|s| s.level)) - } /// Reset clip state. Used to quickly restore the clipping state. pub fn resetClip(&self) { self.sender.send(PPMMessage::ResetClip).unwrap(); } - fn getClipState(&self) -> Vec { - self.status.lock().iter().map(|s| s.clip).collect() - + /// Returns the current state: levels and clip state + pub fn getState(&self) -> (Dcol, Vec) { + let status = self.status.lock(); + let levels = Dcol::from_iter(status.iter().map(|s| s.level)); + let clips = status.iter().map(|s| s.clip).collect(); + (levels, clips) } } impl Drop for PPM { @@ -228,14 +236,11 @@ impl PPM { Self::new(smgr) } - #[pyo3(name = "getLevels")] - fn getLevels_py<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray1> { - self.getLevels().to_pyarray_bound(py) - } - - #[pyo3(name = "getClipState")] - fn getClipState_py(&self) -> Vec { - self.getClipState() + #[pyo3(name = "getState")] + fn getState_py<'py>(&self, py: Python<'py>) -> (Bound<'py, PyArray1>, Vec) { + let (levels, clips) = self.getState(); + let levels = levels.to_pyarray_bound(py); + (levels, clips) } #[pyo3(name = "resetClip")]