use anyhow::Result;
use lasprs::{Flt, FreqWeighting, Overlap, WindowType, daq::*, measurement::*, ps::*};
use std::{path::PathBuf, thread, time::Duration};
fn main() -> Result<()> {
println!("LaspRS Recording and Analysis Example");
println!("====================================");
let mut stream_mgr = StreamMgr::new_with_devices();
let devices = stream_mgr.getDeviceInfo();
if devices.is_empty() {
anyhow::bail!("No audio devices available for recording");
}
println!("Available devices:");
for (i, device) in devices.iter().enumerate() {
println!(" {}: {}", i, device.device_name);
}
let device = &devices[0];
let mut config = DaqConfig::newFromDeviceInfo(device);
let mut in_channels = config.inchannel_config.clone();
if !in_channels.is_empty() {
in_channels[0].enabled = true;
in_channels[0].name = "Channel 1".to_string();
in_channels[0].sensitivity = 1.0; config.inchannel_config = in_channels;
} else {
anyhow::bail!("No input channels available on the selected device");
}
println!("Using device: {}", device.device_name);
println!("Sample rate: {} Hz", config.sampleRate(device));
let filename = "example_recording.h5";
let recording_duration = Duration::from_secs(3);
let cps_settings = CPSSettings {
nfft: 2048, overlap: Overlap::NoOverlap {},
window: WindowType::Hann,
istart: None,
istop: None,
};
let record_settings = RecordSettings::new(
filename,
false,
Some(recording_duration),
None, Some(cps_settings),
None,
false,
None,
vec![],
)?;
println!("Recording settings:");
println!(" Filename: {}", filename);
println!(" Duration: {:?}", recording_duration);
println!(" FFT size: {}", cps_settings.nfft);
println!("\nStarting input stream...");
stream_mgr.startStream(StreamType::Input, &config)?;
println!("Starting recording...");
let mut recording = Recording::new(record_settings, &mut stream_mgr)?;
loop {
match recording.status() {
RecordStatus::Idle {} => {
println!("Status: Idle");
}
RecordStatus::Waiting {} => {
println!("Status: Waiting for start delay...");
}
RecordStatus::Recording {
recorded,
pct_done,
clipped,
} => {
println!(
"Status: Recording... {:.1}% complete ({:.2}s recorded)",
pct_done * 100.0,
recorded
);
if clipped {
println!(" WARNING: Signal clipping detected!");
}
}
RecordStatus::Finished { finishedrecording } => {
println!("Recording finished!");
if finishedrecording.clipped {
println!(" WARNING: Recording contained clipped samples!");
}
if let Some(error) = &finishedrecording.error {
println!(" ERROR: {}", error);
anyhow::bail!("Recording failed: {}", error);
}
break;
}
}
thread::sleep(Duration::from_millis(100));
}
println!("Stopping input stream...");
stream_mgr.stopStream(StreamType::Input)?;
println!("\nAnalyzing recorded data...");
let filepath = PathBuf::from(filename);
if !filepath.exists() {
anyhow::bail!("Recording file '{}' does not exist", filename);
}
let measurement_arc = Measurement::from_file(&filepath)?;
let (nchannels, samplerate, duration);
let channel_names;
let cps_result;
{
let mut measurement = measurement_arc.write();
println!("Measurement file opened successfully:");
nchannels = measurement.nchannels();
samplerate = measurement.samplerate();
duration = measurement.get_duration();
println!(" Number of channels: {}", nchannels);
println!(" Sample rate: {} Hz", samplerate);
println!(" Duration: {:.2} seconds", duration);
channel_names = measurement.channel_names();
println!(" Channel names: {:?}", channel_names);
println!("\nCalculating auto power spectrum for first channel...");
cps_result = measurement.CPS(
&cps_settings,
FreqWeighting::Z, Some(&[0]), )?;
}
let auto_power = cps_result.ap(0);
println!("Auto power spectrum calculated!");
println!(" Number of frequency bins: {}", auto_power.len());
let total_power: Flt = auto_power.iter().sum();
let max_power = auto_power.iter().fold(0.0, |acc, x| Flt::max(acc, *x));
let avg_power = total_power / auto_power.len() as f64;
println!("Power spectrum statistics:");
println!(" Total power: {:.6e}", total_power);
println!(" Average power per bin: {:.6e}", avg_power);
println!(" Maximum power in any bin: {:.6e}", max_power);
println!("\nCleaning up...");
if filepath.exists() {
std::fs::remove_file(&filepath)?;
println!("Removed temporary recording file: {}", filename);
}
println!("\nExample completed successfully!");
Ok(())
}