1use super::xorshift::XorShift32;
2use serde::{Deserialize, Serialize};
3
4#[cfg(feature = "micromath")]
5#[allow(unused_imports)]
6use micromath::F32Ext;
7#[cfg(feature = "libm")]
8#[allow(unused_imports)]
9use num_traits::float::Float;
10
11#[derive(Debug, Default, Clone, Copy, Serialize, Deserialize, Eq, Hash, PartialEq)]
12pub enum Waveform {
13 #[default]
14 TranslatedSine,
15 TranslatedSquare,
16 TranslatedRampUp,
17 TranslatedRampDown,
18 Sine,
19 RampDown,
20 Square,
21 Random,
22}
23
24impl Waveform {
25 fn value(&self, step: f32) -> f32 {
26 let step = step % 1.0;
27 return match self {
28 Waveform::TranslatedSine => 0.5 + 0.5 * (core::f32::consts::TAU * (step + 0.25)).sin(),
29 Waveform::TranslatedSquare => {
30 if step < 0.5 {
31 1.0
32 } else {
33 0.0
34 }
35 }
36 Waveform::TranslatedRampUp => {
37 if step < 0.5 {
38 0.5 * step
39 } else {
40 0.5 * step + 0.5
41 }
42 }
43 Waveform::TranslatedRampDown => {
44 if step < 0.5 {
45 1.0 - 0.5 * step
46 } else {
47 -0.5 * step + 0.5
48 }
49 }
50 Waveform::Sine => -(core::f32::consts::TAU * step).sin(),
51 Waveform::RampDown => -2.0 * step + if step < 0.5 { 0.0 } else { 2.0 },
52 Waveform::Square => {
53 if step < 0.5 {
54 -1.0
55 } else {
56 1.0
57 }
58 }
59 Waveform::Random => 0.0,
60 };
61 }
62}
63
64#[derive(Default, Clone, Copy, Debug)]
65pub struct WaveformState {
66 wf: Waveform,
67 rng: XorShift32,
68}
69
70impl WaveformState {
71 pub fn new(wf: Waveform) -> Self {
72 Self {
73 wf,
74 rng: XorShift32::default(),
75 }
76 }
77
78 pub fn value(&mut self, step: f32) -> f32 {
79 if let Waveform::Random = self.wf {
80 self.rng.next_f32()
81 } else {
82 self.wf.value(step)
83 }
84 }
85}