diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-11-28 14:56:41 -0500 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-11-28 14:56:41 -0500 |
commit | 20814daa780a5e96ed312caf327b2a19306ce3ab (patch) | |
tree | e4daac20399fd929eecf6f22fac825e6880aa707 | |
parent | 284fb87d68596b750c34c0a1164b780479aa04cf (diff) |
Add talkgroup switch buffer
-rw-r--r-- | src/main.rs | 84 |
1 files changed, 55 insertions, 29 deletions
diff --git a/src/main.rs b/src/main.rs index 1e2edaa..446c8b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,11 @@ use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; use ringbuf::HeapRb; use serde::Deserialize; -use std::{collections::HashMap, net::UdpSocket}; +use std::{ + collections::HashMap, + net::UdpSocket, + time::{Duration, Instant}, +}; #[allow(dead_code)] #[derive(Debug, Deserialize, Clone)] @@ -49,8 +53,7 @@ fn init_cpal() -> (cpal::Device, cpal::SupportedStreamConfig) { .expect("no supported config?!") .with_sample_rate(cpal::SampleRate(8000)); - dbg!(device.name().unwrap()); - (device, dbg!(supported_config)) + (device, supported_config) } fn write_audio<T: cpal::Sample + std::fmt::Debug>( @@ -68,6 +71,12 @@ fn write_audio<T: cpal::Sample + std::fmt::Debug>( } } +enum TalkGroupStatus { + None, + Complete(TalkGroup, Instant), + Active(TalkGroup), +} + fn main() { // Load talkgroups from file let mut csv_reader = csv::Reader::from_path("talkgroups.csv").unwrap(); @@ -77,27 +86,25 @@ fn main() { talkgroups.insert(record.id, record); } // Print TalkGroup info - { - let mut tg_info = format!("Talkgroups loaded: {}", talkgroups.len()); - for i in 1..=32 { - let at_pri = talkgroups - .values() - .filter(|tg| tg.priority == i) - .collect::<Vec<_>>(); - if !at_pri.is_empty() { - tg_info.push_str(&format!("\n\tPriority {}: {} talkgroups", i, at_pri.len())); - } - } - let i = -1; + println!("Talkgroups loaded: {}", talkgroups.len()); + for i in 1..=32 { let at_pri = talkgroups .values() .filter(|tg| tg.priority == i) .collect::<Vec<_>>(); if !at_pri.is_empty() { - tg_info.push_str(&format!("\n\tPriority {}: {} talkgroups", i, at_pri.len())); + println!("\tPriority {}: {} talkgroups", i, at_pri.len()); } - println!("{}", tg_info); } + let i = -1; + let at_pri = talkgroups + .values() + .filter(|tg| tg.priority == i) + .collect::<Vec<_>>(); + if !at_pri.is_empty() { + println!("\tPriority {}: {} talkgroups", i, at_pri.len()); + } + drop(at_pri); let socket = UdpSocket::bind("0.0.0.0:9123").expect("couldn't bind to address"); @@ -106,7 +113,7 @@ fn main() { let buffer = HeapRb::<i16>::new(8192); let (mut producer, mut consumer) = buffer.split(); - let mut listening_tg: Option<TalkGroup> = None; + let mut listening_tg = TalkGroupStatus::None; let audio_stream = match stream_config.sample_format() { cpal::SampleFormat::I16 => device @@ -137,26 +144,45 @@ fn main() { let audio_bytes = &filled_buf[4..]; match &listening_tg { - Some(listen_tg) => { + TalkGroupStatus::Active(listen_tg) => { if listen_tg.id != curr_tg.id { - if curr_tg.priority > 0 && curr_tg.priority < listen_tg.priority { - println!("Switching to TG with higher priority: {}", curr_tg.name); - listening_tg = Some(curr_tg.to_owned()); - } + // Big maybe on if we wanna do this. In theory, we can swap talkgroups + // immediately if a higher priority talkgroup comes in, but that might + // be a bit jarring. For now, we'll just wait until the current talkgroup + // is done. + // if curr_tg.priority > 0 && curr_tg.priority < listen_tg.priority { + // println!("Switching to TG with higher priority: {}", curr_tg.name); + // listening_tg = Some(curr_tg.to_owned()); + // } continue; } } - None => { + TalkGroupStatus::Complete(listen_tg, completed_at) => { + if audio_bytes.len() == 2 && i16::from_le_bytes(audio_bytes.try_into().unwrap()) == 0 { + continue; + } + if listen_tg.id != curr_tg.id { + if completed_at.elapsed() > Duration::from_secs(1) { + println!("Switching to TG: {}", curr_tg.name); + listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); + } else { + continue; + } + } else { + listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); + } + } + TalkGroupStatus::None => { println!("Switching to TG: {}", curr_tg.name); - listening_tg = Some(curr_tg.to_owned()); + listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); } } if audio_bytes.len() == 2 && i16::from_le_bytes(audio_bytes.try_into().unwrap()) == 0 { - if let Some(curr_tg) = listening_tg { - println!("End of transmission from TG {}", curr_tg.name); - } - listening_tg = None; + // if let Some(listen_tg) = &listening_tg { + // println!("End of transmission from TG {}", listen_tg.name); + // } + listening_tg = TalkGroupStatus::Complete(curr_tg.to_owned(), Instant::now()); continue; } |