]> code.octet-stream.net Git - m17rt/blobdiff - m17app/src/soundmodem.rs
Fix timing bugs and add documentation
[m17rt] / m17app / src / soundmodem.rs
index 2d005b1b31b408f2134bd49ff5096659a4ffe876..391bfadde1b66b2ee33c1b7a336991aabe126e19 100644 (file)
@@ -138,8 +138,12 @@ fn spawn_soundmodem_worker(
         let mut ptt = false;
         while let Ok(ev) = event_rx.recv() {
             // Update clock on TNC before we do anything
         let mut ptt = false;
         while let Ok(ev) = event_rx.recv() {
             // Update clock on TNC before we do anything
-            let sample_time = (start.elapsed().as_nanos() / 48000) as u64;
-            tnc.set_now(sample_time);
+            let sample_time = start.elapsed();
+            let secs = sample_time.as_secs();
+            let nanos = sample_time.subsec_nanos();
+            // Accurate to within approx 1 sample
+            let now_samples = 48000 * secs + (nanos as u64 / 20833);
+            tnc.set_now(now_samples);
 
             // Handle event
             match ev {
 
             // Handle event
             match ev {
@@ -277,7 +281,7 @@ impl InputSource for InputRrcFile {
                     if let Err(e) = samples.try_send(SoundmodemEvent::BasebandInput(buf.into())) {
                         debug!("overflow feeding soundmodem: {e:?}");
                     }
                     if let Err(e) = samples.try_send(SoundmodemEvent::BasebandInput(buf.into())) {
                         debug!("overflow feeding soundmodem: {e:?}");
                     }
-                    next_tick = next_tick + TICK;
+                    next_tick += TICK;
                     idx = 0;
                     std::thread::sleep(next_tick.duration_since(Instant::now()));
                 }
                     idx = 0;
                     std::thread::sleep(next_tick.duration_since(Instant::now()));
                 }
@@ -317,7 +321,7 @@ impl InputSource for NullInputSource {
 
             loop {
                 std::thread::sleep(next_tick.duration_since(Instant::now()));
 
             loop {
                 std::thread::sleep(next_tick.duration_since(Instant::now()));
-                next_tick = next_tick + TICK;
+                next_tick += TICK;
                 if end_rx.try_recv() != Err(TryRecvError::Empty) {
                     break;
                 }
                 if end_rx.try_recv() != Err(TryRecvError::Empty) {
                     break;
                 }
@@ -336,6 +340,12 @@ impl InputSource for NullInputSource {
     }
 }
 
     }
 }
 
+impl Default for NullInputSource {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 pub struct OutputBuffer {
     pub idling: bool,
     // TODO: something more efficient
 pub struct OutputBuffer {
     pub idling: bool,
     // TODO: something more efficient
@@ -353,6 +363,12 @@ impl OutputBuffer {
     }
 }
 
     }
 }
 
+impl Default for OutputBuffer {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 pub trait OutputSink: Send + Sync + 'static {
     fn start(&self, event_tx: SyncSender<SoundmodemEvent>, buffer: Arc<RwLock<OutputBuffer>>);
     fn close(&self);
 pub trait OutputSink: Send + Sync + 'static {
     fn start(&self, event_tx: SyncSender<SoundmodemEvent>, buffer: Arc<RwLock<OutputBuffer>>);
     fn close(&self);
@@ -390,7 +406,7 @@ impl OutputSink for OutputRrcFile {
 
             loop {
                 std::thread::sleep(next_tick.duration_since(Instant::now()));
 
             loop {
                 std::thread::sleep(next_tick.duration_since(Instant::now()));
-                next_tick = next_tick + TICK;
+                next_tick += TICK;
                 if end_rx.try_recv() != Err(TryRecvError::Empty) {
                     break;
                 }
                 if end_rx.try_recv() != Err(TryRecvError::Empty) {
                     break;
                 }
@@ -440,6 +456,12 @@ impl NullOutputSink {
     }
 }
 
     }
 }
 
+impl Default for NullOutputSink {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl OutputSink for NullOutputSink {
     fn start(&self, event_tx: SyncSender<SoundmodemEvent>, buffer: Arc<RwLock<OutputBuffer>>) {
         let (end_tx, end_rx) = channel();
 impl OutputSink for NullOutputSink {
     fn start(&self, event_tx: SyncSender<SoundmodemEvent>, buffer: Arc<RwLock<OutputBuffer>>) {
         let (end_tx, end_rx) = channel();
@@ -451,7 +473,7 @@ impl OutputSink for NullOutputSink {
 
             loop {
                 std::thread::sleep(next_tick.duration_since(Instant::now()));
 
             loop {
                 std::thread::sleep(next_tick.duration_since(Instant::now()));
-                next_tick = next_tick + TICK;
+                next_tick += TICK;
                 if end_rx.try_recv() != Err(TryRecvError::Empty) {
                     break;
                 }
                 if end_rx.try_recv() != Err(TryRecvError::Empty) {
                     break;
                 }
@@ -459,7 +481,7 @@ impl OutputSink for NullOutputSink {
                 let mut buffer = buffer.write().unwrap();
                 let mut taken = 0;
                 for _ in 0..SAMPLES_PER_TICK {
                 let mut buffer = buffer.write().unwrap();
                 let mut taken = 0;
                 for _ in 0..SAMPLES_PER_TICK {
-                    if !buffer.samples.pop_front().is_some() {
+                    if buffer.samples.pop_front().is_none() {
                         if !buffer.idling {
                             debug!("null output had underrun");
                             let _ = event_tx.send(SoundmodemEvent::OutputUnderrun);
                         if !buffer.idling {
                             debug!("null output had underrun");
                             let _ = event_tx.send(SoundmodemEvent::OutputUnderrun);
@@ -497,6 +519,12 @@ impl NullPtt {
     }
 }
 
     }
 }
 
+impl Default for NullPtt {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
 impl Ptt for NullPtt {
     fn ptt_on(&mut self) {}
     fn ptt_off(&mut self) {}
 impl Ptt for NullPtt {
     fn ptt_on(&mut self) {}
     fn ptt_off(&mut self) {}