From 8ee5fcbf020f93a826c52a0981a63357b65e94c6 Mon Sep 17 00:00:00 2001 From: "J.A. de Jong - Redu-Sone B.V., ASCEE V.O.F." Date: Tue, 8 Oct 2024 12:07:18 +0200 Subject: [PATCH] Split up siggen code in source and siggen submods --- src/lib.rs | 2 +- src/siggen/mod.rs | 26 +++++++++ src/siggen/siggen.rs | 131 +------------------------------------------ src/siggen/source.rs | 105 ++++++++++++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 129 deletions(-) create mode 100644 src/siggen/mod.rs create mode 100644 src/siggen/source.rs diff --git a/src/lib.rs b/src/lib.rs index e01f3b7..4161b37 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,7 @@ mod config; use config::*; +use filter::*; pub use config::Flt; pub mod daq; @@ -40,7 +41,6 @@ pub mod filter; pub mod ps; mod math; pub mod siggen; -use filter::*; pub mod rt; pub mod slm; diff --git a/src/siggen/mod.rs b/src/siggen/mod.rs new file mode 100644 index 0000000..6236ad6 --- /dev/null +++ b/src/siggen/mod.rs @@ -0,0 +1,26 @@ +//! This module provide signal generators. The import struct defined here is +//! [Siggen], which has several creation methods. +//! +//! # Examples +//! +//! ## Create some white noise and print it. +//! +//! ``` +//! use lasprs::siggen::Siggen; +//! let mut wn = Siggen::newWhiteNoise(1); +//! // Set gains for all channels +//! wn.setAllGains(0.1); +//! // Unmute all channels +//! wn.setAllMute(false); +//! // Create a slice where data is stored. +//! let mut sig = [0. ; 1024]; +//! // Fill `sig` with the signal data. +//! wn.genSignal(&mut sig); +//! // Print data. +//! println!("{:?}", &sig); +//! +//! ``` +mod siggen; +mod source; +pub use source::{Silence, Sine, WhiteNoise}; +pub use siggen::Siggen; diff --git a/src/siggen/siggen.rs b/src/siggen/siggen.rs index 324d043..62fe5ec 100644 --- a/src/siggen/siggen.rs +++ b/src/siggen/siggen.rs @@ -1,138 +1,13 @@ -//! This module provide signal generators. The import struct defined here is -//! [Siggen], which has several creation methods. -//! -//! # Examples -//! -//! ## Create some white noise and print it. -//! -//! ``` -//! use lasprs::siggen::Siggen; -//! let mut wn = Siggen::newWhiteNoise(1); -//! // Set gains for all channels -//! wn.setAllGains(0.1); -//! // Unmute all channels -//! wn.setAllMute(false); -//! // Create a slice where data is stored. -//! let mut sig = [0. ; 1024]; -//! // Fill `sig` with the signal data. -//! wn.genSignal(&mut sig); -//! // Print data. -//! println!("{:?}", &sig); -//! -//! ``` -use super::config::*; -use super::filter::Filter; +use crate::config::*; +use crate::filter::Filter; +use super::source::*; use dasp_sample::{FromSample, Sample}; use rayon::prelude::*; use std::fmt::Debug; use std::iter::ExactSizeIterator; use std::slice::IterMut; -use rand::prelude::*; -use rand::rngs::ThreadRng; -use rand_distr::StandardNormal; -/// Ratio between circumference and radius of a circle -const twopi: Flt = 2.0 * pi; - -/// Source for the signal generator. Implementations are sine waves, sweeps, noise. -pub trait Source: Send { - /// Generate the 'pure' source signal. Output is placed inside the `sig` argument. - fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator); - /// Reset the source state, i.e. set phase to 0, etc - fn reset(&mut self, fs: Flt); - /// Used to make the Siggen struct cloneable - fn clone_dyn(&self) -> Box; -} -impl Clone for Box { - fn clone(&self) -> Self { - self.clone_dyn() - } -} - -#[derive(Clone)] -struct Silence {} - -impl Source for Silence { - fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator) { - sig.for_each(|s| { - *s = 0.0; - }); - } - fn reset(&mut self, _fs: Flt) {} - fn clone_dyn(&self) -> Box { - Box::new(self.clone()) - } -} - -/// White noise source -#[derive(Clone)] -struct WhiteNoise {} -impl WhiteNoise { - /// Generate new WhiteNoise generator - fn new() -> WhiteNoise { - WhiteNoise {} - } -} -impl Source for WhiteNoise { - fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator) { - sig.for_each(|s| { - *s = thread_rng().sample(StandardNormal); - }); - } - fn reset(&mut self, _fs: Flt) {} - fn clone_dyn(&self) -> Box { - Box::new(self.clone()) - } -} - -/// Sine wave, with configurable frequency -#[derive(Clone)] -struct Sine { - // Sampling freq [Hz] - fs: Flt, - // current stored phase - phase: Flt, - // Signal frequency [rad/s] - omg: Flt, -} -impl Sine { - /// Create new sine source signal - /// - /// Args: - /// - /// * fs: Sampling freq [Hz] - /// * - fn new(freq: Flt) -> Sine { - Sine { - fs: -1.0, - phase: 0.0, - omg: 2.0 * pi * freq, - } - } -} -impl Source for Sine { - fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator) { - if self.fs <= 0.0 { - sig.for_each(|s| { - *s = 0.0; - }); - return; - } - sig.for_each(|s| { - *s = Flt::sin(self.phase); - self.phase += self.omg / self.fs; - self.phase %= twopi; - }); - } - fn reset(&mut self, fs: Flt) { - self.fs = fs; - self.phase = 0.0; - } - fn clone_dyn(&self) -> Box { - Box::new(self.clone()) - } -} /// Signal generator. Able to create acoustic output signals. See above example on how to use. /// Typical signal that can be created are: diff --git a/src/siggen/source.rs b/src/siggen/source.rs new file mode 100644 index 0000000..65f2a12 --- /dev/null +++ b/src/siggen/source.rs @@ -0,0 +1,105 @@ +use crate::config::*; +use rand::prelude::*; +use rand::rngs::ThreadRng; +use rand_distr::StandardNormal; + +/// Ratio between circumference and radius of a circle +const twopi: Flt = 2.0 * pi; + +/// Source for the signal generator. Implementations are sine waves, sweeps, noise. +pub trait Source: Send { + /// Generate the 'pure' source signal. Output is placed inside the `sig` argument. + fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator); + /// Reset the source state, i.e. set phase to 0, etc + fn reset(&mut self, fs: Flt); + /// Used to make the Siggen struct cloneable + fn clone_dyn(&self) -> Box; +} +impl Clone for Box { + fn clone(&self) -> Self { + self.clone_dyn() + } +} + +#[derive(Clone)] +pub struct Silence {} + +impl Source for Silence { + fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator) { + sig.for_each(|s| { + *s = 0.0; + }); + } + fn reset(&mut self, _fs: Flt) {} + fn clone_dyn(&self) -> Box { + Box::new(self.clone()) + } +} +/// White noise source +#[derive(Clone)] +pub struct WhiteNoise {} +impl WhiteNoise { + /// Generate new WhiteNoise generator + pub fn new() -> WhiteNoise { + WhiteNoise {} + } +} +impl Source for WhiteNoise { + fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator) { + sig.for_each(|s| { + *s = thread_rng().sample(StandardNormal); + }); + } + fn reset(&mut self, _fs: Flt) {} + fn clone_dyn(&self) -> Box { + Box::new(self.clone()) + } +} + +/// Sine wave, with configurable frequency +#[derive(Clone)] +pub struct Sine { + // Sampling freq \[Hz\] + fs: Flt, + // current stored phase + phase: Flt, + // Signal frequency \[rad/s\] + omg: Flt, +} +impl Sine { + /// Create new sine source signal + /// + /// Args: + /// + /// * fs: Sampling freq [Hz] + /// * + pub fn new(freq: Flt) -> Sine { + Sine { + fs: -1.0, + phase: 0.0, + omg: 2.0 * pi * freq, + } + } +} +impl Source for Sine { + fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator) { + if self.fs <= 0.0 { + sig.for_each(|s| { + *s = 0.0; + }); + return; + } + sig.for_each(|s| { + *s = Flt::sin(self.phase); + self.phase += self.omg / self.fs; + self.phase %= twopi; + }); + } + fn reset(&mut self, fs: Flt) { + self.fs = fs; + self.phase = 0.0; + } + fn clone_dyn(&self) -> Box { + Box::new(self.clone()) + } +}