mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
run pulse counter in transport
This commit is contained in:
parent
d77fe325b0
commit
f26609ed62
4 changed files with 34 additions and 43 deletions
|
|
@ -2,10 +2,10 @@ use crate::*;
|
|||
use std::iter::Iterator;
|
||||
|
||||
/// Any numeric type that represents time
|
||||
pub trait TimeUnit: PartialEq + Copy
|
||||
pub trait TimeUnit: PartialEq + Copy + Display
|
||||
+ Add<Self, Output=Self> + Mul<Self, Output=Self>
|
||||
+ Div<Self, Output=Self> + Rem<Self, Output=Self> {}
|
||||
impl<T> TimeUnit for T where T: PartialEq + Copy
|
||||
impl<T> TimeUnit for T where T: PartialEq + Copy + Display
|
||||
+ Add<Self, Output=Self> + Mul<Self, Output=Self>
|
||||
+ Div<Self, Output=Self> + Rem<Self, Output=Self> {}
|
||||
|
||||
|
|
@ -79,6 +79,12 @@ pub trait PulsesPerQuaver<U: TimeUnit> {
|
|||
fn ppq (&self) -> U;
|
||||
/// Set the PPQ
|
||||
fn set_ppq (&self, ppq: U);
|
||||
/// Return number of pulses to which a number of microseconds corresponds (BPM-dependent)
|
||||
#[inline] fn usecs_to_pulse (&self, usec: U) -> U
|
||||
where U: TimeFloat, Self: BeatsPerMinute<U>
|
||||
{
|
||||
usec / self.usec_per_pulse()
|
||||
}
|
||||
/// Return duration of a pulse in microseconds (BPM-dependent)
|
||||
#[inline] fn usec_per_pulse (&self) -> U
|
||||
where U: TimeFloat, Self: BeatsPerMinute<U>
|
||||
|
|
@ -135,13 +141,13 @@ pub trait UsecPosition<U: TimeUnit> {
|
|||
pub trait LaunchSync<U: TimeUnit> {
|
||||
fn sync (&self) -> U;
|
||||
fn set_sync (&self, sync: U);
|
||||
#[inline] fn next_launch_sample (&self) -> U where U: TimeInteger, Self: FramePosition<U> {
|
||||
#[inline] fn next_launch_sample (&self) -> U where U: TimeInteger, Self: PulsePosition<U> {
|
||||
let sync = self.sync();
|
||||
let sample = self.sample();
|
||||
if sample % sync == U::from(0) {
|
||||
sample
|
||||
let pulse = self.pulse();
|
||||
if pulse % sync == U::from(0) {
|
||||
pulse
|
||||
} else {
|
||||
(sample / sync) * sync + U::from(1)
|
||||
(pulse / sync) * sync + U::from(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -251,10 +257,10 @@ impl Iterator for TicksIterator {
|
|||
if self.1 > self.3 {
|
||||
return None
|
||||
}
|
||||
let fpt = self.0;
|
||||
let fpt = self.0;
|
||||
let sample = self.1 as f64;
|
||||
let start = self.2;
|
||||
let end = self.3;
|
||||
let start = self.2;
|
||||
let end = self.3;
|
||||
self.1 = self.1 + 1;
|
||||
//println!("{fpt} {sample} {start} {end}");
|
||||
let jitter = sample.rem_euclid(fpt); // ramps
|
||||
|
|
|
|||
|
|
@ -237,13 +237,11 @@ impl<E: Engine> Arrangement<E> {
|
|||
match self.selected {
|
||||
ArrangementFocus::Scene(s) => {
|
||||
for (t, track) in self.tracks.iter_mut().enumerate() {
|
||||
let start = self.clock.next_launch_sample();
|
||||
track.player.enqueue_next(start, self.scenes[s].clips[t].as_ref());
|
||||
track.player.enqueue_next(self.scenes[s].clips[t].as_ref());
|
||||
}
|
||||
},
|
||||
ArrangementFocus::Clip(t, s) => {
|
||||
let start = self.clock.next_launch_sample();
|
||||
self.tracks[t].player.enqueue_next(start, self.scenes[s].clips[t].as_ref());
|
||||
self.tracks[t].player.enqueue_next(self.scenes[s].clips[t].as_ref());
|
||||
},
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -345,8 +345,9 @@ impl<E: Engine> PhrasePlayer<E> {
|
|||
pub fn toggle_monitor (&mut self) { self.monitoring = !self.monitoring; }
|
||||
pub fn toggle_record (&mut self) { self.recording = !self.recording; }
|
||||
pub fn toggle_overdub (&mut self) { self.overdub = !self.overdub; }
|
||||
pub fn enqueue_next (&mut self, start_at: usize, phrase: Option<&Arc<RwLock<Phrase>>>) {
|
||||
self.next_phrase = Some((start_at.into(), phrase.map(|p|p.clone())));
|
||||
pub fn enqueue_next (&mut self, phrase: Option<&Arc<RwLock<Phrase>>>) {
|
||||
let start = self.clock.next_launch_sample();
|
||||
self.next_phrase = Some((start.into(), phrase.map(|p|p.clone())));
|
||||
self.reset = true;
|
||||
}
|
||||
pub fn frames_since_start (&self) -> Option<usize> {
|
||||
|
|
|
|||
|
|
@ -1,28 +1,16 @@
|
|||
use crate::*;
|
||||
impl<E: Engine> Audio for TransportToolbar<E> {
|
||||
fn process (&mut self, _: &Client, scope: &ProcessScope) -> Control {
|
||||
let _ = self.update(&scope);
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
impl<E: Engine> TransportToolbar<E> {
|
||||
pub fn update (&mut self, scope: &ProcessScope) -> (bool, usize, usize, usize, usize, f64) {
|
||||
let times = scope.cycle_times().unwrap();
|
||||
let CycleTimes { current_frames, current_usecs, next_usecs, period_usecs } = times;
|
||||
let chunk_size = scope.n_frames() as usize;
|
||||
let CycleTimes { current_frames, current_usecs, next_usecs: _, period_usecs: _ } = times;
|
||||
let _chunk_size = scope.n_frames() as usize;
|
||||
let transport = self.transport.as_ref().unwrap().query().unwrap();
|
||||
self.clock.set_sample(transport.pos.frame() as usize);
|
||||
let mut reset = false;
|
||||
if *self.clock.playing.read().unwrap() != Some(transport.state) {
|
||||
match transport.state {
|
||||
TransportState::Rolling => {
|
||||
self.started = Some((current_frames as usize, current_usecs as usize));
|
||||
},
|
||||
TransportState::Stopped => {
|
||||
self.started = None;
|
||||
reset = true;
|
||||
},
|
||||
_ => {}
|
||||
self.started = match transport.state {
|
||||
TransportState::Rolling => Some((current_frames as usize, current_usecs as usize)),
|
||||
TransportState::Stopped => None,
|
||||
_ => self.started
|
||||
}
|
||||
};
|
||||
*self.clock.playing.write().unwrap() = Some(transport.state);
|
||||
|
|
@ -30,16 +18,14 @@ impl<E: Engine> TransportToolbar<E> {
|
|||
self.started = None;
|
||||
}
|
||||
match self.started {
|
||||
Some((_, usecs)) => { self.clock.set_usec(current_usecs as usize - usecs); },
|
||||
Some((_, usecs)) => {
|
||||
let usec = current_usecs as usize - usecs;
|
||||
let pulse = self.clock.usecs_to_pulse(usec as f64);
|
||||
self.clock.set_usec(usec);
|
||||
self.clock.set_pulse(pulse as usize);
|
||||
},
|
||||
None => { self.clock.set_usec(0); }
|
||||
};
|
||||
(
|
||||
reset,
|
||||
current_frames as usize,
|
||||
chunk_size as usize,
|
||||
current_usecs as usize,
|
||||
next_usecs as usize,
|
||||
period_usecs as f64
|
||||
)
|
||||
Control::Continue
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue