- let host = cpal::default_host();
- let device = if let Some(name) = cpal_name.as_deref() {
- host.input_devices()
- .unwrap()
- .find(|d| d.name().unwrap() == name)
- .unwrap()
- } else {
- host.default_input_device().unwrap()
- };
- let mut configs = device.supported_input_configs().unwrap();
- let config = configs
- .find(|c| c.channels() == 1 && c.sample_format() == SampleFormat::I16)
- .unwrap()
- .with_sample_rate(SampleRate(48000));
- let stream = device
- .build_input_stream(
- &config.into(),
- move |data: &[i16], _info: &cpal::InputCallbackInfo| {
- debug!("input has given us {} samples", data.len());
- let out: Vec<i16> = data.iter().map(|s| *s).collect();
- let _ = samples.try_send(SoundmodemEvent::BasebandInput(out.into()));
- },
- |e| {
- // TODO: abort?
- debug!("error occurred in soundcard input: {e:?}");
- },
- None,
- )
- .unwrap();
- stream.play().unwrap();
- let _ = end_rx.recv();
+ // assuming 48 kHz for now
+ const TICK: Duration = Duration::from_millis(25);
+ const SAMPLES_PER_TICK: usize = 1200;
+
+ let mut next_tick = Instant::now() + TICK;
+ let mut buf = [0i16; SAMPLES_PER_TICK];
+ let mut idx = 0;
+
+ for sample in baseband
+ .chunks(2)
+ .map(|pair| i16::from_le_bytes([pair[0], pair[1]]))
+ {
+ buf[idx] = sample;
+ idx += 1;
+ if idx == SAMPLES_PER_TICK {
+ if let Err(e) = samples.try_send(SoundmodemEvent::BasebandInput(buf.into())) {
+ debug!("overflow feeding soundmodem: {e:?}");
+ }
+ next_tick += TICK;
+ idx = 0;
+ std::thread::sleep(next_tick.duration_since(Instant::now()));
+ }
+ if end_rx.try_recv() != Err(TryRecvError::Empty) {
+ break;
+ }
+ }