fix(tci): wide level rows, honest filter labels, and mute read both ways

Three things reported from the radio, all of them mine.

THE LEVELS. Two half-width sliders side by side left each of them a couple
of centimetres long, which is not enough to set 15% with. One level per
row now, full width, with the value typed in or stepped with ± — and in
the radio's own units, so the volume is dB and the squelch a dBm
threshold, matching what ExpertSDR3's own window shows.

THE FILTERS. The button said 250 and the radio was set to 300-550: 250 Hz
wide, but sitting where no CW note is. The edges are computed from the
width now, and a narrow filter is CENTRED ON THE CW NOTE — a 250 Hz filter
from 100 to 350 would put the note outside its own passband. A button also
lights on the WIDTH the radio reports rather than on an exact pair of
edges, so moving one edge on the radio no longer darkens every button.

MUTE. Read from one shape only, while this radio reports the other
('mute:0,false'), so the button showed the opposite of the truth. Both are
accepted now.

None of this should have reached main before somebody had a radio in front
of it.
This commit is contained in:
2026-08-26 20:54:28 +02:00
parent fc79be7c05
commit fbe01bf19d
4 changed files with 138 additions and 46 deletions
+9 -1
View File
@@ -120,7 +120,15 @@ func (t *TCI) handlePanel(name string, get func(int) string, args string) bool {
p.Volume = n
}
case "mute":
p.Mute = yes(get(1))
// Both shapes. This radio reports "mute:0,false" and the reference shows
// "mute:true" elsewhere — reading only one of them left the button
// showing the opposite of the truth, which is worse than showing
// nothing.
if get(1) != "" {
p.Mute = yes(get(1))
} else {
p.Mute = yes(get(0))
}
case "agc_mode":
if forRX0() {
p.AGC = strings.ToLower(strings.TrimSpace(get(1)))