From 308edb5b5cd5ee6d2e2962f627612e3973f5b586 Mon Sep 17 00:00:00 2001 From: Justin Worthe Date: Sun, 4 Dec 2016 22:45:54 +0200 Subject: Added sampling of a range --- src/num_traits.rs | 4 ++-- src/sinusoid.rs | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 38 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/num_traits.rs b/src/num_traits.rs index b6a2ac8..a754787 100644 --- a/src/num_traits.rs +++ b/src/num_traits.rs @@ -88,7 +88,7 @@ impl_int_pow!(u64); pub trait Float { fn recip(self) -> Self; - fn PI() -> Self; + fn pi() -> Self; } macro_rules! impl_float { @@ -97,7 +97,7 @@ macro_rules! impl_float { fn recip(self) -> Self { self.recip() } - fn PI() -> Self { + fn pi() -> Self { $pi } } diff --git a/src/sinusoid.rs b/src/sinusoid.rs index 6ee5019..1f60b03 100644 --- a/src/sinusoid.rs +++ b/src/sinusoid.rs @@ -1,6 +1,6 @@ -use std; -use std::ops::{Add, Sub, Mul, Div, Neg}; -use ::num_traits::{Trig, Pow, Float}; +use std::cmp::{PartialOrd}; +use std::ops::{Add, Sub, Mul, Div, Rem}; +use ::num_traits::{Trig, Float}; // generic number type, but realistically it's only useful for // floats. Maybe also complex @@ -25,12 +25,28 @@ impl Sinusoid where T: Float + Copy { self.frequency.recip() } } -impl Sinusoid where T: Float + Add + Mul + From + Trig + Copy + std::fmt::Display { +impl Sinusoid where T: Float + Add + Sub + Mul + Div + From + Trig + Copy + PartialOrd + Rem { pub fn radial_frequency(&self) -> T { - (T::from(2))*T::PI()*self.frequency + (T::from(2))*T::pi()*self.frequency } pub fn sample(&self, t: T) -> T { - (self.radial_frequency()*t + self.phase).cos() * self.amplitude + (self.radial_frequency()*(t%self.period()) + self.phase).cos() * self.amplitude + } + //inclusive of start, exclusive of end + pub fn sample_range(&self, start: T, end: T, sample_rate: T) -> Vec { + let sample_resolution = T::from(1) / sample_rate; + let mut result = Vec::new(); + let mut i: u16 = 0; + loop { + let t = start + T::from(i)/sample_rate; + if t >= end { + break; + } + result.push(self.sample(t)); + i += 1; + } + + result } } @@ -60,4 +76,18 @@ mod tests { assert!((sinusoid.sample(0.75)+1.0) < f32::EPSILON); assert!((sinusoid.sample(1.0)-0.0) < f32::EPSILON); } + + #[test] + fn sample_range() { + let sinusoid = Sinusoid::new(1.0 as f32, 1.0, -f32::consts::PI/2.0); //AKA sin + let samples = sinusoid.sample_range(0.0, 100.0, 4.0); + println!("Epsilon is {}", f32::EPSILON); + assert_eq!(samples.len(), 400); + for i in (0..100).map(|i| i*4) { + assert!((samples[i+0]-0.0) < f32::EPSILON, "Sample {} was {}", i+0, samples[i+0]); + assert!((samples[i+1]-1.0) < f32::EPSILON, "Sample {} was {}", i+1, samples[i+1]); + assert!((samples[i+2]-0.0) < f32::EPSILON, "Sample {} was {}", i+2, samples[i+2]); + assert!((samples[i+3]+1.0) < f32::EPSILON, "Sample {} was {}", i+3, samples[i+3]); + } + } } -- cgit v1.2.3