Conversation
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>
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.
Increase the screen refresh rate