use anyhow::{Result, bail};
use argh::FromArgs;
use crossbeam::channel::{Receiver, TryRecvError, unbounded};
use lasprs::Flt;
use lasprs::daq::{RecordSettings, RecordStatus, Recording, StreamMgr, StreamType};
use std::{
io, thread,
time::{self, Duration},
};
#[derive(FromArgs, Debug)]
struct Cli {
#[argh(option, short = 'c')]
config_file_daq: Option<String>,
#[argh(positional)]
filename: String,
#[argh(option, default = "0.0")]
duration_s: Flt,
#[argh(option, default = "0.0")]
start_delay_s: Flt,
}
fn main() -> Result<()> {
use lasprs::daq::DaqConfig;
let ops: Cli = argh::from_env();
let mut smgr = StreamMgr::new();
let stdin_channel = spawn_stdin_channel();
if ops.start_delay_s < 0. {
bail!("Start delay cannot be negative");
}
if ops.duration_s < 0. {
bail!("Duration cannot be negative");
}
let start_delay = if ops.start_delay_s > 0. {
Some(Duration::from_secs(ops.start_delay_s as u64))
} else {
None
};
let duration = if ops.duration_s > 0. {
Some(Duration::from_secs(ops.duration_s as u64))
} else {
None
};
let settings = RecordSettings::new(
&ops.filename,
false,
duration,
start_delay,
None,
None,
false,
None,
vec![],
)?;
match ops.config_file_daq {
None => smgr.startDefaultInputStream()?,
Some(filename) => {
let file = std::fs::read_to_string(filename)?;
let cfg = DaqConfig::deserialize_TOML_str(&file)?;
smgr.startStream(StreamType::Input, &cfg)?;
}
}
let mut r = Recording::new(settings, &mut smgr)?;
'infy: loop {
use lasprs::daq::FinishedRecording;
match r.status() {
RecordStatus::Idle {} => println!("\nIdle"),
RecordStatus::Waiting {} => {
println!("Waiting in start delay...");
}
RecordStatus::Finished {
finishedrecording: FinishedRecording { clipped, error, .. },
} => {
println!("\nRecording finished.");
if clipped {
println!("Recording clipped!");
}
if let Some(msg) = error {
println!("Recording failed with an error: {msg}");
}
break 'infy;
}
RecordStatus::Recording { recorded, .. } => {
println!("Recording... {:.0} ms", recorded * 1000.);
}
};
match stdin_channel.try_recv() {
Ok(_key) => {
println!("User pressed key. Manually stopping recording here.");
match _key.to_lowercase().as_str() {
"c" => r.cancel(),
_ => r.stop(),
}
break 'infy;
}
Err(TryRecvError::Empty) => {}
Err(TryRecvError::Disconnected) => panic!("Channel disconnected"),
}
sleep(500);
}
Ok(())
}
fn sleep(millis: u64) {
let duration = time::Duration::from_millis(millis);
thread::sleep(duration);
}
fn spawn_stdin_channel() -> Receiver<String> {
let (tx, rx) = unbounded();
thread::spawn(move || {
loop {
let mut buffer = String::new();
io::stdin().read_line(&mut buffer).unwrap();
tx.send(buffer).unwrap();
}
});
rx
}