use std::{f64::consts::PI, time::Duration};
use crate::PatternGenerator;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Pause {
duration: Duration,
}
impl Pause {
pub fn new(duration: Duration) -> Self {
Pause { duration }
}
}
impl PatternGenerator for Pause {
fn sample(&mut self, _time: Duration) -> f64 {
0.0
}
fn duration(&self) -> Duration {
self.duration
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Constant {
level: f64,
duration: Duration,
}
impl Constant {
pub fn new(level: f64, duration: Duration) -> Self {
Constant { level, duration }
}
}
impl PatternGenerator for Constant {
fn sample(&mut self, _time: Duration) -> f64 {
self.level
}
fn duration(&self) -> Duration {
self.duration
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Linear {
from: f64,
to: f64,
duration: Duration,
}
impl Linear {
pub fn new(from: f64, to: f64, duration: Duration) -> Self {
Linear { from, to, duration }
}
}
impl PatternGenerator for Linear {
fn sample(&mut self, time: Duration) -> f64 {
self.from + (self.to - self.from) * time.as_secs_f64() / self.duration.as_secs_f64()
}
fn duration(&self) -> Duration {
self.duration
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SawWave {
amplitude: f64,
wavelength: Duration,
}
impl SawWave {
pub fn new(amplitude: f64, wavelength: Duration) -> Self {
SawWave {
amplitude,
wavelength,
}
}
}
impl PatternGenerator for SawWave {
fn sample(&mut self, time: Duration) -> f64 {
self.amplitude * (1.0 / self.wavelength.as_secs_f64()) * time.as_secs_f64() % 1.0
}
fn duration(&self) -> Duration {
self.wavelength
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TriangleWave {
amplitude: f64,
wavelength: Duration,
}
impl TriangleWave {
pub fn new(amplitude: f64, wavelength: Duration) -> Self {
TriangleWave {
amplitude,
wavelength,
}
}
}
impl PatternGenerator for TriangleWave {
fn sample(&mut self, time: Duration) -> f64 {
((2.0 * self.amplitude / self.wavelength.as_secs_f64())
* (((time.as_secs_f64() - self.wavelength.as_secs_f64() / 2.0)
% self.wavelength.as_secs_f64())
- self.wavelength.as_secs_f64() / 2.0)
.abs())
.min(self.amplitude) }
fn duration(&self) -> Duration {
self.wavelength
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SquareWave {
amplitude: f64,
wavelength: Duration,
}
impl SquareWave {
pub fn new(amplitude: f64, wavelength: Duration) -> Self {
SquareWave {
amplitude,
wavelength,
}
}
}
impl PatternGenerator for SquareWave {
fn sample(&mut self, time: Duration) -> f64 {
if time.as_secs_f64() % self.wavelength.as_secs_f64() < self.wavelength.as_secs_f64() / 2.0
{
self.amplitude
} else {
0.0
}
}
fn duration(&self) -> Duration {
self.wavelength
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SineWave {
amplitude: f64,
wavelength: Duration,
}
impl SineWave {
pub fn new(amplitude: f64, wavelength: Duration) -> Self {
SineWave {
amplitude,
wavelength,
}
}
}
impl PatternGenerator for SineWave {
fn sample(&mut self, time: Duration) -> f64 {
(self.amplitude / 2.0)
* f64::cos(
2.0 * PI
* (1.0 / self.wavelength.as_secs_f64())
* (time.as_secs_f64() + self.wavelength.as_secs_f64() / 2.0),
)
+ self.amplitude / 2.0
}
fn duration(&self) -> Duration {
self.wavelength
}
}