Skip to content

Struct ratesync_loop_t

ClassList > 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

size_t ratesync_loop_t::avgs;

non-coherent block size (looks/decision).


variable bn

double ratesync_loop_t::bn;

loop noise bandwidth (retained).


variable ctrl

double ratesync_loop_t::ctrl;

per-input rate deviation now applied.


variable have_prev

int ratesync_loop_t::have_prev;

a previous on-time strobe exists.


variable last_error

double ratesync_loop_t::last_error;

last normalised TED error.


variable lf

loop_filter_state_t ratesync_loop_t::lf;

2nd-order timing PI loop.


variable lock

lockdet_state_t ratesync_loop_t::lock;

declare/drop rule stepped on lock_stat.


variable lock_count

size_t ratesync_loop_t::lock_count;

looks accumulated in the current block.


variable lock_stat

double ratesync_loop_t::lock_stat;

last block-averaged lock_signal.


variable lock_sum

double ratesync_loop_t::lock_sum;

running sum over the current avgs block.


variable m

size_t ratesync_loop_t::m;

terminal outputs per symbol (>= 2, even).


variable out_count

size_t ratesync_loop_t::out_count;

terminal outputs seen (mod m: strobe phase).


variable prev_on

float _Complex ratesync_loop_t::prev_on;

previous on-time strobe.


variable prime_left

size_t ratesync_loop_t::prime_left;

strobes still to discard (cascade filling).


variable prime_taps

size_t ratesync_loop_t::prime_taps;

terminal bank taps; sets the prime length.


variable rate_est

double ratesync_loop_t::rate_est;

smoothed tracked samples/symbol.


variable ring

float _Complex ratesync_loop_t::ring[RATESYNC_MAX_M/2+1];

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

size_t ratesync_loop_t::ring_n;

variable sps

double ratesync_loop_t::sps;

nominal samples per symbol (any double).


variable ted

int ratesync_loop_t::ted;

RATESYNC_TED_GARDNER / _DTTL.


variable ted_scale

double ratesync_loop_t::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

const resamp_state_t* ratesync_loop_t::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

double ratesync_loop_t::term_rate;

terminal stage's own rate; the ctrl scale.


variable tlm

ratesync_tlm_t ratesync_loop_t::tlm;

live telemetry attachment; zeroed in blobs.


variable zeta

double ratesync_loop_t::zeta;

damping factor (retained).



The documentation for this class was generated from the following file native/inc/ratesync/ratesync_core.h