Struct ratesync_loop_t¶
The symbol-timing loop, independent of what feeds it. More...
#include <ratesync_core.h>
Public Attributes¶
| Type | Name |
|---|---|
| size_t | avgs |
| double | bn |
| double | ctrl |
| int | have_prev |
| double | last_error |
| loop_filter_state_t | lf |
| lockdet_state_t | lock |
| size_t | lock_count |
| double | lock_stat |
| double | lock_sum |
| size_t | m |
| size_t | out_count |
| float _Complex | prev_on |
| size_t | prime_left |
| size_t | prime_taps |
| double | rate_est |
| float _Complex | ring |
| size_t | ring_n |
| double | sps |
| int | ted |
| double | ted_scale |
| const resamp_state_t * | term |
| double | term_rate |
| ratesync_tlm_t | tlm |
| double | zeta |
Detailed Description¶
Everything RateSync does after the cascade emits an output: the strobe ring, the TED, the PI loop, the lock detector and the telemetry. It holds no filter and no cascade — it consumes a stream of terminal-stage outputs and produces a per-input rate deviation (ctrl) for whoever owns the accumulator those outputs came from.
That split is what lets a receiver reuse this loop verbatim. RateSync owns a RateConverter and steers it directly; MpskReceiver owns a Ddc/Ddcr (mix + the same cascade) and steers the same accumulator through the DDC's rate_ctrl port. Both drive one implementation of the timing loop, so a fix to the TED or the normaliser reaches both — the two are not peers that can drift apart.
The loop must be told the geometry of the accumulator it is steering (ratesync_loop_set_cascade()): the terminal stage's own rate, because that is the scale ctrl is referenced to, and the terminal bank's tap count, because that is how many outputs are delay-line fill rather than signal.
Public Attributes Documentation¶
variable avgs¶
non-coherent block size (looks/decision).
variable bn¶
loop noise bandwidth (retained).
variable ctrl¶
per-input rate deviation now applied.
variable have_prev¶
a previous on-time strobe exists.
variable last_error¶
last normalised TED error.
variable lf¶
2nd-order timing PI loop.
variable lock¶
declare/drop rule stepped on lock_stat.
variable lock_count¶
looks accumulated in the current block.
variable lock_stat¶
last block-averaged lock_signal.
variable lock_sum¶
running sum over the current avgs block.
variable m¶
terminal outputs per symbol (>= 2, even).
variable out_count¶
terminal outputs seen (mod m: strobe phase).
variable prev_on¶
previous on-time strobe.
variable prime_left¶
strobes still to discard (cascade filling).
variable prime_taps¶
terminal bank taps; sets the prime length.
variable rate_est¶
smoothed tracked samples/symbol.
variable ring¶
Newest-first ring of the last m/2+1 outputs: the transition gate is m/2 outputs behind the on-time strobe, so it is simply the element at index m/2. (Written without brackets on purpose: mkdoxy renders this comment into markdown, where a bare name[i] parses as a link reference and fails the strict docs build.)
variable ring_n¶
variable sps¶
nominal samples per symbol (any double).
variable ted¶
RATESYNC_TED_GARDNER / _DTTL.
variable ted_scale¶
Reciprocal of the detector's own slope against this pulse (symsync_ted_slope()), computed once by ratesync_loop_bind_cascade(). The hot path MULTIPLIES by it: a divide, and the running power estimate it would have divided by, are both construct-time work masquerading as per-symbol work.
variable term¶
The terminal stage itself, borrowed for TELEMETRY ONLY: the loop steers this accumulator but does not own it, and mu — the sampling phase the steering produces — is otherwise unobservable from outside the cascade. NULL when the owner bound the geometry by hand (ratesync_loop_set_cascade()) rather than from a cascade; the probe then reports 0. Never dereferenced on the hot path.
variable term_rate¶
terminal stage's own rate; the ctrl scale.
variable tlm¶
live telemetry attachment; zeroed in blobs.
variable zeta¶
damping factor (retained).
The documentation for this class was generated from the following file native/inc/ratesync/ratesync_core.h