rosu_map/section/timing_points/control_points/
sample.rs1use std::{cmp::Ordering, num::NonZeroU32};
2
3use crate::section::hit_objects::hit_samples::{HitSampleInfo, HitSampleInfoName, SampleBank};
4
5#[derive(Clone, Debug, PartialEq)]
6pub struct SamplePoint {
8 pub time: f64,
9 pub sample_bank: SampleBank,
10 pub sample_volume: i32,
11 pub custom_sample_bank: i32,
12}
13
14impl SamplePoint {
15 pub const DEFAULT_SAMPLE_BANK: SampleBank = SampleBank::Normal;
16 pub const DEFAULT_SAMPLE_VOLUME: i32 = 100;
17 pub const DEFAULT_CUSTOM_SAMPLE_BANK: i32 = 0;
18
19 pub fn new(
20 time: f64,
21 sample_bank: SampleBank,
22 sample_volume: i32,
23 custom_sample_bank: i32,
24 ) -> Self {
25 Self {
26 time,
27 sample_bank,
28 sample_volume: sample_volume.clamp(0, 100),
29 custom_sample_bank,
30 }
31 }
32
33 pub fn is_redundant(&self, existing: &Self) -> bool {
34 self.sample_bank == existing.sample_bank
35 && self.sample_volume == existing.sample_volume
36 && self.custom_sample_bank == existing.custom_sample_bank
37 }
38
39 pub fn apply(&self, sample: &mut HitSampleInfo) {
40 if matches!(sample.name, HitSampleInfoName::Default(_)) {
41 if sample.custom_sample_bank == 0 {
42 sample.custom_sample_bank = self.custom_sample_bank;
43
44 if sample.custom_sample_bank >= 2 {
45 sample.suffix = Some(unsafe {
47 NonZeroU32::new_unchecked(sample.custom_sample_bank as u32)
48 });
49 }
50 }
51
52 if sample.volume == 0 {
53 sample.volume = self.sample_volume.clamp(0, 100);
54 }
55
56 if !sample.bank_specified {
57 sample.bank = self.sample_bank;
58 sample.bank_specified = true;
59 }
60 } else {
61 sample.bank = SamplePoint::DEFAULT_SAMPLE_BANK;
62 sample.suffix = None;
63
64 if sample.volume == 0 {
65 sample.volume = self.sample_volume.clamp(0, 100);
66 }
67
68 sample.custom_sample_bank = 1;
69 sample.bank_specified = false;
70 sample.is_layered = false;
71 }
72 }
73}
74
75impl Default for SamplePoint {
76 fn default() -> Self {
77 Self {
78 time: 0.0,
79 sample_bank: Self::DEFAULT_SAMPLE_BANK,
80 sample_volume: Self::DEFAULT_SAMPLE_VOLUME,
81 custom_sample_bank: Self::DEFAULT_CUSTOM_SAMPLE_BANK,
82 }
83 }
84}
85
86impl PartialOrd for SamplePoint {
87 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
88 self.time.partial_cmp(&other.time)
89 }
90}