Split up siggen code in source and siggen submods

This commit is contained in:
Anne de Jong 2024-10-08 12:07:18 +02:00
parent 4da8a1c74a
commit 8ee5fcbf02
4 changed files with 135 additions and 129 deletions

View File

@ -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;

26
src/siggen/mod.rs Normal file
View File

@ -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;

View File

@ -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<Item = &mut Flt>);
/// 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<dyn Source>;
}
impl Clone for Box<dyn Source> {
fn clone(&self) -> Self {
self.clone_dyn()
}
}
#[derive(Clone)]
struct Silence {}
impl Source for Silence {
fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator<Item = &mut Flt>) {
sig.for_each(|s| {
*s = 0.0;
});
}
fn reset(&mut self, _fs: Flt) {}
fn clone_dyn(&self) -> Box<dyn Source> {
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<Item = &mut Flt>) {
sig.for_each(|s| {
*s = thread_rng().sample(StandardNormal);
});
}
fn reset(&mut self, _fs: Flt) {}
fn clone_dyn(&self) -> Box<dyn Source> {
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<Item = &mut Flt>) {
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<dyn Source> {
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:

105
src/siggen/source.rs Normal file
View File

@ -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<Item = &mut Flt>);
/// 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<dyn Source>;
}
impl Clone for Box<dyn Source> {
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<Item = &mut Flt>) {
sig.for_each(|s| {
*s = 0.0;
});
}
fn reset(&mut self, _fs: Flt) {}
fn clone_dyn(&self) -> Box<dyn Source> {
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<Item = &mut Flt>) {
sig.for_each(|s| {
*s = thread_rng().sample(StandardNormal);
});
}
fn reset(&mut self, _fs: Flt) {}
fn clone_dyn(&self) -> Box<dyn Source> {
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<Item = &mut Flt>) {
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<dyn Source> {
Box::new(self.clone())
}
}