rusty_daw_core/atomic/
atomic_time.rs1use std::sync::atomic::{AtomicU64, Ordering};
2
3use crate::MusicalTime;
4
5pub struct AtomicMusicalTime {
7 atomic: AtomicU64,
8}
9
10#[inline]
11fn u32x2_to_u64(v1: u32, v2: u32) -> u64 {
12 let v1_bytes: [u8; 4] = v1.to_ne_bytes();
13 let v2_bytes: [u8; 4] = v2.to_ne_bytes();
14 let bytes: [u8; 8] = [
15 v1_bytes[0],
16 v1_bytes[1],
17 v1_bytes[2],
18 v1_bytes[3],
19 v2_bytes[0],
20 v2_bytes[1],
21 v2_bytes[2],
22 v2_bytes[3],
23 ];
24
25 u64::from_ne_bytes(bytes)
26}
27
28#[inline]
29fn u64_to_u32x2(v: u64) -> (u32, u32) {
30 let bytes: [u8; 8] = v.to_ne_bytes();
31 let v1_bytes: [u8; 4] = [bytes[0], bytes[1], bytes[2], bytes[3]];
32 let v2_bytes: [u8; 4] = [bytes[4], bytes[5], bytes[6], bytes[7]];
33
34 (u32::from_ne_bytes(v1_bytes), u32::from_ne_bytes(v2_bytes))
35}
36
37impl AtomicMusicalTime {
38 pub fn new(musical_time: MusicalTime) -> AtomicMusicalTime {
40 AtomicMusicalTime {
41 atomic: AtomicU64::new(u32x2_to_u64(
42 musical_time.beats(),
43 musical_time.super_beats(),
44 )),
45 }
46 }
47
48 pub fn get(&self) -> MusicalTime {
50 let (beats, super_beats) = u64_to_u32x2(self.atomic.load(Ordering::Relaxed));
51 MusicalTime::new(beats, super_beats)
52 }
53
54 pub fn set(&self, musical_time: MusicalTime) {
56 self.atomic.store(
57 u32x2_to_u64(musical_time.beats(), musical_time.super_beats()),
58 Ordering::Relaxed,
59 )
60 }
61}
62
63impl Default for AtomicMusicalTime {
64 fn default() -> Self {
65 AtomicMusicalTime::new(MusicalTime::default())
66 }
67}
68
69impl std::fmt::Debug for AtomicMusicalTime {
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 std::fmt::Debug::fmt(&self.get(), f)
72 }
73}
74
75impl From<MusicalTime> for AtomicMusicalTime {
76 fn from(value: MusicalTime) -> Self {
77 AtomicMusicalTime::new(value)
78 }
79}
80
81impl From<AtomicMusicalTime> for MusicalTime {
82 fn from(value: AtomicMusicalTime) -> Self {
83 value.get()
84 }
85}
86
87#[cfg(test)]
88mod tests {
89 use super::*;
90
91 #[test]
92 fn test_atomic_musical_time() {
93 let musical_time_1 = MusicalTime::new(4578749, 12390);
94 let musical_time_2 = MusicalTime::new(5720495, 45781);
95
96 let atomic_musical_time = AtomicMusicalTime::new(musical_time_1);
97
98 assert_eq!(atomic_musical_time.get(), musical_time_1);
99
100 atomic_musical_time.set(musical_time_2);
101
102 std::thread::sleep(std::time::Duration::from_millis(1));
103
104 assert_eq!(atomic_musical_time.get(), musical_time_2);
105 }
106}