mirror of
https://github.com/storytold/soundcraft.git
synced 2026-10-24 02:26:46 -06:00
Fix Min:Secs showing 1 ms early at exact millisecond positions
Found while testing crates/time/src/format.rs:46 Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com> Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Haiku 5.5
parent
3a28a65769
commit
c3d37f367d
@@ -43,7 +43,8 @@ impl TimeFormat {
|
||||
|
||||
fn min_secs(s: Samples, sr: SampleRate) -> String {
|
||||
let neg = s < 0;
|
||||
let ms_total = (sr.seconds(s.saturating_abs()) * 1000.0).floor() as i64;
|
||||
// Integer maths: a float `seconds * 1000` lands just below exact millisecond positions.
|
||||
let ms_total = i64::try_from(i128::from(s).abs() * 1000 / i128::from(sr.hz().max(1))).unwrap_or(i64::MAX);
|
||||
let mins = ms_total / 60_000;
|
||||
let secs = (ms_total / 1000) % 60;
|
||||
let ms = ms_total % 1000;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//! Min:Secs shows exact millisecond positions exactly (no float-floor off-by-one).
|
||||
|
||||
use soundcraft_time::{FrameRate, SampleRate, TempoMap, TimeFormat, format_position};
|
||||
|
||||
fn min_secs(s: i64, sr: SampleRate) -> String {
|
||||
format_position(s, TimeFormat::MinSecs, sr, &TempoMap::default(), FrameRate::default(), 0, 0)
|
||||
}
|
||||
|
||||
fn expected(ms_total: i64) -> String {
|
||||
format!("{}:{:02}.{:03}", ms_total / 60_000, (ms_total / 1000) % 60, ms_total % 1000)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn known_positions_at_44100() {
|
||||
assert_eq!(min_secs(88_641, SampleRate::HZ_44100), "0:02.010");
|
||||
assert_eq!(min_secs(89_523, SampleRate::HZ_44100), "0:02.030");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn negative_position_at_44100() {
|
||||
assert_eq!(min_secs(-88_641, SampleRate::HZ_44100), "-0:02.010");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn every_exact_millisecond_displays_exactly() {
|
||||
for sr in [SampleRate::HZ_44100, SampleRate::HZ_48000] {
|
||||
let hz = i64::from(sr.hz());
|
||||
for ms in 0..=600_000_i64 {
|
||||
if (ms * hz) % 1000 != 0 {
|
||||
continue;
|
||||
}
|
||||
let s = ms * hz / 1000;
|
||||
assert_eq!(min_secs(s, sr), expected(ms), "{hz} Hz, sample {s}");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user