pub trait Sample: Copy + Clone + PartialOrd + PartialEq {
type Signed: SignedSample + Duplex<Self>;
type Float: FloatSample + Duplex<Self>;
const EQUILIBRIUM: Self;
const IDENTITY: Self::Float = <Self::Float as FloatSample>::IDENTITY;
// Provided methods
fn to_sample<S>(self) -> S
where Self: ToSample<S> { ... }
fn from_sample<S>(s: S) -> Self
where Self: FromSample<S> { ... }
fn to_signed_sample(self) -> Self::Signed { ... }
fn to_float_sample(self) -> Self::Float { ... }
fn add_amp(self, amp: Self::Signed) -> Self { ... }
fn mul_amp(self, amp: Self::Float) -> Self { ... }
}
Expand description
A trait for working generically across different Sample format types.
Provides methods for converting to and from any type that implements the
FromSample
trait and provides methods for performing signal
amplitude addition and multiplication.
Example
use dasp_sample::{I24, Sample};
fn main() {
assert_eq!((-1.0).to_sample::<u8>(), 0);
assert_eq!(0.0.to_sample::<u8>(), 128);
assert_eq!(0i32.to_sample::<u32>(), 2_147_483_648);
assert_eq!(I24::new(0).unwrap(), Sample::from_sample(0.0));
assert_eq!(0.0, Sample::EQUILIBRIUM);
}
Required Associated Types§
sourcetype Signed: SignedSample + Duplex<Self>
type Signed: SignedSample + Duplex<Self>
When summing two samples of a signal together, it is necessary for both samples to be
represented in some signed format. This associated Addition
type represents the format to
which Self
should be converted for optimal Addition
performance.
For example, u32’s optimal Addition
type would be i32, u8’s would be i8, f32’s would be
f32, etc.
Specifying this as an associated type allows us to automatically determine the optimal,
lossless Addition format type for summing any two unique Sample
types together.
As a user of the sample
crate, you will never need to be concerned with this type unless
you are defining your own unique Sample
type(s).
sourcetype Float: FloatSample + Duplex<Self>
type Float: FloatSample + Duplex<Self>
When multiplying two samples of a signal together, it is necessary for both samples to be
represented in some signed, floating-point format. This associated Multiplication
type
represents the format to which Self
should be converted for optimal Multiplication
performance.
For example, u32’s optimal Multiplication
type would be f32, u64’s would be f64, i8’s
would be f32, etc.
Specifying this as an associated type allows us to automatically determine the optimal,
lossless Multiplication format type for multiplying any two unique Sample
types together.
As a user of the sample
crate, you will never need to be concerned with this type unless
you are defining your own unique Sample
type(s).
Required Associated Constants§
sourceconst EQUILIBRIUM: Self
const EQUILIBRIUM: Self
The equilibrium value for the wave that this Sample
type represents. This is normally the
value that is equal distance from both the min and max ranges of the sample.
Example
use dasp_sample::Sample;
fn main() {
assert_eq!(0.0, f32::EQUILIBRIUM);
assert_eq!(0, i32::EQUILIBRIUM);
assert_eq!(128, u8::EQUILIBRIUM);
assert_eq!(32_768_u16, Sample::EQUILIBRIUM);
}
Note: This will likely be changed to an “associated const” if the feature lands.
Provided Associated Constants§
sourceconst IDENTITY: Self::Float = <Self::Float as FloatSample>::IDENTITY
const IDENTITY: Self::Float = <Self::Float as FloatSample>::IDENTITY
The multiplicative identity of the signal.
In other words: A value which when used to scale/multiply the amplitude or frequency of a signal, returns the same signal.
This is useful as a default, non-affecting amplitude or frequency multiplier.
Example
use dasp_sample::{Sample, U48};
fn main() {
assert_eq!(1.0, f32::IDENTITY);
assert_eq!(1.0, i8::IDENTITY);
assert_eq!(1.0, u8::IDENTITY);
assert_eq!(1.0, U48::IDENTITY);
}
Provided Methods§
sourcefn to_sample<S>(self) -> Swhere
Self: ToSample<S>,
fn to_sample<S>(self) -> Swhere
Self: ToSample<S>,
Convert self
to any type that implements FromSample<Self>
.
Find more details on type-specific conversion ranges and caveats in the conv
module.
Example
use dasp_sample::Sample;
fn main() {
assert_eq!(0.0.to_sample::<i32>(), 0);
assert_eq!(0.0.to_sample::<u8>(), 128);
assert_eq!((-1.0).to_sample::<u8>(), 0);
}
sourcefn from_sample<S>(s: S) -> Selfwhere
Self: FromSample<S>,
fn from_sample<S>(s: S) -> Selfwhere
Self: FromSample<S>,
Create a Self
from any type that implements ToSample<Self>
.
Find more details on type-specific conversion ranges and caveats in the conv
module.
Example
use dasp_sample::{Sample, I24};
fn main() {
assert_eq!(f32::from_sample(128_u8), 0.0);
assert_eq!(i8::from_sample(-1.0), -128);
assert_eq!(I24::from_sample(0.0), I24::new(0).unwrap());
}
sourcefn to_signed_sample(self) -> Self::Signed
fn to_signed_sample(self) -> Self::Signed
Converts self
to the equivalent Sample
in the associated Signed
format.
This is a simple wrapper around Sample::to_sample
which may provide extra convenience in
some cases, particularly for assisting type inference.
Example
use dasp_sample::Sample;
fn main() {
assert_eq!(128_u8.to_signed_sample(), 0i8);
}
sourcefn to_float_sample(self) -> Self::Float
fn to_float_sample(self) -> Self::Float
Converts self
to the equivalent Sample
in the associated Float
format.
This is a simple wrapper around Sample::to_sample
which may provide extra convenience in
some cases, particularly for assisting type inference.
Example
use dasp_sample::Sample;
fn main() {
assert_eq!(128_u8.to_float_sample(), 0.0);
}
sourcefn add_amp(self, amp: Self::Signed) -> Self
fn add_amp(self, amp: Self::Signed) -> Self
Adds (or “offsets”) the amplitude of the Sample
by the given signed amplitude.
Self
will be converted to Self::Signed
, the addition will occur and then the result
will be converted back to Self
. These conversions allow us to correctly handle the
addition of unsigned signal formats.
Example
use dasp_sample::Sample;
fn main() {
assert_eq!(0.25.add_amp(0.5), 0.75);
assert_eq!(192u8.add_amp(-128), 64);
}
sourcefn mul_amp(self, amp: Self::Float) -> Self
fn mul_amp(self, amp: Self::Float) -> Self
Multiplies (or “scales”) the amplitude of the Sample
by the given float amplitude.
amp
> 1.0 amplifies the sample.amp
< 1.0 attenuates the sample.amp
== 1.0 yields the same sample.amp
== 0.0 yields theSample::EQUILIBRIUM
.
Self
will be converted to Self::Float
, the multiplication will occur and then the
result will be converted back to Self
. These conversions allow us to correctly handle the
multiplication of integral signal formats.
Example
use dasp_sample::Sample;
fn main() {
assert_eq!(64_i8.mul_amp(0.5), 32);
assert_eq!(0.5.mul_amp(-2.0), -1.0);
assert_eq!(64_u8.mul_amp(0.0), 128);
}