diff options
author | Galen Guyer <galen@galenguyer.com> | 2022-11-28 16:24:38 -0500 |
---|---|---|
committer | Galen Guyer <galen@galenguyer.com> | 2022-11-28 16:24:38 -0500 |
commit | f81ae648fef445681fa077846547cccc5a3ec547 (patch) | |
tree | 524a5b15a6a829b8961b9d2fae75c10ad000107c | |
parent | 5e9223919249f46763048557361a849cbd0224d5 (diff) |
Priority and silence switching improvements
-rw-r--r-- | Cargo.lock | 53 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | src/main.rs | 63 |
3 files changed, 98 insertions, 20 deletions
@@ -135,7 +135,7 @@ dependencies = [ "js-sys", "num-integer", "num-traits", - "time", + "time 0.1.44", "wasm-bindgen", "winapi", ] @@ -733,6 +733,15 @@ dependencies = [ ] [[package]] +name = "num_threads" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" +dependencies = [ + "libc", +] + +[[package]] name = "oboe" version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -989,6 +998,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43b2853a4d09f215c24cc5489c992ce46052d359b5109343cbafbf26bc62f8a3" [[package]] +name = "simplelog" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48dfff04aade74dd495b007c831cd6f4e0cee19c344dd9dc0884c0289b70a786" +dependencies = [ + "log", + "termcolor", + "time 0.3.17", +] + +[[package]] name = "smallvec" version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1095,6 +1115,35 @@ dependencies = [ ] [[package]] +name = "time" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" +dependencies = [ + "itoa 1.0.4", + "libc", + "num_threads", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" + +[[package]] +name = "time-macros" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" +dependencies = [ + "time-core", +] + +[[package]] name = "toml" version = "0.5.9" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1111,8 +1160,10 @@ dependencies = [ "cpal", "csv", "dasp", + "log", "ringbuf", "serde", + "simplelog", ] [[package]] @@ -10,5 +10,7 @@ chrono = "0.4.23" cpal = "0.14.1" csv = "1.1.6" dasp = { version = "0.11.0", features = ["all"] } +log = "0.4.17" ringbuf = "0.3.1" serde = { version = "1.0.148", features = ["derive"] } +simplelog = "0.12.0" diff --git a/src/main.rs b/src/main.rs index 4313956..c686f0c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,9 +1,11 @@ use cpal::traits::{DeviceTrait, HostTrait, StreamTrait}; +use log::*; use ringbuf::HeapRb; use serde::Deserialize; use std::{ collections::HashMap, net::UdpSocket, + sync::{Arc, Mutex}, time::{Duration, Instant}, }; @@ -78,6 +80,13 @@ enum TalkGroupStatus { } fn main() { + #[cfg(debug_assertions)] + let _ = + simplelog::SimpleLogger::init(simplelog::LevelFilter::Debug, simplelog::Config::default()); + #[cfg(not(debug_assertions))] + let _ = + simplelog::SimpleLogger::init(simplelog::LevelFilter::Info, simplelog::Config::default()); + // Load talkgroups from file let mut csv_reader = csv::Reader::from_path("talkgroups.csv").unwrap(); let mut talkgroups: HashMap<u32, TalkGroup> = HashMap::new(); @@ -86,14 +95,14 @@ fn main() { talkgroups.insert(record.id, record); } // Print TalkGroup info - println!("Talkgroups loaded: {}", talkgroups.len()); + info!("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() { - println!("\tPriority {}: {} talkgroups", i, at_pri.len()); + info!("\tPriority {}: {} talkgroups", i, at_pri.len()); } } let i = -1; @@ -102,7 +111,7 @@ fn main() { .filter(|tg| tg.priority == i) .collect::<Vec<_>>(); if !at_pri.is_empty() { - println!("\tPriority {}: {} talkgroups", i, at_pri.len()); + info!("\tPriority {}: {} talkgroups", i, at_pri.len()); } drop(at_pri); @@ -113,13 +122,23 @@ fn main() { let buffer = HeapRb::<i16>::new(8192); let (mut producer, mut consumer) = buffer.split(); - let mut listening_tg = TalkGroupStatus::None; + let listening_tg = Arc::new(Mutex::new(TalkGroupStatus::None)); + let stream_listening_tg = listening_tg.clone(); let audio_stream = match stream_config.sample_format() { cpal::SampleFormat::I16 => device .build_output_stream( &stream_config.into(), - move |data: &mut [i16], cbinfo| write_audio(data, &mut consumer, cbinfo), + move |data: &mut [i16], cbinfo| { + let mut listening_tg = stream_listening_tg.lock().unwrap(); + if let TalkGroupStatus::Complete(tg, ea) = &*listening_tg { + if ea.elapsed() > Duration::from_secs(2) { + info!("Stopped listening to {}", tg.name); + *listening_tg = TalkGroupStatus::None; + } + } + write_audio(data, &mut consumer, cbinfo) + }, |err| eprintln!("error occurred on the audio output stream: {}", err), ) .unwrap(), @@ -140,44 +159,50 @@ fn main() { let curr_tg = talkgroups .get(&tg) .map(|tg| tg.to_owned()) - .unwrap_or(TalkGroup::unknown(tg)); + .unwrap_or_else(|| TalkGroup::unknown(tg)); if curr_tg.priority == -1 { continue; } let audio_bytes = &filled_buf[4..]; - match &listening_tg { + let mut listening_tg = listening_tg.lock().unwrap(); + match &*listening_tg { TalkGroupStatus::Active(listen_tg) => { if listen_tg.id != curr_tg.id { // 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; + if curr_tg.priority > 0 && curr_tg.priority < listen_tg.priority { + println!("Switching to TG with higher priority: {}", curr_tg.name); + *listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); + } else { + continue; + } } } TalkGroupStatus::Complete(listen_tg, completed_at) => { - if audio_bytes.len() == 2 && i16::from_le_bytes(audio_bytes.try_into().unwrap()) == 0 { + 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()); + info!("Switching to TG: {}", curr_tg.name); + *listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); } else { + debug!("TG Swap Wait not completed, skipping packet"); continue; } } else { - listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); + debug!("Complete talkgroup still active, resetting"); + *listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); } } TalkGroupStatus::None => { - println!("Switching to TG: {}", curr_tg.name); - listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); + info!("Switching to TG: {}", curr_tg.name); + *listening_tg = TalkGroupStatus::Active(curr_tg.to_owned()); } } @@ -185,7 +210,7 @@ fn main() { // 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()); + *listening_tg = TalkGroupStatus::Complete(curr_tg.to_owned(), Instant::now()); continue; } |