wip: refactor frames_to_ticks, will become Iterator

This commit is contained in:
🪞👃🪞 2024-07-06 08:40:52 +03:00
parent 4204ac4462
commit 238d307817
4 changed files with 86 additions and 46 deletions

38
Cargo.lock generated
View file

@ -111,6 +111,12 @@ dependencies = [
"rustc-demangle", "rustc-demangle",
] ]
[[package]]
name = "base64"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
[[package]] [[package]]
name = "better-panic" name = "better-panic"
version = "0.3.0" version = "0.3.0"
@ -237,6 +243,12 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "const-default"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa"
[[package]] [[package]]
name = "crossbeam-deque" name = "crossbeam-deque"
version = "0.8.5" version = "0.8.5"
@ -814,6 +826,18 @@ dependencies = [
"crossbeam-utils", "crossbeam-utils",
] ]
[[package]]
name = "rlsf"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "222fb240c3286247ecdee6fa5341e7cdad0ffdf8e7e401d9937f2d58482a20bf"
dependencies = [
"cfg-if",
"const-default",
"libc",
"svgbobdoc",
]
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.24" version = "0.1.24"
@ -947,6 +971,19 @@ dependencies = [
"syn 2.0.60", "syn 2.0.60",
] ]
[[package]]
name = "svgbobdoc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2c04b93fc15d79b39c63218f15e3fdffaa4c227830686e3b7c5f41244eb3e50"
dependencies = [
"base64",
"proc-macro2",
"quote",
"syn 1.0.109",
"unicode-width",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.109" version = "1.0.109"
@ -985,6 +1022,7 @@ dependencies = [
"midly", "midly",
"music-math", "music-math",
"ratatui", "ratatui",
"rlsf",
"toml", "toml",
"vst", "vst",
"wavers", "wavers",

View file

@ -21,3 +21,4 @@ wavers = "1.4.3"
music-math = "0.1.1" music-math = "0.1.1"
atomic_float = "1.0.0" atomic_float = "1.0.0"
fraction = "0.15.3" fraction = "0.15.3"
rlsf = "0.2.1"

View file

@ -2,6 +2,9 @@
//#![feature(unboxed_closures)] //#![feature(unboxed_closures)]
#![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)] #![allow(macro_expanded_macro_exports_accessed_by_absolute_paths)]
//#[global_allocator]
//static A: rlsf::SmallGlobalTlsf = rlsf::SmallGlobalTlsf::new();
extern crate clap; extern crate clap;
extern crate jack as _jack; extern crate jack as _jack;
extern crate crossterm; extern crate crossterm;

View file

@ -46,13 +46,13 @@ impl Phrase {
timebase: &Arc<Timebase>, timebase: &Arc<Timebase>,
(frame0, frames, _): (usize, usize, f64), (frame0, frames, _): (usize, usize, f64),
) { ) {
let start = frame0; for (time, tick) in frames_to_ticks(
let end = frame0 + frames; timebase.pulse_frame(),
let repeat = timebase.pulses_frames(self.length as f64); timebase.pulses_frames(self.length as f64),
let ticks = timebase.frames_to_ticks(start as f64, end as f64, repeat); frame0 as f64,
//panic!("{start} {end} {repeat} {ticks:?}"); (frame0 + frames) as f64,
for (time, tick) in ticks.iter() { ) {
if let Some(events) = self.notes.get(&(*tick as usize)) { if let Some(events) = self.notes.get(&(tick as usize)) {
for message in events.iter() { for message in events.iter() {
let mut buf = vec![]; let mut buf = vec![];
let channel = 0.into(); let channel = 0.into();
@ -63,59 +63,57 @@ impl Phrase {
_ => {} _ => {}
} }
LiveEvent::Midi { channel, message }.write(&mut buf).unwrap(); LiveEvent::Midi { channel, message }.write(&mut buf).unwrap();
let t = *time as usize; // FIXME miscalculated, skipping notes output[time as usize].push(buf);
output[t].push(buf);
} }
} }
} }
} }
} }
impl Timebase { fn frames_to_ticks (fpt: f64, repeat: f64, start: f64, end: f64) -> Box<dyn Iterator<Item=(usize, usize)>> {
pub fn frames_to_ticks ( let mut ticks = vec![];
&self, let mut add_frame = |frame: f64|{
start: f64, let jitter = frame.rem_euclid(fpt); // ramps
end: f64, let next_jitter = (frame + 1.0).rem_euclid(fpt);
repeat: f64, if jitter > next_jitter { // at head of ramp crossing
) -> Vec<(usize, usize)> { ticks.push((
let start_frame = start % repeat; frame as usize % (end as usize-start as usize),
let end_frame = end % repeat; (frame / fpt) as usize)
let fpt = self.pulse_frame(); );
//panic!("{start_frame} {end_frame} {fpt}");
let mut ticks = vec![];
let mut add_frame = |frame: f64|{
let jitter = frame.rem_euclid(fpt); // ramps
let next_jitter = (frame + 1.0).rem_euclid(fpt);
if jitter > next_jitter { // at head of ramp crossing
ticks.push((
frame as usize % (end as usize-start as usize),
(frame / fpt) as usize)
);
};
}; };
if start_frame < end_frame { };
for frame in start_frame as usize..end_frame as usize { let start_frame = start % repeat;
add_frame(frame as f64); let end_frame = end % repeat;
} if start_frame < end_frame {
} else { frames_to_ticks_1(&mut add_frame, start % repeat, end % repeat);
let mut frame = start_frame as usize; } else {
frames_to_ticks_2(&mut add_frame, start % repeat, end % repeat, repeat);
}
Box::new(ticks.into_iter())
}
fn frames_to_ticks_1 (add_frame: &mut impl FnMut(f64), start_frame: f64, end_frame: f64) {
for frame in start_frame as usize..end_frame as usize {
add_frame(frame as f64);
}
}
fn frames_to_ticks_2 (add_frame: &mut impl FnMut(f64), start_frame: f64, end_frame: f64, repeat: f64) {
let mut frame = start_frame as usize;
loop {
add_frame(frame as f64);
frame = frame + 1;
if frame >= repeat as usize {
frame = 0;
loop { loop {
add_frame(frame as f64); add_frame(frame as f64);
frame = frame + 1; frame = frame + 1;
if frame >= repeat as usize { if frame >= (end_frame as usize).saturating_sub(1) {
frame = 0;
loop {
add_frame(frame as f64);
frame = frame + 1;
if frame >= (end_frame as usize).saturating_sub(1) {
break
}
}
break break
} }
} }
break
} }
ticks
} }
} }