pub struct Signal<T: SignalType> { /* private fields */ }Expand description
A generic signal container supporting both f32 and f64
§Examples
use iron_wave::Signal;
// Create a signal from a vector
let signal = Signal::<f64>::new(vec![1.0, 2.0, 3.0, 4.0]);
assert_eq!(signal.len(), 4);
// Create a signal with sample rate
let mut signal = Signal::<f32>::with_sample_rate(vec![0.0; 100], 44100.0);
assert_eq!(signal.sample_rate(), Some(44100.0));Implementations§
Source§impl<T: SignalType> Signal<T>
impl<T: SignalType> Signal<T>
Sourcepub fn with_sample_rate(data: Vec<T>, sample_rate: f64) -> Self
pub fn with_sample_rate(data: Vec<T>, sample_rate: f64) -> Self
Create a new signal with a specified sample rate
Sourcepub fn from_slice(data: &[T]) -> Self
pub fn from_slice(data: &[T]) -> Self
Create a signal from a slice
Sourcepub fn sample_rate(&self) -> Option<f64>
pub fn sample_rate(&self) -> Option<f64>
Get the sample rate if available
Sourcepub fn set_sample_rate(&mut self, rate: f64)
pub fn set_sample_rate(&mut self, rate: f64)
Set the sample rate
Sourcepub fn metadata(&self) -> &SignalMetadata
pub fn metadata(&self) -> &SignalMetadata
Get metadata
Sourcepub fn metadata_mut(&mut self) -> &mut SignalMetadata
pub fn metadata_mut(&mut self) -> &mut SignalMetadata
Get mutable metadata
Sourcepub fn std(&self) -> T
pub fn std(&self) -> T
Compute the sample standard deviation using Welford’s numerically stable algorithm
This calculates the sample standard deviation using Bessel’s correction (n-1 denominator) for unbiased estimation, not the population standard deviation (n denominator).
Formula: σ = sqrt(Σ(xi - μ)² / (n-1))
Where:
- xi: individual sample values
- μ: sample mean
- n: number of samples
§Why Sample Standard Deviation?
We use the sample standard deviation (with n-1) because:
- It provides an unbiased estimate when working with samples from a larger population
- It’s the standard choice in signal processing and statistics
- It prevents underestimation of variance in finite samples
§Returns
Returns 0 if the signal has fewer than 2 samples.
§Example
use iron_wave::Signal;
let signal = Signal::<f64>::new(vec![1.0, 2.0, 3.0, 4.0, 5.0]);
let std = signal.std(); // Sample standard deviation
assert!((std - 1.5811388300841898).abs() < 1e-10);Sourcepub fn std_population(&self) -> T
pub fn std_population(&self) -> T
Compute the population standard deviation
This calculates the population standard deviation using n as the denominator, suitable when you have the complete population rather than a sample.
Formula: σ = sqrt(Σ(xi - μ)² / n)
§Comparison with std()
- Use
std()(sample) when working with a sample from a larger population - Use
std_population()when you have the entire population - For large n, the difference becomes negligible
§Example
use iron_wave::Signal;
let signal = Signal::<f64>::new(vec![1.0, 2.0, 3.0, 4.0, 5.0]);
let std_sample = signal.std(); // Uses n-1
let std_pop = signal.std_population(); // Uses n
assert!(std_sample > std_pop); // Sample std is always largerSourcepub fn normalize(&self) -> Self
pub fn normalize(&self) -> Self
Normalize the signal to have zero mean and unit variance
Uses the sample standard deviation (with Bessel’s correction) for normalization. This is the standard approach in signal processing as it provides unbiased estimation.
The transformation applied is: x’ = (x - μ) / σ
Where:
- x: original sample value
- μ: sample mean
- σ: sample standard deviation (using n-1)
- x’: normalized value
§Returns
Returns a new signal with mean ≈ 0 and standard deviation ≈ 1. If the standard deviation is zero (constant signal), returns a clone of the original.
§Examples
use iron_wave::Signal;
let signal = Signal::<f64>::new(vec![1.0, 2.0, 3.0, 4.0, 5.0]);
let normalized = signal.normalize();
assert!((normalized.mean()).abs() < 1e-10);
assert!((normalized.std() - 1.0).abs() < 1e-10); // Sample std = 1Sourcepub fn energy(&self) -> T
pub fn energy(&self) -> T
Compute the energy of the signal (sum of squared values)
Energy = Σ(xi²) where xi are the signal samples
Sourcepub fn rms(&self) -> T
pub fn rms(&self) -> T
Compute the RMS (Root Mean Square) value of the signal
RMS = sqrt(Σ(xi²) / n) where xi are the signal samples and n is the length
Sourcepub fn peak_to_peak(&self) -> T
pub fn peak_to_peak(&self) -> T
Compute the peak-to-peak amplitude
Source§impl Signal<f64>
impl Signal<f64>
Sourcepub fn energy_fast(&self) -> f64
pub fn energy_fast(&self) -> f64
Optimized energy calculation for f64 signals
Sourcepub fn normalize_inplace(&mut self)
pub fn normalize_inplace(&mut self)
In-place normalization for f64 signals
Sourcepub fn add_scalar_inplace(&mut self, scalar: f64)
pub fn add_scalar_inplace(&mut self, scalar: f64)
Add a scalar value to all elements (in-place)
Sourcepub fn scale_inplace(&mut self, scalar: f64)
pub fn scale_inplace(&mut self, scalar: f64)
Multiply all elements by a scalar (in-place)
Trait Implementations§
Auto Trait Implementations§
impl<T> Freeze for Signal<T>
impl<T> RefUnwindSafe for Signal<T>where
T: RefUnwindSafe,
impl<T> Send for Signal<T>
impl<T> Sync for Signal<T>
impl<T> Unpin for Signal<T>where
T: Unpin,
impl<T> UnwindSafe for Signal<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more