Skip to content

V1.3 rc#28

Merged
KI3P merged 8 commits into
mainfrom
V1.3RC
Jun 8, 2026
Merged

V1.3 rc#28
KI3P merged 8 commits into
mainfrom
V1.3RC

Conversation

@KI3P

@KI3P KI3P commented Jun 8, 2026

Copy link
Copy Markdown
Owner

Increase the screen refresh rate

KI3P and others added 8 commits May 30, 2026 13:51
The spectrum redraw was capped at ~11.7 fps (NCHUNKS=8): a frame draws one
chunk per loop iteration, and each iteration must process one audio block
within the ~10.67 ms real-time budget. Lowering NCHUNKS overran that budget
because the per-frame draw work (~57 ms) was too large.

Two changes free enough budget to run NCHUNKS=6 (15.6 fps) with the receive
chain unaffected (SNR 30.4 dB, no dropouts, verified on the bench):

- Generalize the chunk arithmetic to rounded column boundaries so any NCHUNKS
  (including non-divisors of 512 such as 6 or 7) sums to exactly 512 and the
  completion check still fires.
- Throttle Pass 2 (the audio-spectrum bars + DisplaydbM S-meter, ~13 ms/frame,
  a separate low-priority display element) to every AUDIO_SPECTRUM_DECIMATE-th
  frame. The waterfall colour computation is NOT throttled.

Tuned SPECTRUM_REFRESH_MS=60 to sit on the new 64 ms floor (R-sweep at NCHUNKS=6).

Tradeoff: the audio-spectrum display and S-meter update at ~7.8 fps (half the
main spectrum/waterfall rate). To revert: AUDIO_SPECTRUM_DECIMATE=1, NCHUNKS=8.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Throttling the waterfall scroll (the ~8 ms full-buffer BTE_move that shifts the
waterfall one line) to every other frame frees enough real-time budget to drop
NCHUNKS from 6 to 5, raising the spectrum trace from 15.6 to ~18.8 fps with the
receive chain still clean (SNR 29.5 dB, no dropouts).

- Replace the audio-only frame counter with a single per-frame counter
  (spectrumFrameCtr), incremented at sweep-start so both throttles see a stable
  per-frame value.
- Gate the waterfall scroll BTE + writeRect on WATERFALL_DECIMATE, phase-offset
  from the audio-spectrum throttle so the two heavy ops fall on alternate frames.
- NCHUNKS=5, SPECTRUM_REFRESH_MS=50 (sits on the new ~53 ms floor).

Tradeoffs: the waterfall and the audio-spectrum/S-meter both update at ~9.4 fps
(half the spectrum rate), and the spectrum trace cadence has more jitter
(~43-63 ms/frame) because throttled frames carry uneven load. To soften: raise
SPECTRUM_REFRESH_MS, or set NCHUNKS=6 / WATERFALL_DECIMATE=1 to revert to the
smooth 15.6 fps config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Accepts PJRC-format time packets (T<10-digit-unix-ts><\n|\r>) on Serial
and sets the Teensy hardware RTC plus the TimeLib software clock so
hour()/minute()/second() stay accurate. Lets a host PC keep the radio's
clock within +/- 1 second of UTC, which is required by WSJT-X.

Ported from W3RDL Phoenix 5-28-26. The Phoenix time pane already
restales every second in DrawDisplay, so the W3RDL MarkTimePaneStale()
helper was intentionally omitted.

Includes Loop_test.cpp coverage for valid packets (\n and \r), short
input, missing header, pre-epoch sanity rejection, overrun, and the
empty-buffer no-op path. Required adding Teensy3Clock.wasSet/lastSet
to the Arduino mock and a no-op setTime() to the TimeLib mock.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Accepts PJRC-format time packets (T<10-digit-unix-ts><\n|\r>) on Serial
and sets the Teensy hardware RTC plus the TimeLib software clock so
hour()/minute()/second() stay accurate. Lets a host PC keep the radio's
clock within +/- 1 second of UTC, which is required by WSJT-X.

Ported from W3RDL Phoenix 5-28-26. The Phoenix time pane already
restales every second in DrawDisplay, so the W3RDL MarkTimePaneStale()
helper was intentionally omitted.
The convolution filter's overlap-add history buffers (last_sample_buffer_L/R)
are declared static DMAMEM, which the Teensy 4.x does not zero-initialize at
cold boot (only .bss in DTCM is cleared at startup). After a power cycle they
contained random bit patterns - some NaN/Inf - that were fed into the
convolution FFT on the first frame and then latched permanently into the noise
reduction feedback state, collapsing the audio until NR was toggled off. A
re-flash is a warm reset that preserves OCRAM, which is why it only reproduced
after a cold power cycle.

Two fixes:
1. InitializeFilters() now clears last_sample_buffer_L/R at boot.
2. The NR algorithms are made NaN/Inf tolerant so a transient bad sample can
   no longer latch permanently:
   - Kim1_NR: gain clamp now uses !(NR_G > 0.0), catching NaN/Inf before it
     poisons the NR_Gts time-smoothing feedback.
   - SpectralNoiseReduction: sanitize NR_X at its entry point and guard the
     self-referential xt noise estimate.
   - Xanr: sanitize the input sample before it reaches the adaptive weights.

Adds NoiseReduction_test.cpp (target all_NoiseReduction_tests) with regression
tests covering the overlap-buffer clearing and transient-NaN recovery for all
three NR algorithms.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Update SignalProcessing.ReadDataIntoBuffers and
TransmitChain.TransmitReceiveProcessingPSDContainsCorrectTone to the
post-04b277a I/Q convention (I<-L, Q<-R). The image-formation fix
swapped the channel assignment in ReadIQInputBuffer; the tests still
encoded the old I=R/Q=L convention, so the direct comparison and the
PSD tone bin (mirrored to the lower sideband) were wrong.

Fix the flaky Radio.RadioStateRunThrough keyer test. The keyer state
machine counts DO events as milliseconds, but the timer thread fired
"tick then sleep_for(1ms)", which sleeps >=1ms and drifts behind the
wall-clock millis() the test checks against. Over a dit/dah the drift
exceeded the grace windows, so the test passed in isolation but failed
in the full suite. Lock the DO clock to the wall clock (fire one DO per
elapsed wall-ms), and make the two KEYER_WAIT upper bounds exclusive at
the WAIT->RECEIVE transition to match the now-exact timing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@KI3P KI3P merged commit e58ff10 into main Jun 8, 2026
1 check passed
@KI3P KI3P deleted the V1.3RC branch June 8, 2026 10:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant