diff --git a/src/core/time.rs b/src/core/time.rs index b5f96b3c..cadda8d4 100644 --- a/src/core/time.rs +++ b/src/core/time.rs @@ -55,10 +55,10 @@ impl Timebase { #[inline] fn usec_per_pulse (&self) -> f64 { self.usec_per_beat() / self.ppq() as f64 } - #[inline] pub fn frame_to_pulse (&self, pulses: f64) -> f64 { + #[inline] pub fn pulse_to_frame (&self, pulses: f64) -> f64 { self.pulse_per_frame() * pulses } - #[inline] pub fn pulse_to_frame (&self, frames: f64) -> f64 { + #[inline] pub fn frame_to_pulse (&self, frames: f64) -> f64 { frames / self.pulse_per_frame() } #[inline] pub fn note_to_usec (&self, (num, den): (f64, f64)) -> f64 { @@ -97,3 +97,49 @@ impl Timebase { } } + +pub struct Ticks(pub f64); + +impl Ticks { + pub fn between_frames (&self, start: usize, end: usize) -> TicksIterator { + TicksIterator(self.0, start, start, end) + } +} + +pub struct TicksIterator(f64, usize, usize, usize); + +impl Iterator for TicksIterator { + type Item = (usize, usize); + fn next (&mut self) -> Option { + loop { + if self.1 > self.3 { + return None + } + let fpt = self.0; + let frame = self.1 as f64; + let start = self.2; + let end = self.3; + self.1 = self.1 + 1; + //println!("{fpt} {frame} {start} {end}"); + let jitter = frame.rem_euclid(fpt); // ramps + let next_jitter = (frame + 1.0).rem_euclid(fpt); + if jitter > next_jitter { // at crossing: + let time = (frame as usize) % (end as usize-start as usize); + let tick = (frame / fpt) as usize; + return Some((time, tick)) + } + } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_frames_to_ticks () { + let ticks = Ticks(12.3).between_frames(0, 100).collect::>(); + println!("{ticks:?}"); + } + +} diff --git a/src/model/phrase.rs b/src/model/phrase.rs index c72c2aa6..4da8c78a 100644 --- a/src/model/phrase.rs +++ b/src/model/phrase.rs @@ -75,50 +75,13 @@ impl Phrase { } } } -} -struct Ticks(f64); - -impl Ticks { - fn between_frames (&self, start: usize, end: usize) -> TicksIterator { - TicksIterator(self.0, start, start, end) - } -} - -struct TicksIterator(f64, usize, usize, usize); - -impl Iterator for TicksIterator { - type Item = (usize, usize); - fn next (&mut self) -> Option { - loop { - if self.1 > self.3 { - return None - } - let fpt = self.0; - let frame = self.1 as f64; - let start = self.2; - let end = self.3; - self.1 = self.1 + 1; - //println!("{fpt} {frame} {start} {end}"); - let jitter = frame.rem_euclid(fpt); // ramps - let next_jitter = (frame + 1.0).rem_euclid(fpt); - if jitter > next_jitter { // at crossing: - let time = (frame as usize) % (end as usize-start as usize); - let tick = (frame / fpt) as usize; - return Some((time, tick)) - } + pub fn record_event (&mut self, pulse: usize, message: MidiMessage) { + let contains = self.notes.contains_key(&pulse); + if contains { + self.notes.get_mut(&pulse).unwrap().push(message.clone()); + } else { + self.notes.insert(pulse, vec![message.clone()]); } } } - -#[cfg(test)] -mod test { - use super::*; - - #[test] - fn test_frames_to_ticks () { - let ticks = Ticks(12.3).between_frames(0, 100).collect::>(); - println!("{ticks:?}"); - } - -} diff --git a/src/model/track.rs b/src/model/track.rs index 98173c3c..7d41dfee 100644 --- a/src/model/track.rs +++ b/src/model/track.rs @@ -166,17 +166,12 @@ impl Track { self.midi_out_buf[time].push(bytes.to_vec()) } if recording { - if let Some(phrase) = phrase { - let pulse = timebase.pulse_to_frame((frame0 + time) as f64) as usize; - let pulse = pulse % phrase.length; + phrase.as_mut().map(|p|p.record_event({ + let pulse = timebase.frame_to_pulse((frame0 + time) as f64) as usize; let pulse = (pulse / quant) * quant; - let contains = phrase.notes.contains_key(&pulse); - if contains { - phrase.notes.get_mut(&pulse).unwrap().push(message.clone()); - } else { - phrase.notes.insert(pulse, vec![message.clone()]); - } - }; + let pulse = pulse % p.length; + pulse + }, message)); } match message { MidiMessage::NoteOn { key, .. } => {