Some docs and bugfixes in siggen

This commit is contained in:
Anne de Jong 2023-11-29 07:44:40 +01:00
parent ec010945c6
commit c99faf7d0c

View File

@ -1,3 +1,18 @@
//! This module provide signal generators.
//!
//! # Examples
//!
//! ## Create some white noise and print it.
//!
//! ```
//! let mut wn = Siggen::newWhiteNoise();
//! wn.setGain(0.1);
//! wn.setMute(false);
//! let mut sig = [0. ; 1024];
//! wn.genSignal(&mut sig);
//! println!("{:?}", &sig);
//!
//! ```
use super::config::*; use super::config::*;
use super::filter::Filter; use super::filter::Filter;
use pyo3::prelude::*; use pyo3::prelude::*;
@ -5,9 +20,12 @@ use rand::prelude::*;
use rand::rngs::ThreadRng; use rand::rngs::ThreadRng;
use rand_distr::StandardNormal; use rand_distr::StandardNormal;
pub trait Source: Send { trait Source: Send {
/// Generate the 'pure' source signal. Output is placed inside the `sig` argument.
fn genSignal_unscaled(&mut self, sig: &mut [Flt]); fn genSignal_unscaled(&mut self, sig: &mut [Flt]);
/// Reset the source state, i.e. set phase to 0, etc
fn reset(&mut self, fs: Flt); fn reset(&mut self, fs: Flt);
/// Used to make the Siggen struct cloneable
fn clone_dyn(&self) -> Box<dyn Source>; fn clone_dyn(&self) -> Box<dyn Source>;
} }
impl Clone for Box<dyn Source> { impl Clone for Box<dyn Source> {
@ -30,7 +48,7 @@ impl Source for WhiteNoise {
sig.iter_mut() sig.iter_mut()
.for_each(|s| *s = thread_rng().sample(StandardNormal)); .for_each(|s| *s = thread_rng().sample(StandardNormal));
} }
fn reset(&mut self,_fs: Flt) {} fn reset(&mut self, _fs: Flt) {}
fn clone_dyn(&self) -> Box<dyn Source> { fn clone_dyn(&self) -> Box<dyn Source> {
Box::new(self.clone()) Box::new(self.clone())
} }
@ -88,12 +106,14 @@ impl Source for Sine {
/// Sweep signal /// Sweep signal
#[derive(Clone)] #[derive(Clone)]
/// Signal generator. Able to create acoustic output signals /// Signal generator. Able to create acoustic output signals
pub struct Siggen { pub struct Siggen {
// The source dynamic signal. Noise, a sine wave, sweep, etc
source: Box<dyn Source>, source: Box<dyn Source>,
// Filter applied to the source signal
prefilter: Option<Box<dyn Filter>>, prefilter: Option<Box<dyn Filter>>,
// If set, no dynamic signal source output is given
muted: bool, muted: bool,
gain: Flt, gain: Flt,
DCOffset: Flt, DCOffset: Flt,
@ -105,9 +125,20 @@ impl Siggen {
pub fn setPreFilter(&mut self, pref: Option<Box<dyn Filter>>) { pub fn setPreFilter(&mut self, pref: Option<Box<dyn Filter>>) {
self.prefilter = pref.clone(); self.prefilter = pref.clone();
} }
/// Set the gain applied to the source signal
///
/// * g: Gain value. Can be any float. If set to 0.0, the source is effectively muted. Only
/// using (setMute) is a more efficient way to do this.
pub fn setGain(&mut self, g: Flt) {
self.gain = g;
}
/// Create a white noise signal generator.
pub fn newWhiteNoise() -> Siggen { pub fn newWhiteNoise() -> Siggen {
Siggen::new(Box::new(WhiteNoise::new())) Siggen::new(Box::new(WhiteNoise::new()))
} }
/// Create a sine wave signal generator
///
/// * freq: Frequency of the sine wave in [Hz]
pub fn newSineWave(freq: Flt) -> Siggen { pub fn newSineWave(freq: Flt) -> Siggen {
Siggen::new(Box::new(Sine::new(freq))) Siggen::new(Box::new(Sine::new(freq)))
} }
@ -138,7 +169,7 @@ impl Siggen {
/// - Gain is applied. /// - Gain is applied.
/// - Offset is applied (thus, no gain is applied to the DC offset). /// - Offset is applied (thus, no gain is applied to the DC offset).
/// ///
fn genSignal(&mut self, sig: &mut [Flt]) { pub fn genSignal(&mut self, sig: &mut [Flt]) {
if self.muted { if self.muted {
sig.iter_mut().for_each(|x| { sig.iter_mut().for_each(|x| {
*x = 0.0; *x = 0.0;
@ -162,9 +193,9 @@ impl Siggen {
/// ///
/// * fs: (New) Sampling frequency [Hz] /// * fs: (New) Sampling frequency [Hz]
/// ///
fn reset(&mut self, fs: Flt) { pub fn reset(&mut self, fs: Flt) {
self.source.reset(fs); self.source.reset(fs);
if let Some(f) = self.prefilter { if let Some(f) = &mut self.prefilter {
f.reset(); f.reset();
} }
} }
@ -176,6 +207,8 @@ mod test {
#[test] #[test]
fn test_whitenoise() { fn test_whitenoise() {
println!("{:?}", WhiteNoise::new().genSignal(10)); let mut t = &[0.; 10];
Siggen::newWiteNoise().genSignal(&mut t);
println!("{:?}", &t);
} }
} }