Removed dependency on ndarray_rand. Crate is not updated. Updated pyo3 to new version and updated enum pyclass derive macros. Switch to SmallRng for white noise random number generation.
This commit is contained in:
parent
0567e7fb92
commit
8a573266df
17
Cargo.toml
17
Cargo.toml
@ -16,11 +16,15 @@ crate-type = ["cdylib", "rlib"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
# Error handling
|
# Error handling
|
||||||
anyhow = "1.0.86"
|
anyhow = "1.0.91"
|
||||||
|
|
||||||
# Numerics
|
# Numerics
|
||||||
# Optional future feature for ndarray: blas
|
# Optional future feature for ndarray: blas
|
||||||
ndarray = { version = "0.15.6", features = ["rayon"] }
|
ndarray = { version = "0.16.1", features = ["rayon"] }
|
||||||
|
|
||||||
|
# This is required for HDF5, as it apparently doesn't update anymore.
|
||||||
|
ndarray15p6 = { package = "ndarray", version = "0.15.6", features = ["rayon"] }
|
||||||
|
|
||||||
num = "0.4.3"
|
num = "0.4.3"
|
||||||
# blas-src = { version = "0.8", features = ["openblas"] }
|
# blas-src = { version = "0.8", features = ["openblas"] }
|
||||||
# openblas-src = { version = "0.10", features = ["cblas", "system"] }
|
# openblas-src = { version = "0.10", features = ["cblas", "system"] }
|
||||||
@ -29,15 +33,15 @@ num = "0.4.3"
|
|||||||
rayon = "1.10.0"
|
rayon = "1.10.0"
|
||||||
|
|
||||||
# Python bindings
|
# Python bindings
|
||||||
pyo3 = { version = "0.21.2", optional = true, features = [
|
pyo3 = { version = "0.22.5", optional = true, features = [
|
||||||
"extension-module",
|
"extension-module",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
] }
|
] }
|
||||||
# Python bindings for Numpy arrays
|
# Python bindings for Numpy arrays
|
||||||
numpy = { version = "0.21.0", optional = true }
|
numpy = { version = "0.22.0", optional = true }
|
||||||
|
|
||||||
# White noise etc
|
# White noise etc
|
||||||
rand = "0.8.5"
|
rand = { version = "0.8.5", features = ["small_rng"] }
|
||||||
rand_distr = "0.4.3"
|
rand_distr = "0.4.3"
|
||||||
|
|
||||||
# Cross-platform audio lib
|
# Cross-platform audio lib
|
||||||
@ -105,9 +109,6 @@ smallvec = "1.13.2"
|
|||||||
# Compile time constant floating point operations
|
# Compile time constant floating point operations
|
||||||
softfloat = "1.0.0"
|
softfloat = "1.0.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
ndarray-rand = "0.14.0"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["f64", "cpal-api", "record"]
|
default = ["f64", "cpal-api", "record"]
|
||||||
# Use this to test if everything works well in f32
|
# Use this to test if everything works well in f32
|
||||||
|
@ -32,10 +32,7 @@ pub trait Stream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Stream API descriptor: type and corresponding text
|
/// Stream API descriptor: type and corresponding text
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
//#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
#[derive(strum_macros::EnumMessage, Debug, Clone, PartialEq, Serialize, Deserialize, strum_macros::Display)]
|
#[derive(strum_macros::EnumMessage, Debug, Clone, PartialEq, Serialize, Deserialize, strum_macros::Display)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum StreamApiDescr {
|
pub enum StreamApiDescr {
|
||||||
|
@ -7,10 +7,7 @@ use crate::config::*;
|
|||||||
|
|
||||||
/// Data type description for samples coming from a stream
|
/// Data type description for samples coming from a stream
|
||||||
#[derive(strum_macros::EnumMessage, PartialEq, Copy, Debug, Clone, Serialize, Deserialize)]
|
#[derive(strum_macros::EnumMessage, PartialEq, Copy, Debug, Clone, Serialize, Deserialize)]
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
//#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum DataType {
|
pub enum DataType {
|
||||||
/// 32-bit floats
|
/// 32-bit floats
|
||||||
|
@ -50,10 +50,7 @@ use api::*;
|
|||||||
use crate::config::*;
|
use crate::config::*;
|
||||||
/// Stream types that can be started
|
/// Stream types that can be started
|
||||||
///
|
///
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
// #[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
#[derive(PartialEq, Clone, Copy)]
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
pub enum StreamType {
|
pub enum StreamType {
|
||||||
/// Input-only stream
|
/// Input-only stream
|
||||||
|
@ -7,9 +7,7 @@ use strum_macros;
|
|||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
/// Physical quantities that are I/O of a Daq device.
|
/// Physical quantities that are I/O of a Daq device.
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
// #[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
#[derive(PartialEq, Serialize, Deserialize, strum_macros::EnumMessage, Debug, Clone, Copy)]
|
#[derive(PartialEq, Serialize, Deserialize, strum_macros::EnumMessage, Debug, Clone, Copy)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub enum Qty {
|
pub enum Qty {
|
||||||
|
@ -161,28 +161,32 @@ impl Recording {
|
|||||||
nchannels: usize,
|
nchannels: usize,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
match data.getRaw() {
|
match data.getRaw() {
|
||||||
|
// The code below uses ndarray 0.15.6, which is the version required
|
||||||
|
// to communicate with rust-hdf5. It requires input to be C-ordered,
|
||||||
|
// or interleaved. This happens to be the default for ndarray as
|
||||||
|
// well.
|
||||||
RawStreamData::Datai8(dat) => {
|
RawStreamData::Datai8(dat) => {
|
||||||
let arr = ndarray::ArrayView2::<i8>::from_shape((framesPerBlock, nchannels), dat)?;
|
let arr = ndarray15p6::ArrayView2::<i8>::from_shape((framesPerBlock, nchannels), dat)?;
|
||||||
ds.write_slice(arr, (ctr, .., ..))?;
|
ds.write_slice(arr, (ctr, .., ..))?;
|
||||||
}
|
}
|
||||||
RawStreamData::Datai16(dat) => {
|
RawStreamData::Datai16(dat) => {
|
||||||
let arr =
|
let arr =
|
||||||
ndarray::ArrayView2::<i16>::from_shape((framesPerBlock, nchannels), dat)?;
|
ndarray15p6::ArrayView2::<i16>::from_shape((framesPerBlock, nchannels), dat)?;
|
||||||
ds.write_slice(arr, (ctr, .., ..))?;
|
ds.write_slice(arr, (ctr, .., ..))?;
|
||||||
}
|
}
|
||||||
RawStreamData::Datai32(dat) => {
|
RawStreamData::Datai32(dat) => {
|
||||||
let arr =
|
let arr =
|
||||||
ndarray::ArrayView2::<i32>::from_shape((framesPerBlock, nchannels), dat)?;
|
ndarray15p6::ArrayView2::<i32>::from_shape((framesPerBlock, nchannels), dat)?;
|
||||||
ds.write_slice(arr, (ctr, .., ..))?;
|
ds.write_slice(arr, (ctr, .., ..))?;
|
||||||
}
|
}
|
||||||
RawStreamData::Dataf32(dat) => {
|
RawStreamData::Dataf32(dat) => {
|
||||||
let arr =
|
let arr =
|
||||||
ndarray::ArrayView2::<f32>::from_shape((framesPerBlock, nchannels), dat)?;
|
ndarray15p6::ArrayView2::<f32>::from_shape((framesPerBlock, nchannels), dat)?;
|
||||||
ds.write_slice(arr, (ctr, .., ..))?;
|
ds.write_slice(arr, (ctr, .., ..))?;
|
||||||
}
|
}
|
||||||
RawStreamData::Dataf64(dat) => {
|
RawStreamData::Dataf64(dat) => {
|
||||||
let arr =
|
let arr =
|
||||||
ndarray::ArrayView2::<f64>::from_shape((framesPerBlock, nchannels), dat)?;
|
ndarray15p6::ArrayView2::<f64>::from_shape((framesPerBlock, nchannels), dat)?;
|
||||||
ds.write_slice(arr, (ctr, .., ..))?;
|
ds.write_slice(arr, (ctr, .., ..))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,8 @@ use strum_macros::Display;
|
|||||||
use crate::config::*;
|
use crate::config::*;
|
||||||
|
|
||||||
/// Errors that happen in a stream
|
/// Errors that happen in a stream
|
||||||
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
#[derive(strum_macros::EnumMessage, PartialEq, Debug, Clone, Display, Copy)]
|
#[derive(strum_macros::EnumMessage, PartialEq, Debug, Clone, Display, Copy)]
|
||||||
|
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
|
||||||
//#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
|
|
||||||
pub enum StreamError {
|
pub enum StreamError {
|
||||||
/// Input overrun
|
/// Input overrun
|
||||||
#[strum(
|
#[strum(
|
||||||
|
@ -2,7 +2,10 @@
|
|||||||
//!
|
//!
|
||||||
//!
|
//!
|
||||||
use crate::config::*;
|
use crate::config::*;
|
||||||
use ndarray::ArrayView1;
|
use ndarray::{ArrayView1, IntoDimension};
|
||||||
|
use rand::{rngs::SmallRng, thread_rng, Rng, SeedableRng};
|
||||||
|
use rand_distr::StandardNormal;
|
||||||
|
use smallvec::Array;
|
||||||
|
|
||||||
/// Compute maximum value of an array of float values
|
/// Compute maximum value of an array of float values
|
||||||
pub fn max<T>(arr: ArrayView<Flt, T>) -> Flt
|
pub fn max<T>(arr: ArrayView<Flt, T>) -> Flt
|
||||||
@ -33,3 +36,22 @@ where
|
|||||||
{
|
{
|
||||||
arr.fold(0., |acc, new| if new.abs() > acc { new.abs() } else { acc })
|
arr.fold(0., |acc, new| if new.abs() > acc { new.abs() } else { acc })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Generate an array of *PSEUDO* random numbers from the standard normal
|
||||||
|
/// distribution. Typically used for white noise generation. To be used for
|
||||||
|
/// noise signals, not for anything that needs to be truly random.
|
||||||
|
///
|
||||||
|
/// # Args
|
||||||
|
///
|
||||||
|
/// - `shape` - Shape of the returned array
|
||||||
|
///
|
||||||
|
pub fn randNormal<Sh, D>(shape: Sh) -> ndarray::Array<Flt,D>
|
||||||
|
where
|
||||||
|
Sh: ShapeBuilder<Dim=D>,
|
||||||
|
D: Dimension
|
||||||
|
{
|
||||||
|
// Explicit conversion to Fortran order
|
||||||
|
let mut rng = SmallRng::from_entropy();
|
||||||
|
let shape = shape.f().into_shape_with_order();
|
||||||
|
ArrayBase::from_shape_simple_fn(shape, || rng.sample(StandardNormal))
|
||||||
|
}
|
||||||
|
@ -308,11 +308,9 @@ impl AvPowerSpectra {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
use approx::assert_abs_diff_eq;
|
use approx::assert_abs_diff_eq;
|
||||||
use ndarray_rand::rand_distr::Normal;
|
|
||||||
use ndarray_rand::RandomExt;
|
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::config::*;
|
use crate::{config::*, math::randNormal};
|
||||||
|
|
||||||
use super::{ApsMode, AvPowerSpectra, CPSResult, Overlap, WindowType};
|
use super::{ApsMode, AvPowerSpectra, CPSResult, Overlap, WindowType};
|
||||||
use Overlap::Percentage;
|
use Overlap::Percentage;
|
||||||
@ -359,8 +357,7 @@ mod test {
|
|||||||
let mut aps = AvPowerSpectra::new(settings);
|
let mut aps = AvPowerSpectra::new(settings);
|
||||||
assert_eq!(aps.overlap_keep, 0);
|
assert_eq!(aps.overlap_keep, 0);
|
||||||
|
|
||||||
let distr = Normal::new(1.0, 1.0).expect("Distribution cannot be built");
|
let timedata_some = randNormal((nfft,1));
|
||||||
let timedata_some = Dmat::random((nfft, 1), distr);
|
|
||||||
let timedata_zeros = Dmat::zeros((nfft, 1));
|
let timedata_zeros = Dmat::zeros((nfft, 1));
|
||||||
|
|
||||||
// Clone here, as first_result reference is overwritten by subsequent
|
// Clone here, as first_result reference is overwritten by subsequent
|
||||||
@ -382,8 +379,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tf1() {
|
fn test_tf1() {
|
||||||
let nfft = 4800;
|
let nfft = 4800;
|
||||||
let distr = Normal::new(1.0, 1.0).unwrap();
|
let mut timedata = randNormal((nfft, 1));
|
||||||
let mut timedata = Dmat::random((nfft, 1), distr);
|
|
||||||
timedata
|
timedata
|
||||||
.push_column(timedata.column(0).mapv(|a| 2. * a).view())
|
.push_column(timedata.column(0).mapv(|a| 2. * a).view())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -405,8 +401,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tf2() {
|
fn test_tf2() {
|
||||||
let nfft = 4800;
|
let nfft = 4800;
|
||||||
let distr = Normal::new(1.0, 1.0).unwrap();
|
let mut timedata = randNormal((nfft, 1));
|
||||||
let mut timedata = Dmat::random((nfft, 1), distr);
|
|
||||||
timedata
|
timedata
|
||||||
.push_column(timedata.column(0).mapv(|a| 2. * a).view())
|
.push_column(timedata.column(0).mapv(|a| 2. * a).view())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@ -431,8 +426,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_ap() {
|
fn test_ap() {
|
||||||
let nfft = 1024;
|
let nfft = 1024;
|
||||||
let distr = Normal::new(1.0, 1.0).unwrap();
|
let timedata = randNormal((150 * nfft, 1));
|
||||||
let timedata = Dmat::random((150 * nfft, 1), distr);
|
|
||||||
let timedata_mean_square = (&timedata * &timedata).sum() / (timedata.len() as Flt);
|
let timedata_mean_square = (&timedata * &timedata).sum() / (timedata.len() as Flt);
|
||||||
|
|
||||||
for wt in [
|
for wt in [
|
||||||
|
@ -2,11 +2,7 @@ use crate::config::*;
|
|||||||
use strum::IntoEnumIterator;
|
use strum::IntoEnumIterator;
|
||||||
use strum_macros::{Display, EnumIter, EnumMessage};
|
use strum_macros::{Display, EnumIter, EnumMessage};
|
||||||
/// Sound level frequency weighting type (A, C, Z)
|
/// Sound level frequency weighting type (A, C, Z)
|
||||||
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
|
||||||
// #[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
#[derive(Copy, Display, Debug, EnumMessage, Default, Clone, PartialEq, EnumIter)]
|
#[derive(Copy, Display, Debug, EnumMessage, Default, Clone, PartialEq, EnumIter)]
|
||||||
pub enum FreqWeighting {
|
pub enum FreqWeighting {
|
||||||
/// A-weighting
|
/// A-weighting
|
||||||
|
@ -252,7 +252,6 @@ mod test {
|
|||||||
use approx::{abs_diff_eq, assert_relative_eq, assert_ulps_eq, ulps_eq};
|
use approx::{abs_diff_eq, assert_relative_eq, assert_ulps_eq, ulps_eq};
|
||||||
// For absolute value
|
// For absolute value
|
||||||
use num::complex::ComplexFloat;
|
use num::complex::ComplexFloat;
|
||||||
use rand_distr::StandardNormal;
|
|
||||||
|
|
||||||
/// Generate a sine wave at the order i
|
/// Generate a sine wave at the order i
|
||||||
fn generate_sinewave(nfft: usize, order: usize) -> Dcol {
|
fn generate_sinewave(nfft: usize, order: usize) -> Dcol {
|
||||||
@ -267,6 +266,8 @@ mod test {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
use crate::math::randNormal;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
#[test]
|
#[test]
|
||||||
/// Test whether DC part of single-sided FFT has right properties
|
/// Test whether DC part of single-sided FFT has right properties
|
||||||
@ -349,7 +350,6 @@ mod test {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
use ndarray_rand::RandomExt;
|
|
||||||
// Test parseval's theorem for some random data
|
// Test parseval's theorem for some random data
|
||||||
#[test]
|
#[test]
|
||||||
fn test_parseval() {
|
fn test_parseval() {
|
||||||
@ -358,7 +358,7 @@ mod test {
|
|||||||
let mut ps = PowerSpectra::newFromWindow(rect);
|
let mut ps = PowerSpectra::newFromWindow(rect);
|
||||||
|
|
||||||
// Start with a time signal
|
// Start with a time signal
|
||||||
let t: Dmat = Dmat::random((nfft, 1), StandardNormal);
|
let t: Dmat = randNormal((nfft,1));
|
||||||
|
|
||||||
let tavg = t.sum() / (nfft as Flt);
|
let tavg = t.sum() / (nfft as Flt);
|
||||||
let t_dc_power = tavg.powi(2);
|
let t_dc_power = tavg.powi(2);
|
||||||
@ -394,7 +394,7 @@ mod test {
|
|||||||
let mut ps = PowerSpectra::newFromWindow(window);
|
let mut ps = PowerSpectra::newFromWindow(window);
|
||||||
|
|
||||||
// Start with a time signal
|
// Start with a time signal
|
||||||
let t: Dmat = 2. * Dmat::random((nfft, 1), StandardNormal);
|
let t: Dmat = randNormal((nfft,1));
|
||||||
|
|
||||||
let tavg = t.sum() / (nfft as Flt);
|
let tavg = t.sum() / (nfft as Flt);
|
||||||
let t_dc_power = tavg.powi(2);
|
let t_dc_power = tavg.powi(2);
|
||||||
|
@ -73,11 +73,8 @@ fn hamming(N: usize) -> Dcol {
|
|||||||
/// * Blackman
|
/// * Blackman
|
||||||
///
|
///
|
||||||
/// The [WindowType::default] is [WindowType::Hann].
|
/// The [WindowType::default] is [WindowType::Hann].
|
||||||
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
#[derive(Display, Default, Copy, Clone, Debug, PartialEq, EnumMessage, EnumIter)]
|
#[derive(Display, Default, Copy, Clone, Debug, PartialEq, EnumMessage, EnumIter)]
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
|
||||||
// #[cfg_attr(feature = "python-bindings", pyclass(eq))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
pub enum WindowType {
|
pub enum WindowType {
|
||||||
/// Von Hann window
|
/// Von Hann window
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -192,8 +192,8 @@ impl Drop for PPM {
|
|||||||
|
|
||||||
/// Enumerator denoting, for each channel what the level approximately is. Low,
|
/// Enumerator denoting, for each channel what the level approximately is. Low,
|
||||||
/// fine, high or clipped.
|
/// fine, high or clipped.
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
#[derive(Copy, Debug, Clone, Default)]
|
#[derive(Copy, Debug, PartialEq, Clone, Default)]
|
||||||
pub enum ClipState {
|
pub enum ClipState {
|
||||||
/// Level is rather low
|
/// Level is rather low
|
||||||
#[default]
|
#[default]
|
||||||
|
@ -42,7 +42,7 @@ impl Source {
|
|||||||
/// Create a white noise signal source
|
/// Create a white noise signal source
|
||||||
pub fn newWhiteNoise() -> Source {
|
pub fn newWhiteNoise() -> Source {
|
||||||
Source {
|
Source {
|
||||||
src: Box::new(WhiteNoise {}),
|
src: Box::new(WhiteNoise { rng: SmallRng::from_entropy()}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,11 +121,14 @@ impl SourceImpl for Silence {
|
|||||||
}
|
}
|
||||||
/// White noise source. Can be colored by applying a color filter to the source
|
/// White noise source. Can be colored by applying a color filter to the source
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
struct WhiteNoise {}
|
struct WhiteNoise {
|
||||||
|
// SmallRng is a cheap random number generator
|
||||||
|
rng: SmallRng
|
||||||
|
}
|
||||||
impl SourceImpl for WhiteNoise {
|
impl SourceImpl for WhiteNoise {
|
||||||
fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator<Item = &mut Flt>) {
|
fn genSignal_unscaled(&mut self, sig: &mut dyn ExactSizeIterator<Item = &mut Flt>) {
|
||||||
sig.for_each(|s| {
|
sig.for_each(|s| {
|
||||||
*s = thread_rng().sample(StandardNormal);
|
*s = self.rng.sample(StandardNormal);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn reset(&mut self, _fs: Flt) {}
|
fn reset(&mut self, _fs: Flt) {}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Sweep signal generation code
|
//! Sweep signal generation code
|
||||||
use strum_macros::{Display, EnumMessage};
|
|
||||||
use strum::EnumMessage;
|
use strum::EnumMessage;
|
||||||
|
use strum_macros::{Display, EnumMessage};
|
||||||
use {
|
use {
|
||||||
crate::config::*,
|
crate::config::*,
|
||||||
anyhow::{bail, Result},
|
anyhow::{bail, Result},
|
||||||
@ -10,8 +10,8 @@ const twopi: Flt = 2. * pi;
|
|||||||
|
|
||||||
/// Enumerator representing the type of sweep source to create. Used as
|
/// Enumerator representing the type of sweep source to create. Used as
|
||||||
/// parameter in [Siggen::newSweep].
|
/// parameter in [Siggen::newSweep].
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
#[cfg_attr(feature = "python-bindings", pyclass(eq, eq_int))]
|
||||||
#[derive(Debug, Clone, Display, EnumMessage)]
|
#[derive(Debug, PartialEq, Clone, Display, EnumMessage)]
|
||||||
pub enum SweepType {
|
pub enum SweepType {
|
||||||
/// Forward only logarithmic sweep, repeats itself
|
/// Forward only logarithmic sweep, repeats itself
|
||||||
#[strum(message = "Forward logarithmic")]
|
#[strum(message = "Forward logarithmic")]
|
||||||
|
@ -3,11 +3,7 @@ use crate::config::*;
|
|||||||
use strum::EnumMessage;
|
use strum::EnumMessage;
|
||||||
use strum_macros::Display;
|
use strum_macros::Display;
|
||||||
/// Time weighting to use in level detection of Sound Level Meter.
|
/// Time weighting to use in level detection of Sound Level Meter.
|
||||||
///
|
#[cfg_attr(feature = "python-bindings", pyclass(eq))]
|
||||||
// Do the following when Pyo3 0.22 can finally be used combined with rust-numpy:
|
|
||||||
// #[cfg_attr(feature = "python-bindings", pyclass(eq))]
|
|
||||||
// For now:
|
|
||||||
#[cfg_attr(feature = "python-bindings", pyclass)]
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Display)]
|
#[derive(Clone, Copy, Debug, PartialEq, Display)]
|
||||||
pub enum TimeWeighting {
|
pub enum TimeWeighting {
|
||||||
// I know that the curly braces here are not required and add some
|
// I know that the curly braces here are not required and add some
|
||||||
@ -37,10 +33,6 @@ pub enum TimeWeighting {
|
|||||||
#[cfg(feature = "python-bindings")]
|
#[cfg(feature = "python-bindings")]
|
||||||
#[cfg_attr(feature = "python-bindings", pymethods)]
|
#[cfg_attr(feature = "python-bindings", pymethods)]
|
||||||
impl TimeWeighting {
|
impl TimeWeighting {
|
||||||
// This method is still required in Pyo3 0.21, not anymore in 0.22
|
|
||||||
fn __eq__(&self, other: &Self) -> bool {
|
|
||||||
self == other
|
|
||||||
}
|
|
||||||
fn __str__(&self) -> String {
|
fn __str__(&self) -> String {
|
||||||
format!("{self}")
|
format!("{self}")
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user