diff options
-rw-r--r-- | build.rs | 2 | ||||
-rw-r--r-- | src/fl2k.rs | 33 | ||||
-rw-r--r-- | src/main.rs | 26 |
3 files changed, 47 insertions, 14 deletions
@@ -18,7 +18,7 @@ fn main() { println!("cargo:rustc-link-lib=usb-1.0"); // Tell cargo to invalidate the built crate whenever the wrapper changes - println!("cargo:rerun-if-changed=c_sources/osmo-fl2k.h"); + println!("cargo:rerun-if-changed=c_sources/*"); let bindings = bindgen::Builder::default() .header("c_sources/osmo-fl2k.h") diff --git a/src/fl2k.rs b/src/fl2k.rs index a17a04d..695d32a 100644 --- a/src/fl2k.rs +++ b/src/fl2k.rs @@ -1,5 +1,7 @@ -use std::{ffi::{c_int, c_void}, sync::mpsc}; -use fl2k_ampliphase::{fl2k_dev_t, fl2k_get_device_count, fl2k_open, fl2k_close, fl2k_stop_tx, fl2k_set_sample_rate, fl2k_get_sample_rate, fl2k_start_tx}; +use std::{ffi::{c_int, c_void}, sync::mpsc, mem::swap}; +use fl2k_ampliphase::{fl2k_dev_t, fl2k_get_device_count, fl2k_open, fl2k_close, fl2k_stop_tx, fl2k_set_sample_rate, fl2k_get_sample_rate, fl2k_start_tx, FL2K_BUF_LEN}; + +const BUF_LEN : usize = FL2K_BUF_LEN as usize; #[derive(Debug)] pub enum FL2KError { @@ -32,6 +34,9 @@ pub struct FL2K { device: *mut fl2k_dev_t, callback_ctx: Box<CallbackCtx>, tx : mpsc::SyncSender<(Vec<i8>, Vec<i8>)>, + + r_buf : Vec<i8>, + g_buf : Vec<i8> } pub struct CallbackCtx { @@ -88,7 +93,11 @@ impl FL2K { abort: false, }; unsafe { - let mut fl2k = FL2K { device: std::mem::zeroed(), callback_ctx: Box::new(ctx), tx }; + + let r_buf = Vec::with_capacity(2 * BUF_LEN); + let g_buf = Vec::with_capacity(2 * BUF_LEN); + + let mut fl2k = FL2K { device: std::mem::zeroed(), callback_ctx: Box::new(ctx), tx, r_buf, g_buf }; handle_return_value(fl2k_open(&mut fl2k.device, device_index))?; Ok(fl2k) } @@ -118,11 +127,25 @@ impl FL2K { handle_return_value( unsafe { fl2k_stop_tx(self.device) } ) } - pub fn send(&self, r_buf: Vec<i8>, g_buf: Vec<i8>) -> bool { + pub fn send(&mut self, mut r_buf: Vec<i8>, mut g_buf: Vec<i8>) -> bool { if r_buf.len() != g_buf.len() { panic!("r_buf and g_buf must have same length"); } - self.tx.send((r_buf, g_buf)).is_ok() + + self.r_buf.append(&mut r_buf); + self.g_buf.append(&mut g_buf); + + if self.r_buf.len() >= BUF_LEN { + let mut r = self.r_buf.split_off(BUF_LEN); + let mut g = self.g_buf.split_off(BUF_LEN); + /* self.r_buf contains head, r contains tail. Swap them, as we want to give the head and keep the tail. */ + swap(&mut r, &mut self.r_buf); + swap(&mut g, &mut self.g_buf); + self.tx.send((r, g)).is_ok() + } + else { + true + } } } diff --git a/src/main.rs b/src/main.rs index 38a34d4..0814506 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ /* - * Copyright (C) 2022 by Matthias P. Braendli <matthias.braendli@mpb.li> + * Copyright (C) 2023 by Matthias P. Braendli <matthias.braendli@mpb.li> * * Based on previous work by * Copyright (C) 2022 by Felix Erckenbrecht <eligs@eligs.de> @@ -245,14 +245,20 @@ fn main() { ) }; - if let Err(e) = source_file.read_exact(&mut buf_u8) { - if e.kind() != std::io::ErrorKind::UnexpectedEof { - eprintln!("Input file read stopped {:?}", e); - } - else { - eprintln!("Input file EOF reached"); + match source_file.read(&mut buf_u8) { + Ok(len) => { + if len == 0 { + if let Err(e_seek) = source_file.rewind() { + eprintln!("Failed to rewind source file: {}", e_seek); + break; + } + } + buf.resize(len, 0); + }, + Err(e) => { + eprintln!("Failed to read source file: {}", e); + break; } - break; } let buf: Vec<f32> = buf @@ -271,6 +277,8 @@ fn main() { break; } } + + eprintln!("Leaving input thread"); }); // Read samples, calculate PD and PDSLOPE @@ -326,6 +334,7 @@ fn main() { break; } } + eprintln!("Leaving pd thread"); }); // Read PD and PDSLOPE, interpolate to higher rate @@ -374,6 +383,7 @@ fn main() { } } } + eprintln!("Leaving dds thread"); }); // Main thread, output to file/device |