summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Guyer <galen@galenguyer.com>2022-11-28 16:24:38 -0500
committerGalen Guyer <galen@galenguyer.com>2022-11-28 16:24:38 -0500
commitf81ae648fef445681fa077846547cccc5a3ec547 (patch)
tree524a5b15a6a829b8961b9d2fae75c10ad000107c
parent5e9223919249f46763048557361a849cbd0224d5 (diff)
Priority and silence switching improvements
-rw-r--r--Cargo.lock53
-rw-r--r--Cargo.toml2
-rw-r--r--src/main.rs63
3 files changed, 98 insertions, 20 deletions
diff --git a/Cargo.lock b/Cargo.lock
index cee579e..46a293b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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]]
diff --git a/Cargo.toml b/Cargo.toml
index d813090..7e59bd3 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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;
}