modem: show the waterfall while transmitting - #175
Open
rafael2k wants to merge 1 commit into
Open
Conversation
Every radio shows you your own signal on transmit; mercury froze the display
on key-up, because the spectrum slot was fed only from the capture path.
Feed it from the transmitted burst as well. Same slot, same lock, same
sequence counter the RX path uses, so the publisher thread and the on-the-wire
spectrum frame need no change whatsoever. Only one writer is ever active --
the link is half duplex, so RX decode and TX modulation never overlap -- and
the FFT runs inline under the lock exactly as it already does for RX.
Two details that decide whether this looks right:
- Publishing once per burst would paint a single line every 3.7 s on
DATAC16. Instead it publishes from inside the drain loop that
send_modulated_data already runs while the burst plays out, indexed by
elapsed playout. The ring is filled far faster than it drains, so drain
progress -- not write progress -- is what paces the display.
- Samples are taken at modem rate, which is what g_spectrum_sample_rate
already reports, so the frequency axis matches RX and the display does not
jump scale on key-up.
Gated by g_spectrum_enabled, the switch the RX FFT already uses, so the UI
checkbox and -W turn off both directions at once: one waterfall control, one
setter. Unlike RX there is no second consumer to keep it alive -- the
channel-busy detector shares the RX FFT, but occupancy means nothing while we
are the ones occupying the channel.
The stats struct is opened lazily and TX now gets there first -- mercury sends
CALL before it has decoded anything -- so the open is done here too. Omitting
it ran the first burst of every connect over an unopened MODEM_STATS, which
hung the connect; caught by the integration suite, which is the only gate that
transmits.
Gate: unit suite green; integration 245.1 s against a 245-246 s baseline;
mercury and the embedded fyne UI both build, go vet clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every radio shows you your own signal on transmit — an IC-7300 or FT-710 does.
Mercury froze the display on key-up, because the spectrum slot was fed only
from the capture path.
Approach
Feed the same slot from the transmitted burst. Same slot, same lock, same
sequence counter as RX, so the publisher thread and the on-the-wire spectrum
frame need no change at all. Only one writer is ever active — the link is half
duplex, so RX decode and TX modulation never overlap — and the FFT runs inline
under the lock exactly as it already does for RX.
Two details decide whether this actually looks like a waterfall:
on DATAC16. Instead it publishes from inside the drain loop that
send_modulated_dataalready runs while the burst plays out, indexed byelapsed playout. The ring is filled far faster than it drains, so drain
progress — not write progress — is what paces the display.
g_spectrum_sample_ratealready reports, so the axis matches RX and thedisplay does not jump scale on key-up.
Honours the existing waterfall switch: with the UI waterfall off there is no
publisher thread, so the modem skips the work rather than computing frames
nobody consumes.
The bug worth recording
g_spectrum_statsis opened lazily, and TX now gets there first — mercurysends CALL before it has decoded anything. Omitting
modem_stats_open()ranthe first burst of every connect over an unopened
MODEM_STATSand hung theconnect at ~10 s.
Only the integration suite caught it. Build was clean and the unit suite
passed, because neither transmits. Worth remembering for anything touching the
TX path.
Two theories I chased first were both wrong and are recorded here so nobody
re-runs them: it is not a lock-order inversion (the instance lock is released
at
modem.c:1116, well before the drain loop at 1160+, so the publish holds nomodem locks), and "don't compute an FFT under the spectrum lock" is advice the
RX path already ignores successfully at
modem.c:2229.Gate
debugmsgsave2; no mercury frames, 0 lock-order inversionsCaveat on TSan: that run is
-x nullidle RX, so it does not exercise the newTX path. The ASan+UBSan CI job runs an integration session, which does.
Not yet verified visually — the waterfall should be watched on a real UI during
a transmit to confirm it scrolls and the scale is stable across key-up.