[fix](trx-rs): show signal strength with decimal precision
Change RigRxStatus.sig from i32 to f64 and add get_signal_strength_db to RigCat trait so SDR backends can bypass the coarse 0..15 quantisation. Compensate for decimation processing gain so the meter matches the spectrum peak. Display with one decimal place in all units. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
@@ -887,7 +887,9 @@ async fn refresh_state_from_cat(rig: &mut Box<dyn RigCat>, state: &mut RigState)
|
||||
state.status.vfo = vfo;
|
||||
|
||||
if state.status.tx_en {
|
||||
state.status.rx.get_or_insert(RigRxStatus { sig: None }).sig = Some(0);
|
||||
state.status.rx.get_or_insert(RigRxStatus { sig: None }).sig = Some(0.0);
|
||||
} else if let Some(db) = rig.get_signal_strength_db().await {
|
||||
state.status.rx.get_or_insert(RigRxStatus { sig: None }).sig = Some(db);
|
||||
} else if let Ok(meter) = rig.get_signal_strength().await {
|
||||
let sig = map_signal_strength(&state.status.mode, meter);
|
||||
state.status.rx.get_or_insert(RigRxStatus { sig: None }).sig = Some(sig);
|
||||
@@ -1015,12 +1017,12 @@ async fn prime_vfo_state(
|
||||
}
|
||||
|
||||
/// Map raw signal strength to S-meter value based on mode.
|
||||
fn map_signal_strength(mode: &RigMode, raw: u8) -> i32 {
|
||||
fn map_signal_strength(mode: &RigMode, raw: u8) -> f64 {
|
||||
// FT-817 returns 0-15 for signal strength
|
||||
// Map to approximate dBm / S-units
|
||||
match mode {
|
||||
RigMode::FM | RigMode::WFM | RigMode::AIS | RigMode::VDES => -120 + (raw as i32 * 6),
|
||||
_ => -127 + (raw as i32 * 6),
|
||||
RigMode::FM | RigMode::WFM | RigMode::AIS | RigMode::VDES => -120.0 + (raw as f64 * 6.0),
|
||||
_ => -127.0 + (raw as f64 * 6.0),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -757,7 +757,13 @@ impl ChannelDsp {
|
||||
}
|
||||
|
||||
// Signal strength measurement (before AGC).
|
||||
//
|
||||
// The decimated samples carry the total power of the channel bandwidth,
|
||||
// which is higher than the per-bin spectral density shown on the
|
||||
// spectrum display by approximately 10·log10(decim_factor). Subtract
|
||||
// that so the meter and the spectrum peak agree.
|
||||
{
|
||||
let decim_correction = 10.0 * (self.decim_factor as f32).max(1.0).log10();
|
||||
if self.mode == RigMode::WFM {
|
||||
// WFM: smooth envelope power directly.
|
||||
// FM is constant-envelope, so I²+Q² is inherently stable
|
||||
@@ -769,7 +775,8 @@ impl ChannelDsp {
|
||||
let pwr = s.re * s.re + s.im * s.im;
|
||||
self.carrier_iq_i += alpha * (pwr - self.carrier_iq_i);
|
||||
}
|
||||
self.last_signal_db = 10.0 * self.carrier_iq_i.max(1e-12).log10();
|
||||
self.last_signal_db =
|
||||
10.0 * self.carrier_iq_i.max(1e-12).log10() - decim_correction;
|
||||
} else {
|
||||
// Other modes: peak IQ magnitude with EMA smoothing.
|
||||
const SIGNAL_EMA_ALPHA: f32 = 0.4;
|
||||
@@ -777,7 +784,7 @@ impl ChannelDsp {
|
||||
.iter()
|
||||
.map(|s| s.re * s.re + s.im * s.im)
|
||||
.fold(0.0_f32, f32::max);
|
||||
let peak_db = 10.0 * peak_power.max(1e-12).log10();
|
||||
let peak_db = 10.0 * peak_power.max(1e-12).log10() - decim_correction;
|
||||
self.last_signal_db += SIGNAL_EMA_ALPHA * (peak_db - self.last_signal_db);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -567,6 +567,19 @@ impl RigCat for SoapySdrRig {
|
||||
})
|
||||
}
|
||||
|
||||
fn get_signal_strength_db<'a>(
|
||||
&'a mut self,
|
||||
) -> Pin<Box<dyn std::future::Future<Output = Option<f64>> + Send + 'a>> {
|
||||
Box::pin(async move {
|
||||
self.pipeline
|
||||
.channel_dsps
|
||||
.read()
|
||||
.unwrap()
|
||||
.get(self.primary_channel_idx)
|
||||
.and_then(|dsp| dsp.lock().ok().map(|d| d.signal_db() as f64))
|
||||
})
|
||||
}
|
||||
|
||||
// -- TX / unsupported methods -------------------------------------------
|
||||
|
||||
fn set_ptt<'a>(
|
||||
|
||||
Reference in New Issue
Block a user