use lsl_core::prelude::*;
use std::time::Duration;
fn main() -> anyhow::Result<()> {
let eeg_info = StreamInfo::new("EEG", "EEG", 32, 256.0, ChannelFormat::Float32, "eeg_src");
let eeg_desc = eeg_info.desc();
let channels = eeg_desc.append_child("channels");
for ch in ["Fp1", "Fp2", "F3", "F4", "C3", "C4", "P3", "P4"] {
let c = channels.append_child("channel");
c.append_child_value("label", ch);
c.append_child_value("unit", "microvolts");
c.append_child_value("type", "EEG");
}
let eeg_outlet = StreamOutlet::new(&eeg_info, 0, 360);
eprintln!(
"✓ EEG outlet: 32ch × 256Hz, port {}",
eeg_info.v4data_port()
);
let emg_info = StreamInfo::new("EMG", "EMG", 4, 2000.0, ChannelFormat::Float32, "emg_src");
let emg_outlet = StreamOutlet::new(&emg_info, 0, 360);
eprintln!(
"✓ EMG outlet: 4ch × 2000Hz, port {}",
emg_info.v4data_port()
);
let marker_info = StreamInfo::new(
"Markers",
"Markers",
1,
IRREGULAR_RATE,
ChannelFormat::String,
"marker_src",
);
let marker_outlet = StreamOutlet::new(&marker_info, 0, 0);
eprintln!(
"✓ Marker outlet: 1ch, irregular, port {}",
marker_info.v4data_port()
);
eprintln!();
eprintln!("Streaming... Ctrl-C to stop.");
let mut eeg_data = vec![0.0f32; 32];
let mut emg_data = vec![0.0f32; 4];
let eeg_interval = Duration::from_secs_f64(1.0 / 256.0);
let mut sample_idx: u64 = 0;
loop {
let t = sample_idx as f64 / 256.0;
for ch in 0..32 {
let freq = 8.0 + ch as f64 * 0.5; eeg_data[ch] = (100.0 * (2.0 * std::f64::consts::PI * freq * t).sin()) as f32;
}
eeg_outlet.push_sample_f(&eeg_data, 0.0, true);
if sample_idx % 1 == 0 {
for ch in 0..4 {
emg_data[ch] =
(50.0 * (2.0 * std::f64::consts::PI * 150.0 * t + ch as f64).sin()) as f32;
}
emg_outlet.push_sample_f(&emg_data, 0.0, true);
}
if sample_idx % 512 == 0 && sample_idx > 0 {
let event = format!("event_{}", sample_idx / 512);
marker_outlet.push_sample_str(&[event.clone()], 0.0, true);
eprintln!(" → marker: {}", event);
}
sample_idx += 1;
std::thread::sleep(eeg_interval);
}
}