rosu_pp/model/control_point/
timing.rs1#[derive(Copy, Clone, Debug, PartialEq)]
3pub struct TimingPoint {
4 pub time: f64,
5 pub beat_len: f64,
6}
7
8impl TimingPoint {
9 pub const DEFAULT_BEAT_LEN: f64 =
10 rosu_map::section::timing_points::TimingPoint::DEFAULT_BEAT_LEN;
11
12 pub const DEFAULT_BPM: f64 = 60_000.0 / Self::DEFAULT_BEAT_LEN;
13
14 pub const fn new(time: f64, beat_len: f64) -> Self {
15 Self {
16 time,
17 beat_len: beat_len.clamp(6.0, 60_000.0),
18 }
19 }
20
21 pub const fn bpm(&self) -> f64 {
22 60_000.0 / self.beat_len
23 }
24}
25
26impl Default for TimingPoint {
27 fn default() -> Self {
28 Self {
29 time: 0.0,
30 beat_len: Self::DEFAULT_BEAT_LEN,
31 }
32 }
33}
34
35pub fn timing_point_at(points: &[TimingPoint], time: f64) -> Option<&TimingPoint> {
36 let i = points
37 .binary_search_by(|probe| probe.time.total_cmp(&time))
38 .unwrap_or_else(|i| i.saturating_sub(1));
39
40 points.get(i)
41}