From a891927c73fb3aba3b8e98adf493cc7f7eeca5fc Mon Sep 17 00:00:00 2001 From: Erik Natanael Gustafsson Date: Thu, 11 Jan 2024 15:56:36 +0100 Subject: [PATCH] Rename Superseconds and Superbeats --- knyst/examples/beat_callbacks.rs | 12 +-- knyst/examples/filtered_noise.rs | 127 +++++++++++++++++++++++++++++++ knyst/src/controller.rs | 57 ++++++-------- knyst/src/gen/basic_gens.rs | 19 ++--- knyst/src/gen/delay.rs | 6 +- knyst/src/gen/osc.rs | 8 +- knyst/src/graph.rs | 20 ++--- knyst/src/graph/tests.rs | 32 ++++---- knyst/src/modal_interface.rs | 4 +- knyst/src/prelude.rs | 2 +- knyst/src/resources.rs | 8 +- knyst/src/scheduling.rs | 86 ++++++++++----------- knyst/src/time.rs | 116 +++++++++++++--------------- knyst/src/trig.rs | 16 ++-- 14 files changed, 308 insertions(+), 205 deletions(-) create mode 100644 knyst/examples/filtered_noise.rs diff --git a/knyst/examples/beat_callbacks.rs b/knyst/examples/beat_callbacks.rs index f0fdfcb..ad5a148 100644 --- a/knyst/examples/beat_callbacks.rs +++ b/knyst/examples/beat_callbacks.rs @@ -4,7 +4,7 @@ use knyst::{ controller::{print_error_handler, StartBeat}, graph::Mult, prelude::*, - time::Superbeats, + time::Beats, }; use rand::{thread_rng, Rng}; use std::time::Duration; @@ -71,20 +71,20 @@ fn main() -> Result<()> { k.schedule_change(ParameterChange::beats( node0.input("freq"), freq as Sample, - time + Superbeats::from_beats_f32(0.5), + time + Beats::from_beats_f32(0.5), )); i += 1; - if time > Superbeats::from_beats(32) { + if time > Beats::from_beats(32) { None } else { if i % 2 == 0 { - Some(Superbeats::from_beats(2)) + Some(Beats::from_beats(2)) } else { - Some(Superbeats::from_beats_f32(1.25)) + Some(Beats::from_beats_f32(1.25)) } } }, - StartBeat::Multiple(Superbeats::from_beats(4)), // Start after a multiple of 4 beats + StartBeat::Multiple(Beats::from_beats(4)), // Start after a multiple of 4 beats )); let mut input = String::new(); loop { diff --git a/knyst/examples/filtered_noise.rs b/knyst/examples/filtered_noise.rs new file mode 100644 index 0000000..3007f97 --- /dev/null +++ b/knyst/examples/filtered_noise.rs @@ -0,0 +1,127 @@ +use std::time::Duration; + +use anyhow::Result; +#[allow(unused)] +use knyst::{ + audio_backend::{CpalBackend, CpalBackendOptions, JackBackend}, + controller::print_error_handler, + envelope::Envelope, + handles::{graph_output, handle, Handle}, + modal_interface::knyst_commands, + prelude::{delay::static_sample_delay, *}, + sphere::{KnystSphere, SphereSettings}, +}; +use knyst::{ + envelope::envelope_gen, + gen::filter::svf::{svf_dynamic, svf_filter, SvfFilterType}, +}; +use rand::{thread_rng, Rng}; +fn main() -> Result<()> { + let mut backend = CpalBackend::new(CpalBackendOptions::default())?; + // let mut backend = JackBackend::new("Knyst<3JACK")?; + let _sphere = KnystSphere::start( + &mut backend, + SphereSettings { + num_inputs: 1, + num_outputs: 1, + ..Default::default() + }, + print_error_handler, + ); + + let mut rng = thread_rng(); + // loop { + // let freq = rng.gen_range(100.0..1000.0); + // let length = rng.gen_range(0.5..4.0); + // dbg!(freq, length); + // spawn_filtered_noise(freq, length); + // std::thread::sleep(Duration::from_secs_f32(length)); + // } + loop { + let mut chord = [1.0, 5. / 4., 3. / 2., 17. / 8., 7. / 4.]; + let freq = rng.gen_range(100.0..200.0); + for f in &mut chord { + *f *= freq; + } + changed_harmony_chord(&chord); + + std::thread::sleep(Duration::from_secs_f32(10.)); + } + + // graph_output(0, white_noise()); + + // graph_output(0, (sine(wt).freq(200.)).repeat_outputs(1)); + + // Wait for ENTER + println!("Press ENTER to exit"); + let mut input = String::new(); + std::io::stdin().read_line(&mut input)?; + Ok(()) +} + +fn spawn_filtered_noise(freq: f32, length: f32) { + let mut rng = thread_rng(); + let filtered_noise = upload_graph(knyst_commands().default_graph_settings(), || { + let env = envelope_gen( + 0.0, + vec![ + (1.0, rng.gen_range(0.7..1.9)), + (0.5, length * 0.34), + (0.0, length * 0.66), + ], + knyst::envelope::SustainMode::NoSustain, + StopAction::FreeGraph, + ); + let source = pink_noise(); + let sig = svf_filter( + SvfFilterType::Band, + freq, + rng.gen_range(2000.0..10000.), + 0.0, + ) + .input(source); + let sig = sig * env * 0.01; + graph_output(0, sig.channels(2)); + }); + graph_output(0, filtered_noise); +} + +fn changed_harmony_chord(new_chord: &[f32]) { + let mut rng = thread_rng(); + if rng.gen::() > 0.4 { + for f in new_chord { + let length = rng.gen_range(6.0..14.0); + let speaker = rng.gen_range(0..4); + let filtered_noise = upload_graph(knyst_commands().default_graph_settings(), || { + let env = envelope_gen( + 0.0, + vec![(1.0, 3.), (1.0, length - 5.), (0.0, 2.)], + knyst::envelope::SustainMode::NoSustain, + StopAction::FreeGraph, + ); + let source = white_noise(); + let mut sigs = vec![]; + for i in 0..5 { + let freq_detune = [1.0, 1.001, 0.999, 1.002, 0.998][i]; + let q_env = envelope_gen( + 1.0 / rng.gen_range(0.001..0.008), + vec![(1. / 0.0003, length)], + knyst::envelope::SustainMode::NoSustain, + StopAction::Continue, + ); + + let sig = svf_dynamic(SvfFilterType::Band) + .cutoff_freq(f * freq_detune) + .q(q_env) + .gain(0.0) + .input(source); + sigs.push(sig); + } + let sig = sigs[0] + sigs[1] + sigs[2] + sigs[3] + sigs[4]; + let sig = sig * env * 0.01; + graph_output(speaker, sig); + }); + graph_output(0, filtered_noise); + } + } +} diff --git a/knyst/src/controller.rs b/knyst/src/controller.rs index 6f9a3f4..dc164d3 100644 --- a/knyst/src/controller.rs +++ b/knyst/src/controller.rs @@ -31,7 +31,7 @@ use crate::{ handles::{GraphHandle, Handle}, inputs, scheduling::MusicalTimeMap, - time::Superbeats, + time::Beats, KnystError, }; use crossbeam_channel::{unbounded, Receiver, Sender}; @@ -137,9 +137,7 @@ pub trait KnystCommands { /// Add a new beat callback. See [`BeatCallback`] for documentation. fn schedule_beat_callback( &mut self, - callback: impl FnMut(Superbeats, &mut MultiThreadedKnystCommands) -> Option - + Send - + 'static, + callback: impl FnMut(Beats, &mut MultiThreadedKnystCommands) -> Option + Send + 'static, start_time: StartBeat, ) -> CallbackHandle; /// Disconnect (undo) a [`Connection`] @@ -371,12 +369,10 @@ impl KnystCommands for MultiThreadedKnystCommands { /// Add a new beat callback. See [`BeatCallback`] for documentation. fn schedule_beat_callback( &mut self, - callback: impl FnMut(Superbeats, &mut MultiThreadedKnystCommands) -> Option - + Send - + 'static, + callback: impl FnMut(Beats, &mut MultiThreadedKnystCommands) -> Option + Send + 'static, start_time: StartBeat, ) -> CallbackHandle { - let c = BeatCallback::new(callback, Superbeats::ZERO); + let c = BeatCallback::new(callback, Beats::ZERO); let handle = c.handle(); let command = Command::ScheduleBeatCallback(c, start_time); self.sender.send(command).unwrap(); @@ -713,9 +709,9 @@ impl CallbackHandle { /// The beat on which a callback should start, either an absolute beat value or the next multiple of some number of beats. pub enum StartBeat { /// An absolute time in beat - Absolute(Superbeats), + Absolute(Beats), /// The next multiple of this number of beats - Multiple(Superbeats), + Multiple(Beats), } /// Callback that is scheduled in [`Superbeats`]. The closure inside the @@ -729,18 +725,15 @@ pub enum StartBeat { /// can return the time to wait until it gets called again or `None` to remove /// the callback. pub struct BeatCallback { - callback: - Box Option + Send>, - next_timestamp: Superbeats, + callback: Box Option + Send>, + next_timestamp: Beats, free_flag: Arc, } impl BeatCallback { /// Create a new [`BeatCallback`] with a given start time fn new( - callback: impl FnMut(Superbeats, &mut MultiThreadedKnystCommands) -> Option - + Send - + 'static, - start_time: Superbeats, + callback: impl FnMut(Beats, &mut MultiThreadedKnystCommands) -> Option + Send + 'static, + start_time: Beats, ) -> Self { let free_flag = Arc::new(AtomicBool::new(false)); Self { @@ -942,10 +935,10 @@ impl Controller { StartBeat::Absolute(beats) => beats, StartBeat::Multiple(beats) => { let mut i = 1; - while beats * Superbeats::from_beats(i) < current_beats { + while beats * Beats::from_beats(i) < current_beats { i += 1; } - beats * Superbeats::from_beats(i) + beats * Beats::from_beats(i) } }; // println!( @@ -1040,7 +1033,7 @@ impl Controller { let c = &mut self.beat_callbacks[i - 1]; if c.next_timestamp < current_time_beats || c.next_timestamp.checked_sub(current_time_beats).unwrap() - < Superbeats::from_beats_f32(0.25) + < Beats::from_beats_f32(0.25) { if let CallbackResult::Delete = c.run_callback(&mut k) { self.beat_callbacks.remove(i - 1); @@ -1141,20 +1134,20 @@ mod tests { graph_output(0, once_trig()); }); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(5, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(5, sr as u64)), || { graph_output(0, once_trig()); }, ); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(10, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(10, sr as u64)), || { graph_output(0, once_trig()); }, ); let mut og = None; schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(16, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(16, sr as u64)), || { og = Some(one_gen()); graph_output(0, og.unwrap()); @@ -1162,20 +1155,20 @@ mod tests { ); let og = og.unwrap(); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(17, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(17, sr as u64)), || { og.passthrough(2.0); }, ); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(19, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(19, sr as u64)), || { og.passthrough(3.0); }, ); // Try with the pure KnystCommands methods as well. knyst_commands().start_scheduling_bundle(knyst::graph::Time::Superseconds( - Superseconds::from_samples(20, sr as u64), + Seconds::from_samples(20, sr as u64), )); og.passthrough(4.0); knyst_commands().upload_scheduling_bundle(); @@ -1216,20 +1209,20 @@ mod tests { graph_output(0, once_trig()); }); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(5, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(5, sr as u64)), || { graph_output(0, once_trig()); }, ); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(10, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(10, sr as u64)), || { graph_output(0, once_trig()); }, ); let mut og = None; schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(16, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(16, sr as u64)), || { og = Some(one_gen()); graph_output(0, og.unwrap()); @@ -1237,7 +1230,7 @@ mod tests { ); let og = og.unwrap(); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(17, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(17, sr as u64)), || { og.passthrough(2.0); @@ -1246,14 +1239,14 @@ mod tests { }, ); schedule_bundle( - crate::graph::Time::Superseconds(Superseconds::from_samples(19, sr as u64)), + crate::graph::Time::Superseconds(Seconds::from_samples(19, sr as u64)), || { og.passthrough(3.0); }, ); // Try with the pure KnystCommands methods as well. knyst_commands().start_scheduling_bundle(knyst::graph::Time::Superseconds( - Superseconds::from_samples(20, sr as u64), + Seconds::from_samples(20, sr as u64), )); og.passthrough(4.0); knyst_commands().upload_scheduling_bundle(); diff --git a/knyst/src/gen/basic_gens.rs b/knyst/src/gen/basic_gens.rs index 9b333c8..b4451c2 100644 --- a/knyst/src/gen/basic_gens.rs +++ b/knyst/src/gen/basic_gens.rs @@ -1,6 +1,6 @@ //! Includes basic `Gen`s such as `Mul` and `Range` -use crate::{self as knyst, prelude::Superseconds, SampleRate}; +use crate::{self as knyst, prelude::Seconds, SampleRate}; use knyst_macro::impl_gen; use crate::{ @@ -319,7 +319,7 @@ impl PanMonoToStereo { pub struct LineSegment { start: Sample, end: Sample, - dur: Superseconds, + dur: Seconds, num_samples_left: usize, current_value: f64, step: f64, @@ -329,7 +329,7 @@ impl LineSegment { #[allow(missing_docs)] #[new] #[must_use] - pub fn new(start: Sample, end: Sample, dur: Superseconds) -> Self { + pub fn new(start: Sample, end: Sample, dur: Seconds) -> Self { Self { start, end, @@ -375,7 +375,7 @@ impl LineSegment { pub struct ExpLineSegment { start: Sample, end: Sample, - dur: Superseconds, + dur: Seconds, num_samples_left: usize, current_value: f64, coeff: f64, @@ -385,7 +385,7 @@ impl ExpLineSegment { #[allow(missing_docs)] #[new] #[must_use] - pub fn new(start: Sample, end: Sample, dur: Superseconds) -> Self { + pub fn new(start: Sample, end: Sample, dur: Seconds) -> Self { Self { start, end, @@ -429,17 +429,14 @@ impl ExpLineSegment { #[cfg(test)] mod tests { - use crate::{handles::graph_output, offline::KnystOffline, prelude::Superseconds}; + use crate::{handles::graph_output, offline::KnystOffline, prelude::Seconds}; use super::{exp_line_segment, line_segment}; #[test] fn line_segment_test() { let mut kt = KnystOffline::new(8, 8, 0, 1); - graph_output( - 0, - line_segment(1.0, 2.0, Superseconds::from_seconds_f64(1.0)), - ); + graph_output(0, line_segment(1.0, 2.0, Seconds::from_seconds_f64(1.0))); kt.process_block(); let output = kt.output_channel(0).unwrap(); for i in 0..8 { @@ -457,7 +454,7 @@ mod tests { let mut kt = KnystOffline::new(sr, sr, 0, 1); graph_output( 0, - exp_line_segment(1.0, 2.0, Superseconds::from_seconds_f64(1.0)), + exp_line_segment(1.0, 2.0, Seconds::from_seconds_f64(1.0)), ); kt.process_block(); let output = kt.output_channel(0).unwrap(); diff --git a/knyst/src/gen/delay.rs b/knyst/src/gen/delay.rs index f5002b7..7bef6df 100644 --- a/knyst/src/gen/delay.rs +++ b/knyst/src/gen/delay.rs @@ -7,7 +7,7 @@ use crate::BlockSize; use crate::SampleRate; use knyst_macro::impl_gen; -use crate::time::Superseconds; +use crate::time::Seconds; use crate::Sample; /// Delay by an integer number of samples, no interpolation. This is good for e.g. triggers. @@ -20,7 +20,7 @@ use crate::Sample; pub struct SampleDelay { buffer: Vec, write_position: usize, - max_delay_length: Superseconds, + max_delay_length: Seconds, } impl SampleDelay {} @@ -28,7 +28,7 @@ impl SampleDelay {} impl SampleDelay { #[new] /// Create a new SampleDelay with a maximum delay time. - pub fn new(max_delay_length: Superseconds) -> Self { + pub fn new(max_delay_length: Seconds) -> Self { Self { buffer: vec![0.0; 0], max_delay_length, diff --git a/knyst/src/gen/osc.rs b/knyst/src/gen/osc.rs index f06e15e..d60125d 100644 --- a/knyst/src/gen/osc.rs +++ b/knyst/src/gen/osc.rs @@ -5,7 +5,7 @@ use crate::buffer::Buffer; use crate::{ buffer::BufferKey, gen::{Gen, GenContext, GenState, StopAction}, - prelude::Superseconds, + prelude::Seconds, resources::{BufferId, IdOrKey, WavetableId, WavetableKey}, wavetable::{Wavetable, WavetablePhase, FRACTIONAL_PART, TABLE_SIZE}, Resources, Sample, SampleRate, @@ -132,7 +132,7 @@ pub struct BufferReader { /// true if the [`BufferReader`] should loop the buffer pub looping: bool, stop_action: StopAction, - start_time: Superseconds, + start_time: Seconds, } #[impl_gen] @@ -153,7 +153,7 @@ impl BufferReader { finished: false, looping, stop_action, - start_time: Superseconds::ZERO, + start_time: Seconds::ZERO, } } /// Jump back to the start of the buffer @@ -166,7 +166,7 @@ impl BufferReader { self.finished = false; } /// Jump to a specific point in the buffer in samples. Has to be called before processing starts. - pub fn start_at(mut self, start_time: Superseconds) -> Self { + pub fn start_at(mut self, start_time: Seconds) -> Self { self.start_time = start_time; self } diff --git a/knyst/src/graph.rs b/knyst/src/graph.rs index 9f146f0..a9e8ea2 100644 --- a/knyst/src/graph.rs +++ b/knyst/src/graph.rs @@ -51,7 +51,7 @@ pub use run_graph::{RunGraph, RunGraphSettings}; use crate::inspection::{EdgeInspection, EdgeSource, GraphInspection, NodeInspection}; use crate::scheduling::MusicalTimeMap; -use crate::time::{Superbeats, Superseconds}; +use crate::time::{Beats, Seconds}; use rtrb::RingBuffer; use slotmap::{new_key_type, SecondaryMap, SlotMap}; @@ -242,7 +242,7 @@ impl SimultaneousChanges { } } /// Empty `Self` set to be scheduled a specified beat time. - pub fn beats(beats: Superbeats) -> Self { + pub fn beats(beats: Beats) -> Self { Self { time: Time::Beats(beats), changes: vec![], @@ -341,7 +341,7 @@ pub struct ParameterChange { impl ParameterChange { /// Schedule a change at a specific time in [`Superbeats`] - pub fn beats(channel: NodeInput, value: impl Into, beats: Superbeats) -> Self { + pub fn beats(channel: NodeInput, value: impl Into, beats: Beats) -> Self { Self { input: channel, value: value.into(), @@ -352,7 +352,7 @@ impl ParameterChange { pub fn superseconds( channel: NodeInput, value: impl Into, - superseconds: Superseconds, + superseconds: Seconds, ) -> Self { Self { input: channel, @@ -386,9 +386,9 @@ impl ParameterChange { #[allow(missing_docs)] #[derive(Clone, Copy, Debug)] pub enum Time { - Beats(Superbeats), + Beats(Beats), DurationFromNow(Duration), - Superseconds(Superseconds), + Superseconds(Seconds), Immediately, } @@ -397,7 +397,7 @@ pub enum Time { #[derive(Clone, Copy, Debug)] pub enum TimeOffset { Frames(i64), - Superseconds(Relative), + Superseconds(Relative), } impl TimeOffset { @@ -1887,12 +1887,12 @@ impl Graph { /// Returns the current audio thread time in Superbeats based on the /// MusicalTimeMap, or None if it is not available (e.g. if the Graph has /// not been started yet). - pub fn get_current_time_musical(&self) -> Option { + pub fn get_current_time_musical(&self) -> Option { if let Some(ggc) = &self.graph_gen_communicator { let ts_samples = ggc.timestamp.load(Ordering::Relaxed); let seconds = (ts_samples as f64) / (self.sample_rate as f64); ggc.scheduler - .seconds_to_musical_time_superbeats(Superseconds::from_seconds_f64(seconds)) + .seconds_to_musical_time_superbeats(Seconds::from_seconds_f64(seconds)) } else { None } @@ -3912,7 +3912,7 @@ impl Scheduler { } } } - fn seconds_to_musical_time_superbeats(&self, ts: Superseconds) -> Option { + fn seconds_to_musical_time_superbeats(&self, ts: Seconds) -> Option { match self { Scheduler::Stopped { .. } => None, Scheduler::Running { diff --git a/knyst/src/graph/tests.rs b/knyst/src/graph/tests.rs index 1bd71c5..924c3f4 100644 --- a/knyst/src/graph/tests.rs +++ b/knyst/src/graph/tests.rs @@ -12,7 +12,7 @@ use crate::controller::KnystCommands; use crate::gen::{BufferReader, WavetableOscillatorOwned}; use crate::graph::{FreeError, Oversampling, ScheduleError}; use crate::prelude::*; -use crate::time::{Superbeats, Superseconds}; +use crate::time::{Beats, Seconds}; use crate::{controller::Controller, graph::connection::constant}; // Outputs its input value + 1 @@ -505,21 +505,21 @@ fn scheduling() { .schedule_change(ParameterChange::superseconds( node0.input(0), 1.0, - Superseconds::from_samples(3, SR), + Seconds::from_samples(3, SR), )) .unwrap(); graph .schedule_change(ParameterChange::superseconds( node0.input("passthrough"), 2.0, - Superseconds::from_samples(2, SR), + Seconds::from_samples(2, SR), )) .unwrap(); graph .schedule_change(ParameterChange::superseconds( node1.input(0), 10.0, - Superseconds::from_samples(7, SR), + Seconds::from_samples(7, SR), )) .unwrap(); // Schedule far into the future, this should not show up in the test output @@ -541,21 +541,21 @@ fn scheduling() { .schedule_change(ParameterChange::superseconds( node0.input(0), 0.0, - Superseconds::from_samples(5, SR), + Seconds::from_samples(5, SR), )) .unwrap(); graph .schedule_change(ParameterChange::superseconds( node1.input(0), 0.0, - Superseconds::from_samples(6, SR), + Seconds::from_samples(6, SR), )) .unwrap(); assert_eq!( graph.schedule_change(ParameterChange::superseconds( node1.input("pasta"), 100.0, - Superseconds::from_samples(6, SR) + Seconds::from_samples(6, SR) )), Err(ScheduleError::InputLabelNotFound("pasta")) ); @@ -817,7 +817,7 @@ fn start_nodes_with_sample_precision() { GenState::Continue }) .output("out"), - Time::Superseconds(Superseconds::from_samples(1, SR)), + Time::Superseconds(Seconds::from_samples(1, SR)), ); graph.connect(n0.to_graph_out()).unwrap(); let mut counter1 = 0.; @@ -830,7 +830,7 @@ fn start_nodes_with_sample_precision() { GenState::Continue }) .output("out"), - Time::Superseconds(Superseconds::from_samples(2, SR)), + Time::Superseconds(Seconds::from_samples(2, SR)), ); graph.connect(n1.to_graph_out()).unwrap(); let mut run_graph = test_run_graph(&mut graph, RunGraphSettings::default()); @@ -850,7 +850,7 @@ fn start_nodes_with_sample_precision() { GenState::Continue }) .output("out"), - Time::Superseconds(Superseconds::from_samples(3 + BLOCK_SIZE as u64, SR)), + Time::Superseconds(Seconds::from_samples(3 + BLOCK_SIZE as u64, SR)), ); let mut counter3 = 0.; let n3 = graph.push_at_time( @@ -862,7 +862,7 @@ fn start_nodes_with_sample_precision() { GenState::Continue }) .output("out"), - Time::Superseconds(Superseconds::from_samples(4 + BLOCK_SIZE as u64, SR)), + Time::Superseconds(Seconds::from_samples(4 + BLOCK_SIZE as u64, SR)), ); graph.connect(n2.to_graph_out()).unwrap(); graph.connect(n3.to_graph_out()).unwrap(); @@ -900,7 +900,7 @@ fn beat_scheduling() { .change_musical_time_map(|mtm| { mtm.insert( crate::scheduling::TempoChange::NewTempo { bpm: 120.0 }, - Superbeats::from_beats(1), + Beats::from_beats(1), ); }) .unwrap(); @@ -908,28 +908,28 @@ fn beat_scheduling() { .schedule_change(ParameterChange::beats( node.input(0), 1.0, - Superbeats::from_fractional_beats::<4>(0, 1), + Beats::from_fractional_beats::<4>(0, 1), )) .unwrap(); graph .schedule_change(ParameterChange::beats( node.input(0), 2.0, - Superbeats::from_fractional_beats::<4>(0, 2), + Beats::from_fractional_beats::<4>(0, 2), )) .unwrap(); graph .schedule_change(ParameterChange::beats( node.input(0), 3.0, - Superbeats::from_fractional_beats::<4>(1, 0), + Beats::from_fractional_beats::<4>(1, 0), )) .unwrap(); graph .schedule_change(ParameterChange::beats( node.input(0), 4.0, - Superbeats::from_fractional_beats::<2>(1, 1), + Beats::from_fractional_beats::<2>(1, 1), )) .unwrap(); graph.update(); diff --git a/knyst/src/modal_interface.rs b/knyst/src/modal_interface.rs index 64c6922..aafc711 100644 --- a/knyst/src/modal_interface.rs +++ b/knyst/src/modal_interface.rs @@ -124,9 +124,9 @@ impl KnystCommands for UnifiedKnystCommands { fn schedule_beat_callback( &mut self, callback: impl FnMut( - crate::prelude::Superbeats, + crate::prelude::Beats, &mut MultiThreadedKnystCommands, - ) -> Option + ) -> Option + Send + 'static, start_time: crate::controller::StartBeat, diff --git a/knyst/src/prelude.rs b/knyst/src/prelude.rs index 740cfe9..97cdd3d 100644 --- a/knyst/src/prelude.rs +++ b/knyst/src/prelude.rs @@ -20,7 +20,7 @@ pub use crate::modal_interface::knyst_commands; pub use crate::resources::{IdOrKey, WavetableId, WavetableKey}; pub use crate::resources::{Resources, ResourcesSettings}; pub use crate::sphere::{KnystSphere, SphereSettings}; -pub use crate::time::{Superbeats, Superseconds}; +pub use crate::time::{Beats, Seconds}; pub use crate::wavetable::{Wavetable, TABLE_POWER, TABLE_SIZE}; pub use crate::{BlockSize, Sample, SampleRate, Trig}; pub use knyst_macro::impl_gen; diff --git a/knyst/src/resources.rs b/knyst/src/resources.rs index 2c7c915..b9e6509 100644 --- a/knyst/src/resources.rs +++ b/knyst/src/resources.rs @@ -12,7 +12,7 @@ use std::{collections::HashMap, hash::Hash, sync::atomic::AtomicU64}; use crate::{ buffer::{Buffer, BufferKey}, - prelude::Superseconds, + prelude::Seconds, wavetable::Wavetable, }; @@ -87,7 +87,7 @@ type IdType = u64; pub struct BufferId { id: IdType, channels: usize, - duration: Superseconds, + duration: Seconds, } impl BufferId { @@ -96,7 +96,7 @@ impl BufferId { Self { id: NEXT_BUFFER_ID.fetch_add(1, std::sync::atomic::Ordering::Release), channels: buf.num_channels(), - duration: Superseconds::from_seconds_f64(buf.length_seconds()), + duration: Seconds::from_seconds_f64(buf.length_seconds()), } } /// Number of channels in the Buffer this id points to @@ -104,7 +104,7 @@ impl BufferId { self.channels } /// The duration of this buffer at its native sample rate - pub fn duration(&self) -> Superseconds { + pub fn duration(&self) -> Seconds { self.duration } } diff --git a/knyst/src/scheduling.rs b/knyst/src/scheduling.rs index 578ea29..acd1826 100644 --- a/knyst/src/scheduling.rs +++ b/knyst/src/scheduling.rs @@ -1,8 +1,8 @@ //! This module contains things related to scheduling that are more generic than //! graph internals. -use crate::time::Superbeats; -use crate::time::Superseconds; +use crate::time::Beats; +use crate::time::Seconds; use std::sync::Arc; use std::sync::RwLock; @@ -15,17 +15,15 @@ pub enum TempoChange { impl TempoChange { /// Give the duration in seconds of the TempoChange - pub fn to_secs_f64(&self, duration: Superbeats) -> f64 { + pub fn to_secs_f64(&self, duration: Beats) -> f64 { match self { TempoChange::NewTempo { bpm } => (duration.as_beats_f64() * 60.) / bpm, } } /// Converts a duration in seconds within this TempoChange to Superbeats - pub fn secs_f64_to_beats(&self, section_duration: f64) -> Superbeats { + pub fn secs_f64_to_beats(&self, section_duration: f64) -> Beats { match self { - TempoChange::NewTempo { bpm } => { - Superbeats::from_beats_f64(*bpm * (section_duration / 60.)) - } + TempoChange::NewTempo { bpm } => Beats::from_beats_f64(*bpm * (section_duration / 60.)), } } } @@ -38,7 +36,7 @@ impl TempoChange { /// be possible to map [`Superbeats`] to seconds. The tempo_changes must be /// sorted in ascending order. pub struct MusicalTimeMap { - tempo_changes: Vec<(TempoChange, Superbeats)>, + tempo_changes: Vec<(TempoChange, Beats)>, } impl MusicalTimeMap { /// Make a new [`MusicalTimeMap`] with a single BPM tempo value of 60 bpm at time 0 @@ -64,7 +62,7 @@ impl MusicalTimeMap { /// assert!(map.is_sorted()); /// assert_eq!(map.len(), 6); /// ``` - pub fn insert(&mut self, tempo_change: TempoChange, time_stamp: Superbeats) { + pub fn insert(&mut self, tempo_change: TempoChange, time_stamp: Beats) { let mut same_timestamp_index = None; for (i, (_change, time)) in self.tempo_changes.iter().enumerate() { if *time == time_stamp { @@ -87,10 +85,10 @@ impl MusicalTimeMap { // Uphold the promise that there is a first tempo change that starts at zero if self.tempo_changes.is_empty() { self.tempo_changes - .push((TempoChange::NewTempo { bpm: 60.0 }, Superbeats::new(0, 0))); + .push((TempoChange::NewTempo { bpm: 60.0 }, Beats::new(0, 0))); } - if self.tempo_changes[0].1 != Superbeats::new(0, 0) { - self.insert(TempoChange::NewTempo { bpm: 60.0 }, Superbeats::new(0, 0)); + if self.tempo_changes[0].1 != Beats::new(0, 0) { + self.insert(TempoChange::NewTempo { bpm: 60.0 }, Beats::new(0, 0)); } } /// Replace a [`TempoChange`] @@ -102,12 +100,12 @@ impl MusicalTimeMap { /// Move a [`TempoChange`] to a new position in [`Superbeats`]. If the /// first tempo change is moved a 60 bpm tempo change will be inserted at /// the start. - pub fn move_tempo_change(&mut self, index: usize, time_stamp: Superbeats) { + pub fn move_tempo_change(&mut self, index: usize, time_stamp: Beats) { if index <= self.tempo_changes.len() { self.tempo_changes[index].1 = time_stamp; } - if index == 0 && time_stamp != Superbeats::new(0, 0) { - self.insert(TempoChange::NewTempo { bpm: 60.0 }, Superbeats::new(0, 0)); + if index == 0 && time_stamp != Beats::new(0, 0) { + self.insert(TempoChange::NewTempo { bpm: 60.0 }, Beats::new(0, 0)); } } /// Convert a [`Superbeats`] timestamp to seconds using this map. @@ -137,10 +135,10 @@ impl MusicalTimeMap { /// 16.0 * 0.5 + 16.0 * 1.0 + (1000. * 0.01) /// ); /// ``` - pub fn musical_time_to_secs_f64(&self, ts: Superbeats) -> f64 { + pub fn musical_time_to_secs_f64(&self, ts: Beats) -> f64 { // If we have not upheld our promise about the state of the MusicalTimeMap there is a bug assert!(self.tempo_changes.len() > 0); - assert_eq!(self.tempo_changes[0].1, Superbeats::new(0, 0)); + assert_eq!(self.tempo_changes[0].1, Beats::new(0, 0)); let mut accumulated_seconds: f64 = 0.0; let mut duration_remaining = ts; // Accumulate the entire tempo changes ranges up to the one we are in @@ -160,12 +158,12 @@ impl MusicalTimeMap { duration_remaining = duration_remaining.checked_sub(section_duration).unwrap(); } else { accumulated_seconds += tempo_change_pair0.0.to_secs_f64(duration_remaining); - duration_remaining = Superbeats::new(0, 0); + duration_remaining = Beats::new(0, 0); break; } } - if duration_remaining > Superbeats::new(0, 0) { + if duration_remaining > Beats::new(0, 0) { // The time stamp given is after the last tempo change, simply // calculate the remaining duration using the last tempo change. accumulated_seconds += self @@ -179,11 +177,11 @@ impl MusicalTimeMap { accumulated_seconds } /// Convert a timestamp in seconds to beats using self - pub fn superseconds_to_superbeats(&self, ts: Superseconds) -> Superbeats { + pub fn superseconds_to_superbeats(&self, ts: Seconds) -> Beats { // If we have not upheld our promise about the state of the MusicalTimeMap there is a bug assert!(self.tempo_changes.len() > 0); - assert_eq!(self.tempo_changes[0].1, Superbeats::ZERO); - let mut accumulated_beats = Superbeats::ZERO; + assert_eq!(self.tempo_changes[0].1, Beats::ZERO); + let mut accumulated_beats = Beats::ZERO; let mut duration_remaining = ts.to_seconds_f64(); // Accumulate the entire tempo changes ranges up to the one we are in for (tempo_change_pair0, tempo_change_pair1) in self @@ -227,7 +225,7 @@ impl MusicalTimeMap { } /// Returns true if the tempo changes are in order, false if not. For testing purposes. pub fn is_sorted(&self) -> bool { - let mut last_musical_time = Superbeats::new(0, 0); + let mut last_musical_time = Beats::new(0, 0); for &(_, musical_time) in &self.tempo_changes { if musical_time < last_musical_time { return false; @@ -242,7 +240,7 @@ impl MusicalTimeMap { impl Default for MusicalTimeMap { fn default() -> Self { Self { - tempo_changes: vec![(TempoChange::NewTempo { bpm: 60.0 }, Superbeats::new(0, 0))], + tempo_changes: vec![(TempoChange::NewTempo { bpm: 60.0 }, Beats::new(0, 0))], } } } @@ -252,56 +250,50 @@ pub struct MusicalTimeMapRef(Arc>); #[cfg(test)] mod tests { - use crate::time::Superseconds; + use crate::time::Seconds; #[test] fn musical_time_test() { - use crate::scheduling::{MusicalTimeMap, Superbeats, TempoChange}; + use crate::scheduling::{Beats, MusicalTimeMap, TempoChange}; let mut map = MusicalTimeMap::new(); - assert_eq!(map.musical_time_to_secs_f64(Superbeats::new(0, 0)), 0.0); + assert_eq!(map.musical_time_to_secs_f64(Beats::new(0, 0)), 0.0); // Starts with a TempoChange for a constant 60 bpm per default - assert_eq!(map.musical_time_to_secs_f64(Superbeats::new(1, 0)), 1.0); + assert_eq!(map.musical_time_to_secs_f64(Beats::new(1, 0)), 1.0); assert_eq!( - map.musical_time_to_secs_f64(Superbeats::from_fractional_beats::<4>(5, 3)), + map.musical_time_to_secs_f64(Beats::from_fractional_beats::<4>(5, 3)), 5.75 ); assert_eq!( - map.superseconds_to_superbeats(Superseconds::from_seconds_f64(2.)), - Superbeats::from_beats(2) + map.superseconds_to_superbeats(Seconds::from_seconds_f64(2.)), + Beats::from_beats(2) ); map.replace(0, TempoChange::NewTempo { bpm: 120.0 }); - assert_eq!(map.musical_time_to_secs_f64(Superbeats::new(1, 0)), 0.5); + assert_eq!(map.musical_time_to_secs_f64(Beats::new(1, 0)), 0.5); assert_eq!( - map.musical_time_to_secs_f64(Superbeats::from_fractional_beats::<4>(5, 3)), + map.musical_time_to_secs_f64(Beats::from_fractional_beats::<4>(5, 3)), 5.75 * 0.5 ); - map.insert( - TempoChange::NewTempo { bpm: 60.0 }, - Superbeats::from_beats(16), - ); - map.insert( - TempoChange::NewTempo { bpm: 6000.0 }, - Superbeats::from_beats(32), - ); + map.insert(TempoChange::NewTempo { bpm: 60.0 }, Beats::from_beats(16)); + map.insert(TempoChange::NewTempo { bpm: 6000.0 }, Beats::from_beats(32)); assert_eq!( - map.musical_time_to_secs_f64(Superbeats::from_beats(17)), + map.musical_time_to_secs_f64(Beats::from_beats(17)), 16.0 * 0.5 + 1.0 ); assert_eq!( - map.musical_time_to_secs_f64(Superbeats::from_beats(32)), + map.musical_time_to_secs_f64(Beats::from_beats(32)), 16.0 * 0.5 + 16.0 ); assert_eq!( - map.musical_time_to_secs_f64(Superbeats::from_beats(33)), + map.musical_time_to_secs_f64(Beats::from_beats(33)), 16.0 * 0.5 + 16.0 + 0.01 ); assert_eq!( - map.musical_time_to_secs_f64(Superbeats::from_beats(32 + 1000)), + map.musical_time_to_secs_f64(Beats::from_beats(32 + 1000)), 16.0 * 0.5 + 16.0 + 10. ); assert_eq!( - map.superseconds_to_superbeats(Superseconds::from_seconds_f64(2.)), - Superbeats::from_beats(4) + map.superseconds_to_superbeats(Seconds::from_seconds_f64(2.)), + Beats::from_beats(4) ); } } diff --git a/knyst/src/time.rs b/knyst/src/time.rs index 338ff34..1c3c443 100644 --- a/knyst/src/time.rs +++ b/knyst/src/time.rs @@ -18,11 +18,11 @@ pub static SUBBEAT_TESIMALS_PER_BEAT: u32 = 1_476_034_560; /// Inspired by BillyDM's blog post https://billydm.github.io/blog/time-keeping/ #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] #[cfg_attr(feature = "serde-derive", derive(serde::Serialize, serde::Deserialize))] -pub struct Superseconds { +pub struct Seconds { seconds: u32, subsample_tesimals: u32, } -impl Superseconds { +impl Seconds { /// 0 seconds 0 tesmials pub const ZERO: Self = Self { seconds: 0, @@ -101,7 +101,7 @@ impl Superseconds { } } } -impl From for Superseconds { +impl From for Seconds { fn from(value: Duration) -> Self { let seconds = value.as_secs(); let nanos = value.subsec_nanos(); @@ -111,12 +111,12 @@ impl From for Superseconds { } } -impl PartialOrd for Superseconds { +impl PartialOrd for Seconds { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for Superseconds { +impl Ord for Seconds { fn cmp(&self, other: &Self) -> std::cmp::Ordering { if self.seconds == other.seconds { self.subsample_tesimals.cmp(&other.subsample_tesimals) @@ -126,10 +126,10 @@ impl Ord for Superseconds { } } -impl ops::Add for Superseconds { +impl ops::Add for Seconds { type Output = Self; - fn add(self, rhs: Superseconds) -> Self::Output { + fn add(self, rhs: Seconds) -> Self::Output { let mut seconds = self.seconds + rhs.seconds; let mut subsample_tesimals = self.subsample_tesimals + rhs.subsample_tesimals; while subsample_tesimals >= SUBSAMPLE_TESIMALS_PER_SECOND { @@ -137,60 +137,60 @@ impl ops::Add for Superseconds { subsample_tesimals -= SUBSAMPLE_TESIMALS_PER_SECOND; } - Superseconds::new(seconds, subsample_tesimals) + Seconds::new(seconds, subsample_tesimals) } } -impl ops::AddAssign for Superseconds { - fn add_assign(&mut self, rhs: Superseconds) { +impl ops::AddAssign for Seconds { + fn add_assign(&mut self, rhs: Seconds) { let result = *self + rhs; *self = result; } } -impl ops::Mul for Superseconds { +impl ops::Mul for Seconds { type Output = Self; - fn mul(self, rhs: Superseconds) -> Self::Output { + fn mul(self, rhs: Seconds) -> Self::Output { let mut seconds = self.seconds * rhs.seconds; let mut subsample_tesimals = self.subsample_tesimals as u64 * rhs.subsample_tesimals as u64; if subsample_tesimals > SUBSAMPLE_TESIMALS_PER_SECOND as u64 { seconds += (subsample_tesimals / SUBSAMPLE_TESIMALS_PER_SECOND as u64) as u32; subsample_tesimals %= SUBSAMPLE_TESIMALS_PER_SECOND as u64; } - Superseconds::new(seconds, subsample_tesimals as u32) + Seconds::new(seconds, subsample_tesimals as u32) } } -impl ops::Mul for Superseconds { +impl ops::Mul for Seconds { type Output = Self; fn mul(self, rhs: f64) -> Self::Output { let seconds = self.to_seconds_f64() * rhs; - Superseconds::from_seconds_f64(seconds) + Seconds::from_seconds_f64(seconds) } } -impl ops::Mul for f64 { - type Output = Superseconds; +impl ops::Mul for f64 { + type Output = Seconds; - fn mul(self, rhs: Superseconds) -> Self::Output { + fn mul(self, rhs: Seconds) -> Self::Output { rhs * self } } -impl ops::Mul for Superseconds { +impl ops::Mul for Seconds { type Output = Self; fn mul(self, rhs: f32) -> Self::Output { let seconds = self.to_seconds_f64() as f32 * rhs; - Superseconds::from_seconds_f64(seconds as f64) + Seconds::from_seconds_f64(seconds as f64) } } -impl ops::Mul for f32 { - type Output = Superseconds; +impl ops::Mul for f32 { + type Output = Seconds; - fn mul(self, rhs: Superseconds) -> Self::Output { + fn mul(self, rhs: Seconds) -> Self::Output { rhs * self } } -impl ops::MulAssign for Superseconds { - fn mul_assign(&mut self, rhs: Superseconds) { +impl ops::MulAssign for Seconds { + fn mul_assign(&mut self, rhs: Seconds) { *self = *self * rhs; } } @@ -203,11 +203,11 @@ impl ops::MulAssign for Superseconds { /// Inspired by BillyDM's blog post https://billydm.github.io/blog/time-keeping/ #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] #[cfg_attr(feature = "serde-derive", derive(serde::Serialize, serde::Deserialize))] -pub struct Superbeats { +pub struct Beats { beats: u32, beat_tesimals: u32, } -impl Superbeats { +impl Beats { /// Zero beats pub const ZERO: Self = Self { beats: 0, @@ -279,17 +279,17 @@ impl Superbeats { } } } -impl std::iter::Sum for Superbeats { +impl std::iter::Sum for Beats { fn sum>(iter: I) -> Self { - iter.fold(Superbeats::ZERO, |acc, elem| acc + elem) + iter.fold(Beats::ZERO, |acc, elem| acc + elem) } } -impl PartialOrd for Superbeats { +impl PartialOrd for Beats { fn partial_cmp(&self, other: &Self) -> Option { Some(self.cmp(other)) } } -impl Ord for Superbeats { +impl Ord for Beats { fn cmp(&self, other: &Self) -> std::cmp::Ordering { if self.beats == other.beats { self.beat_tesimals.cmp(&other.beat_tesimals) @@ -298,10 +298,10 @@ impl Ord for Superbeats { } } } -impl ops::Add for Superbeats { +impl ops::Add for Beats { type Output = Self; - fn add(self, rhs: Superbeats) -> Self::Output { + fn add(self, rhs: Beats) -> Self::Output { let mut beats = self.beats + rhs.beats; let mut beat_tesimals = self.beat_tesimals + rhs.beat_tesimals; while beat_tesimals >= SUBBEAT_TESIMALS_PER_BEAT { @@ -309,19 +309,19 @@ impl ops::Add for Superbeats { beat_tesimals -= SUBBEAT_TESIMALS_PER_BEAT; } - Superbeats::new(beats, beat_tesimals) + Beats::new(beats, beat_tesimals) } } -impl ops::AddAssign for Superbeats { - fn add_assign(&mut self, rhs: Superbeats) { +impl ops::AddAssign for Beats { + fn add_assign(&mut self, rhs: Beats) { let result = *self + rhs; *self = result; } } -impl ops::Mul for Superbeats { +impl ops::Mul for Beats { type Output = Self; - fn mul(self, rhs: Superbeats) -> Self::Output { + fn mul(self, rhs: Beats) -> Self::Output { let mut beats = self.beats * rhs.beats + ((self.beats as u64 * rhs.beat_tesimals as u64) / SUBBEAT_TESIMALS_PER_BEAT as u64) as u32; @@ -332,62 +332,56 @@ impl ops::Mul for Superbeats { beats += (beat_tesimals / SUBBEAT_TESIMALS_PER_BEAT as u64) as u32; beat_tesimals %= SUBBEAT_TESIMALS_PER_BEAT as u64; } - Superbeats::new(beats, beat_tesimals as u32) + Beats::new(beats, beat_tesimals as u32) } } -impl ops::MulAssign for Superbeats { - fn mul_assign(&mut self, rhs: Superbeats) { +impl ops::MulAssign for Beats { + fn mul_assign(&mut self, rhs: Beats) { *self = *self * rhs; } } #[cfg(test)] mod tests { - use super::{Superseconds, SUBSAMPLE_TESIMALS_PER_SECOND}; + use super::{Seconds, SUBSAMPLE_TESIMALS_PER_SECOND}; use std::time::Duration; #[test] fn convert_to_u64_and_back() { - let original_ts = Superseconds::new(8347, SUBSAMPLE_TESIMALS_PER_SECOND - 5); + let original_ts = Seconds::new(8347, SUBSAMPLE_TESIMALS_PER_SECOND - 5); let as_u64 = original_ts.to_subsample_tesimals_u64(); - assert_eq!( - original_ts, - Superseconds::from_subsample_tesimals_u64(as_u64) - ); + assert_eq!(original_ts, Seconds::from_subsample_tesimals_u64(as_u64)); } #[test] fn duration_to_subsample_time() { for seconds in [73.73, 10.832, 10000.25, 84923.399] { - let superseconds = Superseconds::from_seconds_f64(seconds); + let superseconds = Seconds::from_seconds_f64(seconds); let duration = Duration::from_secs_f64(seconds); assert_eq!(superseconds, duration.into()) } } #[test] fn sample_conversion() { - assert_eq!(Superseconds::from_samples(1, 44100).to_samples(88200), 2); - assert_eq!(Superseconds::from_samples(1, 44100).to_samples(44100), 1); - assert_eq!(Superseconds::from_samples(2, 44100).to_samples(44100), 2); - assert_eq!(Superseconds::from_samples(3, 44100).to_samples(44100), 3); - assert_eq!(Superseconds::from_samples(4, 44100).to_samples(44100), 4); - assert_eq!( - Superseconds::from_samples(44100, 44100).to_samples(88200), - 88200 - ); + assert_eq!(Seconds::from_samples(1, 44100).to_samples(88200), 2); + assert_eq!(Seconds::from_samples(1, 44100).to_samples(44100), 1); + assert_eq!(Seconds::from_samples(2, 44100).to_samples(44100), 2); + assert_eq!(Seconds::from_samples(3, 44100).to_samples(44100), 3); + assert_eq!(Seconds::from_samples(4, 44100).to_samples(44100), 4); + assert_eq!(Seconds::from_samples(44100, 44100).to_samples(88200), 88200); assert_eq!( - Superseconds::from_samples(44100 * 3 + 1, 44100).to_samples(88200), + Seconds::from_samples(44100 * 3 + 1, 44100).to_samples(88200), 3 * 88200 + 2 ); assert_eq!( - Superseconds::from_samples(96000 * 3 + 8, 96000).to_samples(88200), + Seconds::from_samples(96000 * 3 + 8, 96000).to_samples(88200), 3 * 88200 + 7 ); } #[test] fn arithmetic() { assert_eq!( - Superseconds::new(0, SUBSAMPLE_TESIMALS_PER_SECOND - 1) + Superseconds::new(1, 1), - Superseconds::new(2, 0) + Seconds::new(0, SUBSAMPLE_TESIMALS_PER_SECOND - 1) + Seconds::new(1, 1), + Seconds::new(2, 0) ); } } diff --git a/knyst/src/trig.rs b/knyst/src/trig.rs index 25aae2d..a19bf1d 100644 --- a/knyst/src/trig.rs +++ b/knyst/src/trig.rs @@ -9,7 +9,7 @@ use crate as knyst; use knyst::{gen::GenState, Sample, SampleRate}; use knyst_macro::impl_gen; -use crate::time::Superseconds; +use crate::time::Seconds; /// Returns true is `sample` is a trigger, otherwise false. #[inline(always)] @@ -65,7 +65,7 @@ impl OnceTrig { /// 0. "trig": A trigger sent at the interval. pub struct IntervalTrig { // counter: Vec, - counter: Superseconds, + counter: Seconds, } #[impl_gen] @@ -74,7 +74,7 @@ impl IntervalTrig { #[allow(missing_docs)] pub fn new() -> Self { Self { - counter: Superseconds::ZERO, + counter: Seconds::ZERO, } } #[process] @@ -84,12 +84,12 @@ impl IntervalTrig { interval: &[Sample], trig: &mut [Sample], ) -> GenState { - let one_sample = Superseconds::from_samples(1, *sample_rate as u64); + let one_sample = Seconds::from_samples(1, *sample_rate as u64); for (interval, trig_out) in interval.iter().zip(trig.iter_mut()) { // Adding first makes the time until the first trigger the same as // the time between subsequent triggers so it is more consistent. self.counter += one_sample; - let interval_as_superseconds = Superseconds::from_seconds_f64(*interval as f64); + let interval_as_superseconds = Seconds::from_seconds_f64(*interval as f64); *trig_out = if self.counter >= interval_as_superseconds { self.counter = self .counter @@ -104,7 +104,7 @@ impl IntervalTrig { } #[init] fn init(&mut self) { - self.counter = Superseconds::ZERO; + self.counter = Seconds::ZERO; } } @@ -115,7 +115,7 @@ mod tests { use crate::resources::{Resources, ResourcesSettings}; use crate::prelude::*; - use crate::time::Superseconds; + use crate::time::Seconds; use crate::trig::IntervalTrig; use crate::*; #[test] @@ -131,7 +131,7 @@ mod tests { let mut graph = Graph::new(graph_settings); let node = graph.push(IntervalTrig::new()); graph.connect(node.to_graph_out()).unwrap(); - let every_8_samples = Superseconds::from_samples(8, SR).to_seconds_f64(); + let every_8_samples = Seconds::from_samples(8, SR).to_seconds_f64(); graph .connect(constant(every_8_samples as Sample).to(node)) .unwrap();