summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-11-28 14:56:41 -0500
committerGalen Guyer <galen@galenguyer.com>2022-11-28 14:56:41 -0500
commit20814daa780a5e96ed312caf327b2a19306ce3ab (patch)
treee4daac20399fd929eecf6f22fac825e6880aa707
parent284fb87d68596b750c34c0a1164b780479aa04cf (diff)
Add talkgroup switch buffer
-rw-r--r--src/main.rs84
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;
}