From 43f5ba85d7903301b5a8ef4605857a9ad9251151 Mon Sep 17 00:00:00 2001 From: viktaur Date: Mon, 26 Feb 2024 21:08:58 +0000 Subject: [PATCH 1/3] add support for offsetting phase --- .DS_Store | Bin 0 -> 10244 bytes .idea/.gitignore | 8 +++++ .idea/dasp.iml | 27 +++++++++++++++++ .idea/modules.xml | 8 +++++ .idea/vcs.xml | 6 ++++ dasp_signal/src/lib.rs | 65 ++++++++++++++++++++++++++++++++++++++++- 6 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 .DS_Store create mode 100644 .idea/.gitignore create mode 100644 .idea/dasp.iml create mode 100644 .idea/modules.xml create mode 100644 .idea/vcs.xml diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..76e3f8e0ee17ec73b04ee6c134b595e330eecfdc GIT binary patch literal 10244 zcmeI1zi-n(6vv-S1c4M&TQvx%nAcPo7)AUCmsiUN&3>ET##D-WA z4Be1msE{hb$Uqks7R15|3lj@F-@9|p?>Tnd3WPeGBm1Sk@4Nflx93alLPXy5T78np zC!#V=6-S40$v9NGI{S{H_)dW6A)lH{lQZ*StKFw`H=F~`0q1~oz&YR?*e?#?Gg}?y ziiz&(9B>Xe2do2Xe(-Us7{oC$QBNJX=p_JR3Agou_oM0!q94Z~j**Ed!Qq)yM3d^p zOAODXvZ-dYELOR z!{_bOcOt{kr%FijRf2~uqA@y1bJWFafmW$2Xey7Mrpr0Y&yn#Si>RX&CM0% z93`r2lD1%=b343@w|{-gwr_KJ+gatJUDN-gy>@999<0yb9n-)?eTOb*r=4{`t zTDE~1iBr4Fko7)PaYsH2KZfAkWls=Gtw`oTE)>i?jutOPaGy%hKV^PKwj& zIOmCtOirdvIE%D`)6>txDD$&{@vw^V(7|X3F)HTNUy}L!3osYvaQ=5sEdMU@lD_OE zPxK4$I1aOZVQix>_hnBi@3U2$edoDl&!~?-eS?*f&sTihiw@@H70k}FRKpy(h!_3` zlD4I23v)R8jaQa^7kP>Ad&!gidZzkSX1;guY|1&7#%^V4ICr>Zx%=wkjt|mFEjW$MjYIOfT3A!95XZ-QeGUloiM~l^h*L<6m^)@g%RzTepqry{Dbc)w1Iq&6P zIlN4r@D{5D?@*v9_#E1WvkjV0ySs5LPsdrm4Ew#$*~~im7%0*TPWqrYxv%T`xvOKY zTNl34$f;w8d)4drk3{F&8{c#%ua{I`cJ4!x`^QSjN7(INcy!2A5)U zhjYL=;2dxc>|X~C7&Kq)|6jpZ$eiE*_iqOrnRCE7@YfD_rRq#|8r8&m>wOify>=hx zU7YGry2wPGf{WgcN7UQ#_(N^SPvBHqy~v8+2XTx{)alUZbj1JkV?eyWhE=s&|0iB# e?ltgrfLs4(?-cMgRq=|RJ6fz3>#Kjb{{I8aY6;i? literal 0 HcmV?d00001 diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..13566b8 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/.idea/dasp.iml b/.idea/dasp.iml new file mode 100644 index 0000000..1034b3a --- /dev/null +++ b/.idea/dasp.iml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..05a44bf --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index dacb16d..e43b0bd 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -143,7 +143,8 @@ pub trait Signal { /// /// fn main() { /// // Infinite signals always return `false`. - /// let sine_signal = signal::rate(44_100.0).const_hz(400.0).sine(); + /// use dasp_signal::Step; + /// let sine_signal = signal::rate(44_100.0).const_hz(400.0).offset_phase(0.2).sine(); /// assert_eq!(sine_signal.is_exhausted(), false); /// /// // Signals over iterators return `true` when the inner iterator is exhausted. @@ -960,6 +961,16 @@ pub struct NoiseSimplex { phase: Phase, } +// A signal generator with offset phase. +#[derive(Clone)] +pub struct OffsetPhase +where + S: Signal +{ + const_hz: S, + offset: f64 +} + /// An iterator that yields the sum of the frames yielded by both `other` and `self` in lock-step. #[derive(Clone)] pub struct AddAmp { @@ -1850,6 +1861,14 @@ where pub fn noise_simplex(self) -> NoiseSimplex { self.phase().noise_simplex() } + + #[inline] + pub fn offset_phase(self, offset: f64) -> OffsetPhase { + OffsetPhase { + const_hz: self, + offset, + } + } } impl ConstHz { @@ -1882,6 +1901,14 @@ impl ConstHz { pub fn noise_simplex(self) -> NoiseSimplex { self.phase().noise_simplex() } + + #[inline] + pub fn offset_phase(self, offset: f64) -> OffsetPhase { + OffsetPhase { + const_hz: self, + offset, + } + } } /// Types that may be used to give a phase step size based on some `hz / sample rate`. @@ -2097,6 +2124,42 @@ where } } +impl OffsetPhase { + /// Construct a `Phase` iterator that, for every `hz` yielded by `self`, yields a phase that is + /// stepped by `hz / self.rate.hz`. + #[inline] + pub fn phase(self) -> Phase { + Phase { + step: self.const_hz, + next: self.offset, + } + } + + /// A composable alternative to the `signal::sine` function. + #[inline] + pub fn sine(self) -> Sine { + self.phase().sine() + } + + /// A composable alternative to the `signal::saw` function. + #[inline] + pub fn saw(self) -> Saw { + self.phase().saw() + } + + /// A composable alternative to the `signal::square` function. + #[inline] + pub fn square(self) -> Square { + self.phase().square() + } + + /// A composable alternative to the `signal::noise_simplex` function. + #[inline] + pub fn noise_simplex(self) -> NoiseSimplex { + self.phase().noise_simplex() + } +} + impl Signal for AddAmp where A: Signal, From 725789a95fbac7cf60100a01947abe84518d3ed5 Mon Sep 17 00:00:00 2001 From: viktaur Date: Mon, 26 Feb 2024 23:58:37 +0000 Subject: [PATCH 2/3] provide examples, fix logic --- dasp_signal/src/lib.rs | 44 +++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index e43b0bd..49a6a16 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -144,7 +144,7 @@ pub trait Signal { /// fn main() { /// // Infinite signals always return `false`. /// use dasp_signal::Step; - /// let sine_signal = signal::rate(44_100.0).const_hz(400.0).offset_phase(0.2).sine(); + /// let sine_signal = signal::rate(44_100.0).const_hz(400.0).sine(); /// assert_eq!(sine_signal.is_exhausted(), false); /// /// // Signals over iterators return `true` when the inner iterator is exhausted. @@ -965,9 +965,9 @@ pub struct NoiseSimplex { #[derive(Clone)] pub struct OffsetPhase where - S: Signal + S: Signal + Step { - const_hz: S, + step: S, offset: f64 } @@ -1456,7 +1456,7 @@ where S: Step, { Phase { - step: step, + step, next: 0.0, } } @@ -1862,11 +1862,31 @@ where self.phase().noise_simplex() } + /// Offsets the phase of a signal by the specified value, between 0.0 and 1.0 by default. + /// + /// # Example + /// + /// ```rust + /// use dasp_signal::{self as signal, Signal}; + /// + /// fn main() { + /// let step = signal::rate(4.0).const_hz(1.0).offset_phase(0.25); + /// let mut phase = step.phase(); + /// assert_eq!(phase.next(), 0.25); + /// assert_eq!(phase.next(), 0.5); + /// assert_eq!(phase.next(), 0.75); + /// assert_eq!(phase.next(), 0.0); + /// assert_eq!(phase.next(), 0.25); + /// assert_eq!(phase.next(), 0.5); + /// } + /// ``` #[inline] pub fn offset_phase(self, offset: f64) -> OffsetPhase { + let rem = 1.0; + OffsetPhase { - const_hz: self, - offset, + step: self, + offset: offset % rem, } } } @@ -1904,9 +1924,11 @@ impl ConstHz { #[inline] pub fn offset_phase(self, offset: f64) -> OffsetPhase { + let rem = 1.0; + OffsetPhase { - const_hz: self, - offset, + step: self, + offset: offset % rem, } } } @@ -2125,12 +2147,12 @@ where } impl OffsetPhase { - /// Construct a `Phase` iterator that, for every `hz` yielded by `self`, yields a phase that is - /// stepped by `hz / self.rate.hz`. + /// Construct a `Phase` iterator that is incremented via the constant step size, `self.step`, + /// and takes an offset into account. #[inline] pub fn phase(self) -> Phase { Phase { - step: self.const_hz, + step: self.step, next: self.offset, } } From 8fa21a0322beb1cc0f99730db43554e0998e27bf Mon Sep 17 00:00:00 2001 From: viktaur Date: Tue, 27 Feb 2024 00:10:15 +0000 Subject: [PATCH 3/3] cargo fmt --- dasp_signal/src/lib.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/dasp_signal/src/lib.rs b/dasp_signal/src/lib.rs index 49a6a16..6951bbc 100644 --- a/dasp_signal/src/lib.rs +++ b/dasp_signal/src/lib.rs @@ -965,10 +965,10 @@ pub struct NoiseSimplex { #[derive(Clone)] pub struct OffsetPhase where - S: Signal + Step + S: Signal + Step, { step: S, - offset: f64 + offset: f64, } /// An iterator that yields the sum of the frames yielded by both `other` and `self` in lock-step. @@ -1455,10 +1455,7 @@ pub fn phase(step: S) -> Phase where S: Step, { - Phase { - step, - next: 0.0, - } + Phase { step, next: 0.0 } } /// Creates a frame `Rate` (aka sample rate) representing the rate at which a signal may be