mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-07 12:16:42 +01:00
fix time trait usage
This commit is contained in:
parent
dc38fd3d52
commit
799228e366
7 changed files with 36 additions and 47 deletions
|
|
@ -12,8 +12,8 @@ pub const DEFAULT_PPQ: f64 = 96.0;
|
|||
#[derive(Debug, Default)]
|
||||
pub struct TimeUnit(AtomicF64);
|
||||
impl TimeUnit {
|
||||
fn get (&self) -> f64 { self.0.load(Ordering::Relaxed) }
|
||||
fn set (&self, value: f64) { self.0.store(value, Ordering::Relaxed) }
|
||||
pub fn get (&self) -> f64 { self.0.load(Ordering::Relaxed) }
|
||||
pub fn set (&self, value: f64) { self.0.store(value, Ordering::Relaxed) }
|
||||
}
|
||||
/// Temporal resolutions: sample rate, tempo, MIDI pulses per quaver (beat)
|
||||
#[derive(Debug, Clone)]
|
||||
|
|
@ -274,7 +274,7 @@ pub trait LaunchSync {
|
|||
}
|
||||
}
|
||||
/// Something that defines note quantization
|
||||
pub trait Quantize<T> { fn quant (&self) -> &TimeUnit; }
|
||||
pub trait Quantize { fn quant (&self) -> &TimeUnit; }
|
||||
/// (pulses, name), assuming 96 PPQ
|
||||
pub const NOTE_DURATIONS: [(usize, &str);26] = [
|
||||
(1, "1/384"),
|
||||
|
|
|
|||
|
|
@ -400,14 +400,14 @@ impl PhrasePlayer {
|
|||
}
|
||||
pub fn samples_since_start (&self) -> Option<usize> {
|
||||
self.phrase.as_ref()
|
||||
.map(|(started,_)|started.sample())
|
||||
.map(|started|started - self.clock.instant.sample())
|
||||
.map(|(started,_)|started.sample().get())
|
||||
.map(|started|(started - self.clock.instant.sample().get()) as usize)
|
||||
}
|
||||
pub fn playing_phrase (&self) -> Option<(usize, Arc<RwLock<Phrase>>)> {
|
||||
if let (
|
||||
Some(TransportState::Rolling), Some((started, Some(ref phrase)))
|
||||
) = (*self.clock.playing.read().unwrap(), &self.phrase) {
|
||||
Some((started.sample(), phrase.clone()))
|
||||
Some((started.sample().get() as usize, phrase.clone()))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ impl Audio for PhrasePlayer {
|
|||
self.reset_midi_out_buf(false /* FIXME where did force-reset come from? */);
|
||||
}
|
||||
let has_midi_inputs = self.has_midi_inputs();
|
||||
let quant = self.clock.quant();
|
||||
let quant = self.clock.quant().get();
|
||||
if let Some((start_frame, phrase)) = self.playing_phrase() {
|
||||
// Write chunk of phrase to output
|
||||
phrase.read().map(|phrase|{
|
||||
|
|
@ -58,10 +58,8 @@ impl Audio for PhrasePlayer {
|
|||
let pulse = self.clock.timebase.samples_to_pulse(
|
||||
(frame0 + frame - start_frame) as f64
|
||||
);
|
||||
let quantized = (
|
||||
pulse / quant as f64
|
||||
).round() as usize * quant;
|
||||
let looped = quantized % length;
|
||||
let quantized = (pulse / quant).round() * quant;
|
||||
let looped = quantized as usize % length;
|
||||
looped
|
||||
}, message);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,21 @@ pub struct TransportTime {
|
|||
pub timebase: Arc<Timebase>,
|
||||
/// Current moment in time
|
||||
pub instant: Instant,
|
||||
/// Note quantization factor
|
||||
pub quant: TimeUnit,
|
||||
/// Launch quantization factor
|
||||
pub sync: TimeUnit,
|
||||
/// Playback state
|
||||
pub playing: RwLock<Option<TransportState>>,
|
||||
/// Note quantization factor
|
||||
pub quant: AtomicUsize,
|
||||
/// Launch quantization factor
|
||||
pub sync: AtomicUsize,
|
||||
}
|
||||
impl PulsePosition<usize> for TransportTime {
|
||||
#[inline] fn pulse (&self) -> usize { self.instant.pulse() }
|
||||
#[inline] fn set_pulse (&self, usec: usize) { self.instant.set_pulse(usec); }
|
||||
impl PulsePosition for TransportTime {
|
||||
#[inline] fn pulse (&self) -> &TimeUnit { self.instant.pulse() }
|
||||
}
|
||||
impl Quantize<usize> for TransportTime {
|
||||
#[inline] fn quant (&self) -> usize { self.quant.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_quant (&self, quant: usize) { self.quant.store(quant, Ordering::Relaxed); }
|
||||
impl Quantize for TransportTime {
|
||||
#[inline] fn quant (&self) -> &TimeUnit { &self.quant }
|
||||
}
|
||||
impl LaunchSync<usize> for TransportTime {
|
||||
#[inline] fn sync (&self) -> usize { self.sync.load(Ordering::Relaxed) }
|
||||
#[inline] fn set_sync (&self, sync: usize) { self.sync.store(sync, Ordering::Relaxed); }
|
||||
impl LaunchSync for TransportTime {
|
||||
#[inline] fn sync (&self) -> &TimeUnit { &self.sync }
|
||||
}
|
||||
/// Stores and displays time-related state.
|
||||
pub struct TransportToolbar<E: Engine> {
|
||||
|
|
@ -65,7 +62,7 @@ impl<E: Engine> TransportToolbar<E> {
|
|||
Arc::new(TransportTime {
|
||||
playing: Some(TransportState::Stopped).into(),
|
||||
quant: 24.into(),
|
||||
sync: (timebase.ppq() as usize * 4).into(),
|
||||
sync: (timebase.ppq().get() * 4.).into(),
|
||||
instant: Instant::default(),
|
||||
timebase: timebase.into(),
|
||||
})
|
||||
|
|
|
|||
|
|
@ -24,36 +24,30 @@ impl TransportToolbar<Tui> {
|
|||
Ok(Some(true))
|
||||
}
|
||||
fn handle_bpm (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
let bpm = self.clock.timebase.bpm();
|
||||
let bpm = self.clock.timebase.bpm().get();
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => { self.clock.timebase.set_bpm(bpm - 1.0); },
|
||||
key!(KeyCode::Char('.')) => { self.clock.timebase.set_bpm(bpm + 1.0); },
|
||||
key!(KeyCode::Char('<')) => { self.clock.timebase.set_bpm(bpm - 0.001); },
|
||||
key!(KeyCode::Char('>')) => { self.clock.timebase.set_bpm(bpm + 0.001); },
|
||||
key!(KeyCode::Char(',')) => { self.clock.timebase.bpm.set(bpm - 1.0); },
|
||||
key!(KeyCode::Char('.')) => { self.clock.timebase.bpm.set(bpm + 1.0); },
|
||||
key!(KeyCode::Char('<')) => { self.clock.timebase.bpm.set(bpm - 0.001); },
|
||||
key!(KeyCode::Char('>')) => { self.clock.timebase.bpm.set(bpm + 0.001); },
|
||||
_ => return Ok(None)
|
||||
}
|
||||
Ok(Some(true))
|
||||
}
|
||||
fn handle_quant (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
let quant = self.clock.quant().get() as usize;
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
self.clock.set_quant(prev_note_length(self.clock.quant()));
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
self.clock.set_quant(next_note_length(self.clock.quant()));
|
||||
},
|
||||
key!(KeyCode::Char(',')) => { self.clock.quant.set(prev_note_length(quant) as f64); },
|
||||
key!(KeyCode::Char('.')) => { self.clock.quant.set(next_note_length(quant) as f64); },
|
||||
_ => return Ok(None)
|
||||
}
|
||||
return Ok(Some(true))
|
||||
}
|
||||
fn handle_sync (&mut self, from: &TuiInput) -> Perhaps<bool> {
|
||||
let sync = self.clock.sync().get() as usize;
|
||||
match from.event() {
|
||||
key!(KeyCode::Char(',')) => {
|
||||
self.clock.set_quant(prev_note_length(self.clock.sync()));
|
||||
},
|
||||
key!(KeyCode::Char('.')) => {
|
||||
self.clock.set_quant(next_note_length(self.clock.sync()));
|
||||
},
|
||||
key!(KeyCode::Char(',')) => { self.clock.quant.set(prev_note_length(sync) as f64); },
|
||||
key!(KeyCode::Char('.')) => { self.clock.quant.set(next_note_length(sync) as f64); },
|
||||
_ => return Ok(None)
|
||||
}
|
||||
return Ok(Some(true))
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ impl<E: Engine> Audio for TransportToolbar<E> {
|
|||
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.instant.set_sample(transport.pos.frame() as usize);
|
||||
self.clock.instant.sample.set(transport.pos.frame() as f64);
|
||||
if *self.clock.playing.read().unwrap() != Some(transport.state) {
|
||||
self.started = match transport.state {
|
||||
TransportState::Rolling => Some((current_frames as usize, current_usecs as usize)),
|
||||
|
|
@ -18,8 +18,8 @@ impl<E: Engine> Audio for TransportToolbar<E> {
|
|||
self.started = None;
|
||||
}
|
||||
self.clock.instant.update_from_usec(match self.started {
|
||||
Some((_, usecs)) => current_usecs as usize - usecs,
|
||||
None => 0
|
||||
Some((_, usecs)) => current_usecs as f64 - usecs as f64,
|
||||
None => 0.
|
||||
});
|
||||
Control::Continue
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,14 +20,14 @@ impl Content for TransportToolbar<Tui> {
|
|||
|
||||
row!(
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Bpm, &Outset::X(1u16, {
|
||||
let bpm = self.clock.timebase.bpm();
|
||||
let bpm = self.clock.timebase.bpm().get();
|
||||
row! { "BPM ", format!("{}.{:03}", bpm as usize, (bpm * 1000.0) % 1000.0) }
|
||||
})),
|
||||
//let quant = self.focus.wrap(self.focused, TransportToolbarFocus::Quant, &Outset::X(1u16, row! {
|
||||
//"QUANT ", ppq_to_name(self.quant as usize)
|
||||
//})),
|
||||
self.focus.wrap(self.focused, TransportToolbarFocus::Sync, &Outset::X(1u16, row! {
|
||||
"SYNC ", pulses_to_name(self.clock.sync() as usize)
|
||||
"SYNC ", pulses_to_name(self.clock.sync().get() as usize)
|
||||
}))
|
||||
).align_w().fill_x(),
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue