Problem
While transmitting, SmartMTR exposes only one TX meter choice — Mic Level — or nothing (it stays on the RX signal scale). Operators routinely want to watch SWR, forward power, or compression during a transmission. SmartSDR's meter selector offers these as standard TX meters, so adding them brings SmartMTR toward parity rather than expanding scope.
The underlying data already exists in src/models/MeterModel.h — fwdPower()/fwdPowerInstant() (watts), swr(), and compLevel()/compPeak() (dB). No protocol work.
Proposal
Extend the TX meter selection from a single option to a set:
- None — (unchanged — stay on RX signal)
- Mic Level — (unchanged)
- SWR — (new)
- Power — (new — forward power, watts)
- Compression — (new)
Each new meter is one MeterKind value plus one buildXConfig() + switch case in meterConfig() (src/gui/SmartMtrConfig.cpp / src/gui/SmartMtrConfig.h). SmartMtrWidget is render-only — no widget changes. Selection round-trips through DisplaySettings::TxMeter (src/gui/DisplaySettings.h) and its txMeterToken()/txMeter() pair, whose deserializer already falls back to None on unknown tokens — so old configs and downgrades are safe by construction.
Cross-platform impact
Identical on all supported targets (Linux, macOS, Windows, Raspberry Pi 5). Pure shared-GUI render-config + settings + wiring change; no platform-specific code paths.
Alternatives considered
- Auto-cycle through all TX meters — rejected: operators want a fixed, predictable meter during TX.
- Keep Mic Level only — rejected: doesn't address the operating need.
- Constant Power full-scale (0–100 W) — rejected: would peg on Aurora / AU-520 (500 W exciter, 600 W integrated PA) and on amplifier setups. Power scale must be radio-aware (see below).
Implementation scope
(Updated per @aethersdr-agent review — corrected routing site and the VFO-feed plumbing the first draft understated; Power scale made radio-aware after the Aurora question.)
- Meter kind + scale — add enumerators to
MeterKind (src/gui/SmartMtrConfig.h) and a buildXConfig() + case in meterConfig() (src/gui/SmartMtrConfig.cpp).
- Setting — add enumerators + token cases to
DisplaySettings::TxMeter and txMeterToken() (src/gui/DisplaySettings.h). Backward-compatible (unknown token → None).
- Selector UI — three more
addItem(tr(...), int(DS::TxMeter::X)) lines next to the existing None/Mic Level entries in VfoWidget's TX-meter combo (m_txMeterCmb).
- Routing — in
VfoWidget::pushSmartMtrInput() (src/gui/VfoWidget.cpp), extend the per-TxMeter branch to set MeterInput kind/value/min/max for each new meter. (MeterViewController only caches/persists the selection — it is not the routing site.)
- Feed the values to the VFO —
VfoWidget is currently fed only mic level (setMicLevel()/m_micDbfs):
- add
VfoWidget setters + members for forward power, SWR, and compression (mirroring setMicLevel/m_micDbfs);
- in
src/gui/MainWindow_Wiring.cpp, wire MeterModel::txMetersChanged(fwdPower, swr) → VFO (today it reaches only SMeterWidget), and capture the compression args already carried by the micMetersChanged lambda (currently discarded).
Scale-range guidance
- SWR — 1.0 → ~3.0, nonlinear, red/high zone above ~2.0; ticks at 1.0 / 1.5 / 2.0 / 3.0. Fixed range; no radio peak stat needed.
- Power — forward watts, linear, radio-aware full-scale keyed off the radio's rated power, reusing the existing pattern: barefoot 0–120 W / Aurora (AU-520) 0–600 W (red > 500 W) / amplifier classes as those gauges already handle them. Rated power comes from
TransmitModel::maxPowerLevel() (fed from the radio's max_internal_pa_power, src/models/RadioModel.cpp ~5310), the same source TxApplet::setPowerScale() / SMeterWidget / TunerApplet use today. Use fwdPowerInstant() for the peak marker (as mic does). Implication: unlike the other (static) MeterConfigs, the Power config needs the rated full-scale injected at push time rather than baked into the registry entry.
- Compression — 0–25 dB linear (the documented span of
m_compPeak). Fixed range.
Sequencing
Scope is contained. Suggest one small PR per meter (SWR first — cleanest data path; Power last — it carries the radio-aware-scale wrinkle) or one combined PR. Implementation gated on approval here.
Problem
While transmitting, SmartMTR exposes only one TX meter choice — Mic Level — or nothing (it stays on the RX signal scale). Operators routinely want to watch SWR, forward power, or compression during a transmission. SmartSDR's meter selector offers these as standard TX meters, so adding them brings SmartMTR toward parity rather than expanding scope.
The underlying data already exists in
src/models/MeterModel.h—fwdPower()/fwdPowerInstant()(watts),swr(), andcompLevel()/compPeak()(dB). No protocol work.Proposal
Extend the TX meter selection from a single option to a set:
Each new meter is one
MeterKindvalue plus onebuildXConfig()+switchcase inmeterConfig()(src/gui/SmartMtrConfig.cpp/src/gui/SmartMtrConfig.h).SmartMtrWidgetis render-only — no widget changes. Selection round-trips throughDisplaySettings::TxMeter(src/gui/DisplaySettings.h) and itstxMeterToken()/txMeter()pair, whose deserializer already falls back toNoneon unknown tokens — so old configs and downgrades are safe by construction.Cross-platform impact
Identical on all supported targets (Linux, macOS, Windows, Raspberry Pi 5). Pure shared-GUI render-config + settings + wiring change; no platform-specific code paths.
Alternatives considered
Implementation scope
(Updated per @aethersdr-agent review — corrected routing site and the VFO-feed plumbing the first draft understated; Power scale made radio-aware after the Aurora question.)
MeterKind(src/gui/SmartMtrConfig.h) and abuildXConfig()+caseinmeterConfig()(src/gui/SmartMtrConfig.cpp).DisplaySettings::TxMeterandtxMeterToken()(src/gui/DisplaySettings.h). Backward-compatible (unknown token →None).addItem(tr(...), int(DS::TxMeter::X))lines next to the existing None/Mic Level entries inVfoWidget's TX-meter combo (m_txMeterCmb).VfoWidget::pushSmartMtrInput()(src/gui/VfoWidget.cpp), extend the per-TxMeterbranch to setMeterInputkind/value/min/max for each new meter. (MeterViewControlleronly caches/persists the selection — it is not the routing site.)VfoWidgetis currently fed only mic level (setMicLevel()/m_micDbfs):VfoWidgetsetters + members for forward power, SWR, and compression (mirroringsetMicLevel/m_micDbfs);src/gui/MainWindow_Wiring.cpp, wireMeterModel::txMetersChanged(fwdPower, swr)→ VFO (today it reaches onlySMeterWidget), and capture the compression args already carried by themicMetersChangedlambda (currently discarded).Scale-range guidance
TransmitModel::maxPowerLevel()(fed from the radio'smax_internal_pa_power,src/models/RadioModel.cpp~5310), the same sourceTxApplet::setPowerScale()/SMeterWidget/TunerAppletuse today. UsefwdPowerInstant()for the peak marker (as mic does). Implication: unlike the other (static)MeterConfigs, the Power config needs the rated full-scale injected at push time rather than baked into the registry entry.m_compPeak). Fixed range.Sequencing
Scope is contained. Suggest one small PR per meter (SWR first — cleanest data path; Power last — it carries the radio-aware-scale wrinkle) or one combined PR. Implementation gated on approval here.