aboutsummaryrefslogtreecommitdiff
path: root/src/utils.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/utils.rs')
-rw-r--r--src/utils.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/src/utils.rs b/src/utils.rs
new file mode 100644
index 0000000..ea20ac9
--- /dev/null
+++ b/src/utils.rs
@@ -0,0 +1,88 @@
+use core::intrinsics::transmute;
+use core::mem::size_of;
+use core::slice::{from_raw_parts_mut, from_raw_parts};
+
+pub struct Sampler {
+ freq2: u32,
+ q0: u32,
+ r0: u32,
+ ddl: (u32, u32),
+ cnt: u32,
+ sec_cnt: u32
+}
+
+impl Sampler {
+ pub fn new(freq1: u32, freq2: u32) -> Self {
+ let q0 = freq1 / freq2;
+ let r0 = freq1 - q0 * freq2;
+ Sampler {
+ freq2,
+ q0,
+ r0,
+ ddl: (q0, r0),
+ cnt: 0,
+ sec_cnt: 0
+ }
+ }
+
+ pub fn load(&mut self, reader: &mut Read) -> bool {
+ load_prefix(self, 0, reader)
+ }
+
+ pub fn save(&self, writer: &mut Write) -> bool {
+ save_prefix(self, 0, writer)
+ }
+
+ pub fn tick(&mut self) -> bool {
+ let (q, r) = self.ddl;
+ if self.cnt == q {
+ let nr = r + self.r0;
+ self.ddl = if nr > self.freq2 {
+ (self.q0, nr - self.freq2)
+ } else {
+ (self.q0 - 1, nr)
+ };
+ self.cnt = 0;
+ self.sec_cnt += 1;
+ if self.sec_cnt == self.freq2 {
+ self.sec_cnt = 0
+ }
+ true
+ } else {
+ self.cnt += 1;
+ false
+ }
+ }
+}
+
+pub trait Read {
+ fn read(&mut self, buf: &mut [u8]) -> Option<usize>;
+}
+
+pub trait Write {
+ fn write(&mut self, buf: &[u8]) -> Option<usize>;
+}
+
+pub fn load_prefix<T>(obj: &mut T, ignored: usize, reader: &mut Read) -> bool {
+ let len = size_of::<T>() - ignored;
+ match reader.read(unsafe {
+ from_raw_parts_mut(
+ transmute::<*mut T, *mut u8>(obj as *mut T),
+ len
+ )}) {
+ Some(x) => x == len,
+ None => false
+ }
+}
+
+pub fn save_prefix<T>(obj: &T, ignored: usize, writer: &mut Write) -> bool {
+ let len = size_of::<T>() - ignored;
+ match writer.write(unsafe {
+ from_raw_parts(
+ transmute::<*const T, *const u8>(obj as *const T),
+ len
+ )}) {
+ Some(x) => x == len,
+ None => false
+ }
+}