Split up siggen code in source and siggen submods
This commit is contained in:
parent
4da8a1c74a
commit
8ee5fcbf02
@ -33,6 +33,7 @@
|
|||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
use config::*;
|
use config::*;
|
||||||
|
use filter::*;
|
||||||
|
|
||||||
pub use config::Flt;
|
pub use config::Flt;
|
||||||
pub mod daq;
|
pub mod daq;
|
||||||
@ -40,7 +41,6 @@ pub mod filter;
|
|||||||
pub mod ps;
|
pub mod ps;
|
||||||
mod math;
|
mod math;
|
||||||
pub mod siggen;
|
pub mod siggen;
|
||||||
use filter::*;
|
|
||||||
pub mod rt;
|
pub mod rt;
|
||||||
pub mod slm;
|
pub mod slm;
|
||||||
|
|
||||||
|
26
src/siggen/mod.rs
Normal file
26
src/siggen/mod.rs
Normal 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;
|
@ -1,138 +1,13 @@
|
|||||||
//! This module provide signal generators. The import struct defined here is
|
use crate::config::*;
|
||||||
//! [Siggen], which has several creation methods.
|
use crate::filter::Filter;
|
||||||
//!
|
use super::source::*;
|
||||||
//! # 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 dasp_sample::{FromSample, Sample};
|
use dasp_sample::{FromSample, Sample};
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::iter::ExactSizeIterator;
|
use std::iter::ExactSizeIterator;
|
||||||
use std::slice::IterMut;
|
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.
|
/// Signal generator. Able to create acoustic output signals. See above example on how to use.
|
||||||
/// Typical signal that can be created are:
|
/// Typical signal that can be created are:
|
||||||
|
105
src/siggen/source.rs
Normal file
105
src/siggen/source.rs
Normal 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())
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user