From 0473e18ade0e394fa1c98c8d90f69f41ce8f923f Mon Sep 17 00:00:00 2001 From: Bart Brouns Date: Wed, 20 Nov 2024 01:38:39 +0100 Subject: [PATCH] add bars and beats label if tempo and denominator are known --- src/editor.rs | 52 ++++++++++++++++++++++++++++++++++++++------------- src/lib.rs | 20 ++++++++++++++++++-- src/style.css | 8 ++++---- 3 files changed, 61 insertions(+), 19 deletions(-) diff --git a/src/editor.rs b/src/editor.rs index f035f42..64b4e21 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -430,29 +430,55 @@ impl DelayGraph { cx, params.map(move |params| { const TOTAL_DIGITS: usize = 3; + let tempo = params.tempo.load(Ordering::SeqCst); + let time_sig_numerator = params.time_sig_numerator.load(Ordering::SeqCst); let tap_counter = params.tap_counter.load(Ordering::SeqCst); // Determine the max delay time - let max_delay_time = if tap_counter > 0 { + let seconds = if tap_counter > 0 { params.delay_times[tap_counter - 1].load(Ordering::SeqCst) as f32 / params.sample_rate.load(Ordering::SeqCst) } else { 0.0 }; - if max_delay_time < 0.001 { - String::new() - } else if max_delay_time < 1.0 { - // Calculate the number of digits after the decimal to maintain a total of three digits - let ms = max_delay_time * 1000.0; - let digits_after_decimal = (TOTAL_DIGITS - ms.trunc().to_string().len()) + if tempo >= 0.0 && time_sig_numerator > 0 { + // Only proceed if tempo and time signature are valid (non-negative) + let seconds_per_beat = 60.0 / tempo as f32; + let seconds_per_measure = seconds_per_beat * time_sig_numerator as f32; + + let full_bars = (seconds / seconds_per_measure).floor() as i32; + let remaining_seconds = seconds % seconds_per_measure; + let additional_beats = + (remaining_seconds / seconds_per_beat).round() as i32; + + if full_bars > 1 { + format!("{} bars", full_bars) + } else if full_bars > 0 { + format!("{} bar", full_bars) + } else if additional_beats > 1 { + format!("{} beats", additional_beats) + } else if additional_beats > 0 { + format!("{} beat", additional_beats) + } else { + return String::new(); + } + } else { + if seconds < 0.001 { + String::new() + } else if seconds < 1.0 { + // Calculate the number of digits after the decimal to maintain a total of three digits + let ms = seconds * 1000.0; + let digits_after_decimal = (TOTAL_DIGITS + - ms.trunc().to_string().len()) .max(0) .min(TOTAL_DIGITS - 1); // Ensure it's between 0 and 2 - format!("{ms:.digits_after_decimal$} ms") - } else { - // Same logic for seconds - let digits_after_decimal = - (TOTAL_DIGITS - max_delay_time.trunc().to_string().len()).max(0); - format!("{max_delay_time:.digits_after_decimal$} s") + format!("{ms:.digits_after_decimal$} ms") + } else { + // Same logic for seconds + let digits_after_decimal = + (TOTAL_DIGITS - seconds.trunc().to_string().len()).max(0); + format!("{seconds:.digits_after_decimal$} s") + } } }), ) diff --git a/src/lib.rs b/src/lib.rs index 156eb98..217644e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -50,7 +50,9 @@ use nih_plug::prelude::*; use nih_plug_vizia::ViziaState; use std::ops::Index; use std::simd::f32x4; -use std::sync::atomic::{AtomicBool, AtomicU32, AtomicU64, AtomicU8, AtomicUsize, Ordering}; +use std::sync::atomic::{ + AtomicBool, AtomicI32, AtomicU32, AtomicU64, AtomicU8, AtomicUsize, Ordering, +}; use std::sync::Arc; use synfx_dsp::fh_va::{FilterParams, LadderMode}; @@ -154,6 +156,8 @@ pub struct Del2Params { previous_pan_background_lengths: AtomicF32Array, last_frame_time: AtomicU64, sample_rate: AtomicF32, + tempo: AtomicF32, + time_sig_numerator: AtomicI32, } /// Contains the global parameters. @@ -525,6 +529,8 @@ impl Del2Params { })), last_frame_time: AtomicU64::new(0), sample_rate: 1.0.into(), + tempo: (-1.0).into(), + time_sig_numerator: (-1).into(), } } } @@ -598,7 +604,6 @@ impl Plugin for Del2 { self.params .sample_rate .store(buffer_config.sample_rate, Ordering::SeqCst); - // After `PEAK_METER_DECAY_MS` milliseconds of pure silence, the peak meter's value should // have dropped by 12 dB self.peak_meter_decay_weight = 0.25f64.powf( @@ -645,6 +650,17 @@ impl Plugin for Del2 { let num_samples = buffer.samples(); let sample_rate = context.transport().sample_rate; + self.params + .sample_rate + .store(context.transport().sample_rate, Ordering::SeqCst); + self.params.tempo.store( + context.transport().tempo.unwrap_or(-1.0) as f32, + Ordering::SeqCst, + ); + self.params.time_sig_numerator.store( + context.transport().time_sig_numerator.unwrap_or(-1), + Ordering::SeqCst, + ); let mut next_event = context.next_event(); let mut block_start: usize = 0; let mut block_end: usize = MAX_BLOCK_SIZE.min(num_samples); diff --git a/src/style.css b/src/style.css index 044d3a3..6329f04 100644 --- a/src/style.css +++ b/src/style.css @@ -99,14 +99,14 @@ delay-graph { .tap-nr-label { left: 1s; - right: 13px; + right: 11px; top: 1s; - bottom: 9px; + bottom: 7px; } .tap-length-label { left: 1s; - right: 13px; - top: 1px; + right: 11px; + top: 0px; bottom: 9px; }