[style](trx-rs): apply cargo fmt formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -146,7 +146,9 @@ pub fn ftx_find_candidates(
|
|||||||
|
|
||||||
let score = if is_ft2 {
|
let score = if is_ft2 {
|
||||||
#[cfg(feature = "ft2")]
|
#[cfg(feature = "ft2")]
|
||||||
{ crate::ft2::ft2_sync_score(wf, &cand) }
|
{
|
||||||
|
crate::ft2::ft2_sync_score(wf, &cand)
|
||||||
|
}
|
||||||
#[cfg(not(feature = "ft2"))]
|
#[cfg(not(feature = "ft2"))]
|
||||||
unreachable!()
|
unreachable!()
|
||||||
} else if wf.protocol.uses_ft4_layout() {
|
} else if wf.protocol.uses_ft4_layout() {
|
||||||
|
|||||||
@@ -181,9 +181,14 @@ impl WefaxDecoder {
|
|||||||
while self.signal_detect_buf.len() >= window_size {
|
while self.signal_detect_buf.len() >= window_size {
|
||||||
let window = &self.signal_detect_buf[..window_size];
|
let window = &self.signal_detect_buf[..window_size];
|
||||||
let mean = window.iter().sum::<f32>() / window.len() as f32;
|
let mean = window.iter().sum::<f32>() / window.len() as f32;
|
||||||
let variance = window.iter()
|
let variance = window
|
||||||
.map(|&v| { let d = v - mean; d * d })
|
.iter()
|
||||||
.sum::<f32>() / window.len() as f32;
|
.map(|&v| {
|
||||||
|
let d = v - mean;
|
||||||
|
d * d
|
||||||
|
})
|
||||||
|
.sum::<f32>()
|
||||||
|
/ window.len() as f32;
|
||||||
let stddev = variance.sqrt();
|
let stddev = variance.sqrt();
|
||||||
|
|
||||||
if stddev > SIGNAL_DETECT_MIN_STDDEV {
|
if stddev > SIGNAL_DETECT_MIN_STDDEV {
|
||||||
@@ -231,10 +236,7 @@ impl WefaxDecoder {
|
|||||||
|
|
||||||
State::Phasing { ioc, lpm } => {
|
State::Phasing { ioc, lpm } => {
|
||||||
// Check for stop tone (abort).
|
// Check for stop tone (abort).
|
||||||
if tone_results
|
if tone_results.iter().any(|r| r.tone == Some(AptTone::Stop)) {
|
||||||
.iter()
|
|
||||||
.any(|r| r.tone == Some(AptTone::Stop))
|
|
||||||
{
|
|
||||||
self.transition_to_idle();
|
self.transition_to_idle();
|
||||||
return events;
|
return events;
|
||||||
}
|
}
|
||||||
@@ -248,10 +250,7 @@ impl WefaxDecoder {
|
|||||||
|
|
||||||
State::Receiving { ioc, lpm } => {
|
State::Receiving { ioc, lpm } => {
|
||||||
// Check for stop tone.
|
// Check for stop tone.
|
||||||
if tone_results
|
if tone_results.iter().any(|r| r.tone == Some(AptTone::Stop)) {
|
||||||
.iter()
|
|
||||||
.any(|r| r.tone == Some(AptTone::Stop))
|
|
||||||
{
|
|
||||||
self.state = State::Stopping { ioc, lpm };
|
self.state = State::Stopping { ioc, lpm };
|
||||||
events.extend(self.finalize_image(ioc, lpm));
|
events.extend(self.finalize_image(ioc, lpm));
|
||||||
self.transition_to_idle();
|
self.transition_to_idle();
|
||||||
@@ -268,12 +267,10 @@ impl WefaxDecoder {
|
|||||||
|
|
||||||
// Emit progress event.
|
// Emit progress event.
|
||||||
if self.config.emit_progress && count % PROGRESS_INTERVAL == 0 {
|
if self.config.emit_progress && count % PROGRESS_INTERVAL == 0 {
|
||||||
let line_data = image
|
let line_data =
|
||||||
.last_line()
|
image.last_line().map(|l| l.to_vec()).unwrap_or_default();
|
||||||
.map(|l| l.to_vec())
|
let b64 =
|
||||||
.unwrap_or_default();
|
base64::engine::general_purpose::STANDARD.encode(&line_data);
|
||||||
let b64 = base64::engine::general_purpose::STANDARD
|
|
||||||
.encode(&line_data);
|
|
||||||
events.push(WefaxEvent::Progress(
|
events.push(WefaxEvent::Progress(
|
||||||
WefaxProgress {
|
WefaxProgress {
|
||||||
rig_id: None,
|
rig_id: None,
|
||||||
@@ -333,10 +330,7 @@ impl WefaxDecoder {
|
|||||||
|
|
||||||
/// Check if the decoder is currently receiving an image.
|
/// Check if the decoder is currently receiving an image.
|
||||||
pub fn is_receiving(&self) -> bool {
|
pub fn is_receiving(&self) -> bool {
|
||||||
matches!(
|
matches!(self.state, State::Phasing { .. } | State::Receiving { .. })
|
||||||
self.state,
|
|
||||||
State::Phasing { .. } | State::Receiving { .. }
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state_event(&self, label: &str, ioc: u16, lpm: u16) -> WefaxEvent {
|
fn state_event(&self, label: &str, ioc: u16, lpm: u16) -> WefaxEvent {
|
||||||
@@ -487,7 +481,10 @@ mod tests {
|
|||||||
let signal = generate_apt_start(300.0, 11025, 3.0);
|
let signal = generate_apt_start(300.0, 11025, 3.0);
|
||||||
dec.process_samples(&signal);
|
dec.process_samples(&signal);
|
||||||
assert!(
|
assert!(
|
||||||
matches!(dec.state, State::StartDetected { ioc: 576 } | State::Phasing { ioc: 576, .. }),
|
matches!(
|
||||||
|
dec.state,
|
||||||
|
State::StartDetected { ioc: 576 } | State::Phasing { ioc: 576, .. }
|
||||||
|
),
|
||||||
"state should be StartDetected or Phasing, got {:?}",
|
"state should be StartDetected or Phasing, got {:?}",
|
||||||
dec.state
|
dec.state
|
||||||
);
|
);
|
||||||
@@ -496,10 +493,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn decoder_reset_returns_to_idle() {
|
fn decoder_reset_returns_to_idle() {
|
||||||
let mut dec = WefaxDecoder::new(48000, WefaxConfig::default());
|
let mut dec = WefaxDecoder::new(48000, WefaxConfig::default());
|
||||||
dec.state = State::Receiving {
|
dec.state = State::Receiving { ioc: 576, lpm: 120 };
|
||||||
ioc: 576,
|
|
||||||
lpm: 120,
|
|
||||||
};
|
|
||||||
dec.reset();
|
dec.reset();
|
||||||
assert_eq!(dec.state, State::Idle);
|
assert_eq!(dec.state, State::Idle);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -126,8 +126,7 @@ fn design_hilbert_fir() -> [f32; HILBERT_TAPS] {
|
|||||||
// Hilbert kernel: 2/(π·n) for odd offsets.
|
// Hilbert kernel: 2/(π·n) for odd offsets.
|
||||||
let h = 2.0 / (std::f64::consts::PI * n);
|
let h = 2.0 / (std::f64::consts::PI * n);
|
||||||
// Blackman window.
|
// Blackman window.
|
||||||
let w = 0.42
|
let w = 0.42 - 0.5 * (2.0 * std::f64::consts::PI * i as f64 / m).cos()
|
||||||
- 0.5 * (2.0 * std::f64::consts::PI * i as f64 / m).cos()
|
|
||||||
+ 0.08 * (4.0 * std::f64::consts::PI * i as f64 / m).cos();
|
+ 0.08 * (4.0 * std::f64::consts::PI * i as f64 / m).cos();
|
||||||
coeffs[i] = (h * w) as f32;
|
coeffs[i] = (h * w) as f32;
|
||||||
}
|
}
|
||||||
@@ -173,11 +172,7 @@ mod tests {
|
|||||||
let lum = disc.process(&tone);
|
let lum = disc.process(&tone);
|
||||||
let tail = &lum[lum.len() / 2..];
|
let tail = &lum[lum.len() / 2..];
|
||||||
let avg: f32 = tail.iter().sum::<f32>() / tail.len() as f32;
|
let avg: f32 = tail.iter().sum::<f32>() / tail.len() as f32;
|
||||||
assert!(
|
assert!(avg < 0.05, "expected ~0.0 for black tone, got {}", avg);
|
||||||
avg < 0.05,
|
|
||||||
"expected ~0.0 for black tone, got {}",
|
|
||||||
avg
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -40,18 +40,12 @@ impl ImageAssembler {
|
|||||||
/// Encode the accumulated image to an 8-bit greyscale PNG file.
|
/// Encode the accumulated image to an 8-bit greyscale PNG file.
|
||||||
///
|
///
|
||||||
/// Returns the full path to the saved file.
|
/// Returns the full path to the saved file.
|
||||||
pub fn save_png(
|
pub fn save_png(&self, output_dir: &Path, freq_hz: u64, mode: &str) -> Result<PathBuf, String> {
|
||||||
&self,
|
|
||||||
output_dir: &Path,
|
|
||||||
freq_hz: u64,
|
|
||||||
mode: &str,
|
|
||||||
) -> Result<PathBuf, String> {
|
|
||||||
if self.lines.is_empty() {
|
if self.lines.is_empty() {
|
||||||
return Err("no image lines to save".into());
|
return Err("no image lines to save".into());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::fs::create_dir_all(output_dir)
|
std::fs::create_dir_all(output_dir).map_err(|e| format!("create output dir: {}", e))?;
|
||||||
.map_err(|e| format!("create output dir: {}", e))?;
|
|
||||||
|
|
||||||
let filename = generate_filename(freq_hz, mode);
|
let filename = generate_filename(freq_hz, mode);
|
||||||
let path = output_dir.join(&filename);
|
let path = output_dir.join(&filename);
|
||||||
|
|||||||
@@ -181,9 +181,7 @@ mod tests {
|
|||||||
|
|
||||||
panic!(
|
panic!(
|
||||||
"phasing should have locked after 20 lines (spl={}, pw={}, positions={:?})",
|
"phasing should have locked after 20 lines (spl={}, pw={}, positions={:?})",
|
||||||
spl,
|
spl, pw, det.pulse_positions
|
||||||
pw,
|
|
||||||
det.pulse_positions
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -189,11 +189,7 @@ mod tests {
|
|||||||
// Check last quarter of output is close to 1.0.
|
// Check last quarter of output is close to 1.0.
|
||||||
let tail = &output[output.len() * 3 / 4..];
|
let tail = &output[output.len() * 3 / 4..];
|
||||||
let avg: f32 = tail.iter().sum::<f32>() / tail.len() as f32;
|
let avg: f32 = tail.iter().sum::<f32>() / tail.len() as f32;
|
||||||
assert!(
|
assert!((avg - 1.0).abs() < 0.02, "DC gain mismatch: avg = {}", avg);
|
||||||
(avg - 1.0).abs() < 0.02,
|
|
||||||
"DC gain mismatch: avg = {}",
|
|
||||||
avg
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Resampler {
|
impl Resampler {
|
||||||
|
|||||||
@@ -138,8 +138,7 @@ impl ToneDetector {
|
|||||||
|
|
||||||
fn analyze_window(&mut self) -> ToneDetectResult {
|
fn analyze_window(&mut self) -> ToneDetectResult {
|
||||||
// Compute transition frequency: transitions per second.
|
// Compute transition frequency: transitions per second.
|
||||||
let freq =
|
let freq = self.transitions * self.sample_rate / self.sample_count.max(1) as u32;
|
||||||
self.transitions * self.sample_rate / self.sample_count.max(1) as u32;
|
|
||||||
|
|
||||||
let detected = classify_freq(freq);
|
let detected = classify_freq(freq);
|
||||||
|
|
||||||
@@ -195,7 +194,11 @@ mod tests {
|
|||||||
.map(|i| {
|
.map(|i| {
|
||||||
// Square wave at trans_freq Hz: above 0 → white, below 0 → black.
|
// Square wave at trans_freq Hz: above 0 → white, below 0 → black.
|
||||||
let phase = (2.0 * PI * trans_freq * i as f32 / sample_rate as f32).sin();
|
let phase = (2.0 * PI * trans_freq * i as f32 / sample_rate as f32).sin();
|
||||||
if phase >= 0.0 { 1.0 } else { 0.0 }
|
if phase >= 0.0 {
|
||||||
|
1.0
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
@@ -252,9 +255,8 @@ mod tests {
|
|||||||
.map(|i| {
|
.map(|i| {
|
||||||
// Mix of frequencies that don't match any APT tone.
|
// Mix of frequencies that don't match any APT tone.
|
||||||
let t = i as f32 / sr as f32;
|
let t = i as f32 / sr as f32;
|
||||||
(0.5 + 0.3 * (2.0 * PI * 137.0 * t).sin()
|
(0.5 + 0.3 * (2.0 * PI * 137.0 * t).sin() + 0.2 * (2.0 * PI * 523.0 * t).sin())
|
||||||
+ 0.2 * (2.0 * PI * 523.0 * t).sin())
|
.clamp(0.0, 1.0)
|
||||||
.clamp(0.0, 1.0)
|
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
let results = det.process(&signal);
|
let results = det.process(&signal);
|
||||||
|
|||||||
@@ -265,10 +265,8 @@ fn idct_8x8(coeffs: &[i32; 64], output: &mut [u8; 64]) {
|
|||||||
1.0
|
1.0
|
||||||
};
|
};
|
||||||
let coeff = coeffs[v * 8 + u] as f64;
|
let coeff = coeffs[v * 8 + u] as f64;
|
||||||
let cos_x =
|
let cos_x = (std::f64::consts::PI * (2 * x + 1) as f64 * u as f64 / 16.0).cos();
|
||||||
(std::f64::consts::PI * (2 * x + 1) as f64 * u as f64 / 16.0).cos();
|
let cos_y = (std::f64::consts::PI * (2 * y + 1) as f64 * v as f64 / 16.0).cos();
|
||||||
let cos_y =
|
|
||||||
(std::f64::consts::PI * (2 * y + 1) as f64 * v as f64 / 16.0).cos();
|
|
||||||
sum += cu * cv * coeff * cos_x * cos_y;
|
sum += cu * cv * coeff * cos_x * cos_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -703,16 +701,10 @@ mod tests {
|
|||||||
assert_eq!(asm.identify_satellite(), None);
|
assert_eq!(asm.identify_satellite(), None);
|
||||||
|
|
||||||
asm.spacecraft_id = Some(SPACECRAFT_M2_3);
|
asm.spacecraft_id = Some(SPACECRAFT_M2_3);
|
||||||
assert_eq!(
|
assert_eq!(asm.identify_satellite(), Some(MeteorSatellite::MeteorM2_3));
|
||||||
asm.identify_satellite(),
|
|
||||||
Some(MeteorSatellite::MeteorM2_3)
|
|
||||||
);
|
|
||||||
|
|
||||||
asm.spacecraft_id = Some(SPACECRAFT_M2_4);
|
asm.spacecraft_id = Some(SPACECRAFT_M2_4);
|
||||||
assert_eq!(
|
assert_eq!(asm.identify_satellite(), Some(MeteorSatellite::MeteorM2_4));
|
||||||
asm.identify_satellite(),
|
|
||||||
Some(MeteorSatellite::MeteorM2_4)
|
|
||||||
);
|
|
||||||
|
|
||||||
asm.spacecraft_id = Some(99);
|
asm.spacecraft_id = Some(99);
|
||||||
assert_eq!(asm.identify_satellite(), Some(MeteorSatellite::Unknown));
|
assert_eq!(asm.identify_satellite(), Some(MeteorSatellite::Unknown));
|
||||||
|
|||||||
@@ -26,12 +26,12 @@ use trx_core::audio::{
|
|||||||
parse_vchan_audio_frame, parse_vchan_uuid_msg, read_audio_msg, write_audio_msg,
|
parse_vchan_audio_frame, parse_vchan_uuid_msg, read_audio_msg, write_audio_msg,
|
||||||
write_vchan_uuid_msg, AudioStreamInfo, AUDIO_MSG_AIS_DECODE, AUDIO_MSG_APRS_DECODE,
|
write_vchan_uuid_msg, AudioStreamInfo, AUDIO_MSG_AIS_DECODE, AUDIO_MSG_APRS_DECODE,
|
||||||
AUDIO_MSG_CW_DECODE, AUDIO_MSG_FT2_DECODE, AUDIO_MSG_FT4_DECODE, AUDIO_MSG_FT8_DECODE,
|
AUDIO_MSG_CW_DECODE, AUDIO_MSG_FT2_DECODE, AUDIO_MSG_FT4_DECODE, AUDIO_MSG_FT8_DECODE,
|
||||||
AUDIO_MSG_HF_APRS_DECODE, AUDIO_MSG_HISTORY_COMPRESSED, AUDIO_MSG_RX_FRAME,
|
AUDIO_MSG_HF_APRS_DECODE, AUDIO_MSG_HISTORY_COMPRESSED, AUDIO_MSG_LRPT_IMAGE,
|
||||||
AUDIO_MSG_RX_FRAME_CH, AUDIO_MSG_STREAM_INFO, AUDIO_MSG_TX_FRAME, AUDIO_MSG_VCHAN_ALLOCATED,
|
AUDIO_MSG_LRPT_PROGRESS, AUDIO_MSG_RX_FRAME, AUDIO_MSG_RX_FRAME_CH, AUDIO_MSG_STREAM_INFO,
|
||||||
AUDIO_MSG_VCHAN_BW, AUDIO_MSG_VCHAN_DESTROYED, AUDIO_MSG_VCHAN_FREQ, AUDIO_MSG_VCHAN_MODE,
|
AUDIO_MSG_TX_FRAME, AUDIO_MSG_VCHAN_ALLOCATED, AUDIO_MSG_VCHAN_BW, AUDIO_MSG_VCHAN_DESTROYED,
|
||||||
AUDIO_MSG_LRPT_IMAGE, AUDIO_MSG_LRPT_PROGRESS, AUDIO_MSG_WEFAX_DECODE,
|
AUDIO_MSG_VCHAN_FREQ, AUDIO_MSG_VCHAN_MODE, AUDIO_MSG_VCHAN_REMOVE, AUDIO_MSG_VCHAN_SUB,
|
||||||
AUDIO_MSG_WEFAX_PROGRESS, AUDIO_MSG_VCHAN_REMOVE, AUDIO_MSG_VCHAN_SUB,
|
AUDIO_MSG_VCHAN_UNSUB, AUDIO_MSG_VDES_DECODE, AUDIO_MSG_WEFAX_DECODE, AUDIO_MSG_WEFAX_PROGRESS,
|
||||||
AUDIO_MSG_VCHAN_UNSUB, AUDIO_MSG_VDES_DECODE, AUDIO_MSG_WSPR_DECODE,
|
AUDIO_MSG_WSPR_DECODE,
|
||||||
};
|
};
|
||||||
use trx_core::decode::DecodedMessage;
|
use trx_core::decode::DecodedMessage;
|
||||||
use trx_frontend::VChanAudioCmd;
|
use trx_frontend::VChanAudioCmd;
|
||||||
|
|||||||
@@ -170,171 +170,103 @@ pub(crate) async fn themes_css(req: HttpRequest) -> impl Responder {
|
|||||||
#[get("/app.js")]
|
#[get("/app.js")]
|
||||||
pub(crate) async fn app_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn app_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_app_js();
|
let c = gz_app_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/map-core.js")]
|
#[get("/map-core.js")]
|
||||||
pub(crate) async fn map_core_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn map_core_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_map_core_js();
|
let c = gz_map_core_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/screenshot.js")]
|
#[get("/screenshot.js")]
|
||||||
pub(crate) async fn screenshot_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn screenshot_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_screenshot_js();
|
let c = gz_screenshot_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/decode-history-worker.js")]
|
#[get("/decode-history-worker.js")]
|
||||||
pub(crate) async fn decode_history_worker_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn decode_history_worker_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_decode_history_worker_js();
|
let c = gz_decode_history_worker_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/webgl-renderer.js")]
|
#[get("/webgl-renderer.js")]
|
||||||
pub(crate) async fn webgl_renderer_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn webgl_renderer_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_webgl_renderer_js();
|
let c = gz_webgl_renderer_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/leaflet-ais-tracksymbol.js")]
|
#[get("/leaflet-ais-tracksymbol.js")]
|
||||||
pub(crate) async fn leaflet_ais_tracksymbol_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn leaflet_ais_tracksymbol_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_leaflet_ais_tracksymbol_js();
|
let c = gz_leaflet_ais_tracksymbol_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/aprs.js")]
|
#[get("/aprs.js")]
|
||||||
pub(crate) async fn aprs_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn aprs_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_aprs_js();
|
let c = gz_aprs_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/hf-aprs.js")]
|
#[get("/hf-aprs.js")]
|
||||||
pub(crate) async fn hf_aprs_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn hf_aprs_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_hf_aprs_js();
|
let c = gz_hf_aprs_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/ais.js")]
|
#[get("/ais.js")]
|
||||||
pub(crate) async fn ais_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn ais_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_ais_js();
|
let c = gz_ais_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/vdes.js")]
|
#[get("/vdes.js")]
|
||||||
pub(crate) async fn vdes_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn vdes_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_vdes_js();
|
let c = gz_vdes_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/ft8.js")]
|
#[get("/ft8.js")]
|
||||||
pub(crate) async fn ft8_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn ft8_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_ft8_js();
|
let c = gz_ft8_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/ft4.js")]
|
#[get("/ft4.js")]
|
||||||
pub(crate) async fn ft4_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn ft4_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_ft4_js();
|
let c = gz_ft4_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/ft2.js")]
|
#[get("/ft2.js")]
|
||||||
pub(crate) async fn ft2_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn ft2_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_ft2_js();
|
let c = gz_ft2_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/wspr.js")]
|
#[get("/wspr.js")]
|
||||||
pub(crate) async fn wspr_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn wspr_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_wspr_js();
|
let c = gz_wspr_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/cw.js")]
|
#[get("/cw.js")]
|
||||||
pub(crate) async fn cw_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn cw_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_cw_js();
|
let c = gz_cw_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/sat.js")]
|
#[get("/sat.js")]
|
||||||
pub(crate) async fn sat_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn sat_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_sat_js();
|
let c = gz_sat_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/wefax.js")]
|
#[get("/wefax.js")]
|
||||||
pub(crate) async fn wefax_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn wefax_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_wefax_js();
|
let c = gz_wefax_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/images/{filename}")]
|
#[get("/images/{filename}")]
|
||||||
@@ -364,51 +296,31 @@ pub(crate) async fn wefax_image(path: web::Path<String>) -> impl Responder {
|
|||||||
#[get("/bookmarks.js")]
|
#[get("/bookmarks.js")]
|
||||||
pub(crate) async fn bookmarks_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn bookmarks_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_bookmarks_js();
|
let c = gz_bookmarks_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/scheduler.js")]
|
#[get("/scheduler.js")]
|
||||||
pub(crate) async fn scheduler_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn scheduler_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_scheduler_js();
|
let c = gz_scheduler_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/sat-scheduler.js")]
|
#[get("/sat-scheduler.js")]
|
||||||
pub(crate) async fn sat_scheduler_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn sat_scheduler_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_sat_scheduler_js();
|
let c = gz_sat_scheduler_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/background-decode.js")]
|
#[get("/background-decode.js")]
|
||||||
pub(crate) async fn background_decode_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn background_decode_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_background_decode_js();
|
let c = gz_background_decode_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/vchan.js")]
|
#[get("/vchan.js")]
|
||||||
pub(crate) async fn vchan_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn vchan_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_vchan_js();
|
let c = gz_vchan_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/bandplan.json")]
|
#[get("/bandplan.json")]
|
||||||
@@ -436,11 +348,7 @@ pub(crate) async fn dseg14_classic_woff2() -> impl Responder {
|
|||||||
#[get("/vendor/leaflet.js")]
|
#[get("/vendor/leaflet.js")]
|
||||||
pub(crate) async fn leaflet_js(req: HttpRequest) -> impl Responder {
|
pub(crate) async fn leaflet_js(req: HttpRequest) -> impl Responder {
|
||||||
let c = gz_leaflet_js();
|
let c = gz_leaflet_js();
|
||||||
static_asset_response(
|
static_asset_response(&req, "application/javascript; charset=utf-8", c)
|
||||||
&req,
|
|
||||||
"application/javascript; charset=utf-8",
|
|
||||||
c,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/vendor/leaflet.css")]
|
#[get("/vendor/leaflet.css")]
|
||||||
|
|||||||
@@ -319,10 +319,7 @@ fn static_asset_response(
|
|||||||
if val == etag || val == "*" {
|
if val == etag || val == "*" {
|
||||||
return HttpResponse::NotModified()
|
return HttpResponse::NotModified()
|
||||||
.insert_header((header::ETAG, etag.to_owned()))
|
.insert_header((header::ETAG, etag.to_owned()))
|
||||||
.insert_header((
|
.insert_header((header::CACHE_CONTROL, "public, max-age=31536000, immutable"))
|
||||||
header::CACHE_CONTROL,
|
|
||||||
"public, max-age=31536000, immutable",
|
|
||||||
))
|
|
||||||
.finish();
|
.finish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -342,10 +339,7 @@ fn static_asset_response(
|
|||||||
.insert_header((header::CONTENT_TYPE, content_type))
|
.insert_header((header::CONTENT_TYPE, content_type))
|
||||||
.insert_header((header::CONTENT_ENCODING, encoding))
|
.insert_header((header::CONTENT_ENCODING, encoding))
|
||||||
.insert_header((header::ETAG, etag.to_owned()))
|
.insert_header((header::ETAG, etag.to_owned()))
|
||||||
.insert_header((
|
.insert_header((header::CACHE_CONTROL, "public, max-age=31536000, immutable"))
|
||||||
header::CACHE_CONTROL,
|
|
||||||
"public, max-age=31536000, immutable",
|
|
||||||
))
|
|
||||||
.body(Bytes::copy_from_slice(body))
|
.body(Bytes::copy_from_slice(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,16 +43,11 @@ pub const DSEG14_CLASSIC_WOFF2: &[u8] =
|
|||||||
// Vendored Leaflet 1.9.4
|
// Vendored Leaflet 1.9.4
|
||||||
pub const LEAFLET_JS: &str = include_str!("../assets/web/vendor/leaflet.js");
|
pub const LEAFLET_JS: &str = include_str!("../assets/web/vendor/leaflet.js");
|
||||||
pub const LEAFLET_CSS: &str = include_str!("../assets/web/vendor/leaflet.css");
|
pub const LEAFLET_CSS: &str = include_str!("../assets/web/vendor/leaflet.css");
|
||||||
pub const LEAFLET_MARKER_ICON: &[u8] =
|
pub const LEAFLET_MARKER_ICON: &[u8] = include_bytes!("../assets/web/vendor/marker-icon.png");
|
||||||
include_bytes!("../assets/web/vendor/marker-icon.png");
|
pub const LEAFLET_MARKER_ICON_2X: &[u8] = include_bytes!("../assets/web/vendor/marker-icon-2x.png");
|
||||||
pub const LEAFLET_MARKER_ICON_2X: &[u8] =
|
pub const LEAFLET_MARKER_SHADOW: &[u8] = include_bytes!("../assets/web/vendor/marker-shadow.png");
|
||||||
include_bytes!("../assets/web/vendor/marker-icon-2x.png");
|
pub const LEAFLET_LAYERS: &[u8] = include_bytes!("../assets/web/vendor/layers.png");
|
||||||
pub const LEAFLET_MARKER_SHADOW: &[u8] =
|
pub const LEAFLET_LAYERS_2X: &[u8] = include_bytes!("../assets/web/vendor/layers-2x.png");
|
||||||
include_bytes!("../assets/web/vendor/marker-shadow.png");
|
|
||||||
pub const LEAFLET_LAYERS: &[u8] =
|
|
||||||
include_bytes!("../assets/web/vendor/layers.png");
|
|
||||||
pub const LEAFLET_LAYERS_2X: &[u8] =
|
|
||||||
include_bytes!("../assets/web/vendor/layers-2x.png");
|
|
||||||
|
|
||||||
/// Build version tag used for cache-busting asset URLs and ETag headers.
|
/// Build version tag used for cache-busting asset URLs and ETag headers.
|
||||||
/// Computed once from `PKG_VERSION` + `CLIENT_BUILD_DATE`.
|
/// Computed once from `PKG_VERSION` + `CLIENT_BUILD_DATE`.
|
||||||
|
|||||||
+12
-14
@@ -28,16 +28,14 @@ use trx_core::audio::{
|
|||||||
write_vchan_uuid_msg, AudioStreamInfo, AUDIO_MSG_AIS_DECODE, AUDIO_MSG_APRS_DECODE,
|
write_vchan_uuid_msg, AudioStreamInfo, AUDIO_MSG_AIS_DECODE, AUDIO_MSG_APRS_DECODE,
|
||||||
AUDIO_MSG_CW_DECODE, AUDIO_MSG_FT2_DECODE, AUDIO_MSG_FT4_DECODE, AUDIO_MSG_FT8_DECODE,
|
AUDIO_MSG_CW_DECODE, AUDIO_MSG_FT2_DECODE, AUDIO_MSG_FT4_DECODE, AUDIO_MSG_FT8_DECODE,
|
||||||
AUDIO_MSG_HF_APRS_DECODE, AUDIO_MSG_HISTORY_COMPRESSED, AUDIO_MSG_LRPT_IMAGE,
|
AUDIO_MSG_HF_APRS_DECODE, AUDIO_MSG_HISTORY_COMPRESSED, AUDIO_MSG_LRPT_IMAGE,
|
||||||
AUDIO_MSG_LRPT_PROGRESS, AUDIO_MSG_WEFAX_DECODE, AUDIO_MSG_WEFAX_PROGRESS,
|
AUDIO_MSG_LRPT_PROGRESS, AUDIO_MSG_RX_FRAME, AUDIO_MSG_STREAM_INFO, AUDIO_MSG_TX_FRAME,
|
||||||
AUDIO_MSG_RX_FRAME, AUDIO_MSG_STREAM_INFO, AUDIO_MSG_TX_FRAME, AUDIO_MSG_VCHAN_ALLOCATED,
|
AUDIO_MSG_VCHAN_ALLOCATED, AUDIO_MSG_VCHAN_BW, AUDIO_MSG_VCHAN_DESTROYED, AUDIO_MSG_VCHAN_FREQ,
|
||||||
AUDIO_MSG_VCHAN_BW, AUDIO_MSG_VCHAN_DESTROYED, AUDIO_MSG_VCHAN_FREQ, AUDIO_MSG_VCHAN_MODE,
|
AUDIO_MSG_VCHAN_MODE, AUDIO_MSG_VCHAN_REMOVE, AUDIO_MSG_VCHAN_SUB, AUDIO_MSG_VCHAN_UNSUB,
|
||||||
AUDIO_MSG_VCHAN_REMOVE, AUDIO_MSG_VCHAN_SUB, AUDIO_MSG_VCHAN_UNSUB, AUDIO_MSG_VDES_DECODE,
|
AUDIO_MSG_VDES_DECODE, AUDIO_MSG_WEFAX_DECODE, AUDIO_MSG_WEFAX_PROGRESS, AUDIO_MSG_WSPR_DECODE,
|
||||||
AUDIO_MSG_WSPR_DECODE,
|
|
||||||
};
|
};
|
||||||
use trx_core::decode::{
|
use trx_core::decode::{
|
||||||
AisMessage, AprsPacket, CwEvent, DecodedMessage, Ft8Message, LrptImage, LrptProgress,
|
AisMessage, AprsPacket, CwEvent, DecodedMessage, Ft8Message, LrptImage, LrptProgress,
|
||||||
VdesMessage, WefaxMessage,
|
VdesMessage, WefaxMessage, WsprMessage,
|
||||||
WsprMessage,
|
|
||||||
};
|
};
|
||||||
use trx_core::rig::state::{RigMode, RigState};
|
use trx_core::rig::state::{RigMode, RigState};
|
||||||
use trx_core::vchan::SharedVChanManager;
|
use trx_core::vchan::SharedVChanManager;
|
||||||
@@ -2687,10 +2685,7 @@ pub async fn run_wefax_decoder(
|
|||||||
) {
|
) {
|
||||||
use trx_wefax::{WefaxConfig, WefaxDecoder, WefaxEvent};
|
use trx_wefax::{WefaxConfig, WefaxDecoder, WefaxEvent};
|
||||||
|
|
||||||
info!(
|
info!("WEFAX decoder started ({}Hz, {} ch)", sample_rate, channels);
|
||||||
"WEFAX decoder started ({}Hz, {} ch)",
|
|
||||||
sample_rate, channels
|
|
||||||
);
|
|
||||||
|
|
||||||
let wefax_output_dir = dirs::cache_dir()
|
let wefax_output_dir = dirs::cache_dir()
|
||||||
.unwrap_or_else(|| std::path::PathBuf::from(".cache"))
|
.unwrap_or_else(|| std::path::PathBuf::from(".cache"))
|
||||||
@@ -2705,7 +2700,10 @@ pub async fn run_wefax_decoder(
|
|||||||
let mut last_reset_seq: u64 = 0;
|
let mut last_reset_seq: u64 = 0;
|
||||||
|
|
||||||
let is_wefax_mode = |mode: &RigMode| {
|
let is_wefax_mode = |mode: &RigMode| {
|
||||||
matches!(mode, RigMode::USB | RigMode::LSB | RigMode::AM | RigMode::DIG)
|
matches!(
|
||||||
|
mode,
|
||||||
|
RigMode::USB | RigMode::LSB | RigMode::AM | RigMode::DIG
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut active = state_rx.borrow().decoders.wefax_decode_enabled
|
let mut active = state_rx.borrow().decoders.wefax_decode_enabled
|
||||||
@@ -2716,8 +2714,8 @@ pub async fn run_wefax_decoder(
|
|||||||
match state_rx.changed().await {
|
match state_rx.changed().await {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
let state = state_rx.borrow();
|
let state = state_rx.borrow();
|
||||||
active = state.decoders.wefax_decode_enabled
|
active =
|
||||||
&& is_wefax_mode(&state.status.mode);
|
state.decoders.wefax_decode_enabled && is_wefax_mode(&state.status.mode);
|
||||||
if active {
|
if active {
|
||||||
pcm_rx = pcm_rx.resubscribe();
|
pcm_rx = pcm_rx.resubscribe();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user