Skip to content

Struct burst_capture_state_t

ClassList > burst_capture_state_t

BurstCapture state. More...

  • #include <burst_capture_core.h>

Public Attributes

Type Name
burst_acq_state_t * acq
size_t acq_blob_max
uint8_t * acq_code
size_t acq_code_len
int backed
size_t burst_len
double chip_rate
size_t chunk_max
double cn0_dbhz_est
size_t code_period
float _Complex * corr_buf
size_t corr_len
burst_capture_detection_t * det
size_t det_cap
size_t det_len
double doppler_hz_est
double doppler_res_hz
uint64_t dropped
burst_capture_event_t * ev
size_t ev_cap
size_t ev_len
dp_f32_t * hist
size_t k_hi
size_t k_lo
size_t min_gap
uint64_t n_bursts
size_t pending
uint64_t preamble_start
burst_capture_pending_t * q
size_t q_cap
size_t q_head
int recovered
float * ref_sign
double refine_margin
size_t refine_span
uint8_t * released
size_t reps
size_t retain_span
uint64_t samples_fed
size_t spc
uint64_t suppress_base
uint64_t suppress_until
int underpowered
float _Complex * win
size_t win_cap

Detailed Description

Allocate with burst_capture_create().

Public Attributes Documentation

variable acq

burst_acq_state_t* burst_capture_state_t::acq;

Search stage, certified separately.


variable acq_blob_max

size_t burst_capture_state_t::acq_blob_max;

Fixed upper bound on the acquisition child's blob. state_bytes() must be a pure function of CONFIGURATION jm's binding compares an incoming blob's length against it yet both the retained look-back and acq's own unconsumed ring vary with the stream. Both are therefore written into fixed-size regions with a length prefix.


variable acq_code

uint8_t* burst_capture_state_t::acq_code;

Preamble code, owned copy.


variable acq_code_len

size_t burst_capture_state_t::acq_code_len;

Preamble code length, chips.


variable backed

int burst_capture_state_t::backed;

Non-zero when the ring's pages are a FILE's. Fixed at create(), so state_bytes() stays a pure function of configuration a backed blob and an in-RAM one are different sizes on purpose, and neither restores into the other.


variable burst_len

size_t burst_capture_state_t::burst_len;

Samples in one emitted window. Acquisition has no notion of this acq_create_burst() takes search parameters only which is exactly why it is a parameter HERE: for a capture, the burst length is what gets captured.


variable chip_rate

double burst_capture_state_t::chip_rate;

Chip rate, Hz.


variable chunk_max

size_t burst_capture_state_t::chunk_max;

Largest slice of one push processed at a time, so any block size is accepted without the ring overrunning its own retention.


variable cn0_dbhz_est

double burst_capture_state_t::cn0_dbhz_est;

C/N0 lower bound, dB-Hz (saturating).


variable code_period

size_t burst_capture_state_t::code_period;

One preamble repetition, in SAMPLES. The modulus acq's code_phase is a residue of, so every epoch ambiguity in this object is stated against it.


variable corr_buf

float _Complex* burst_capture_state_t::corr_buf;

Per-offset code-period correlations, reused across the candidate sweep so the sliding correlation is computed once and the non-coherent combine just indexes it.


variable corr_len

size_t burst_capture_state_t::corr_len;

Entries in corr_buf.


variable det

burst_capture_detection_t* burst_capture_state_t::det;

Raw hits of the LAST push what the SEARCH found, before the claim rule and the suppression window.


variable det_cap

size_t burst_capture_state_t::det_cap;

Allocated records.


variable det_len

size_t burst_capture_state_t::det_len;

Records the last push wrote.


variable doppler_hz_est

double burst_capture_state_t::doppler_hz_est;

Signed coarse Doppler, Hz.


variable doppler_res_hz

double burst_capture_state_t::doppler_res_hz;

Width of that estimate.


variable dropped

uint64_t burst_capture_state_t::dropped;

Samples the ring refused. A LOST BURST each, not a statistic lifetime, survives reset().


variable ev

burst_capture_event_t* burst_capture_state_t::ev;

One record per window returned.


variable ev_cap

size_t burst_capture_state_t::ev_cap;

Allocated records.


variable ev_len

size_t burst_capture_state_t::ev_len;

Records the last push() wrote.


variable hist

dp_f32_t* burst_capture_state_t::hist;

History ring. Double-mapped, so a window that spans the wrap is ONE contiguous pointer. This object keeps its own rather than borrowing acq's, which consumes every frame it processes and has therefore released what is still needed.


variable k_hi

size_t burst_capture_state_t::k_hi;

...and AFTER: reps. The detecting frame can start before the preamble, so the anchor can be up to coherent_bins - 1 periods early. It was 2, and at reps=10 refine returned one period early with a resolved-looking margin (doppler#1181).


variable k_lo

size_t burst_capture_state_t::k_lo;

Whole code periods searched BEFORE the anchor: 3*reps + 2, the detection lag's bound.


variable min_gap

size_t burst_capture_state_t::min_gap;

Dead air a caller must leave BETWEEN bursts, in samples edge to edge, not start to start.

DERIVED, and the derivation is the point. A detection's anchor is the code epoch of whichever frame detected, and acquisition's framing is not aligned to the preamble, so the last frame that can detect sits up to reps * code_period past the true start (the detection lag, docs/design/dsss-burst-receiver.md ยง7.1). CLAIM merges two anchors closer than refine_span, so with the first burst detected LATE and the second EARLY the pair survives only when

gap >= refine_span + reps*P - burst_len

ZERO is a real answer a burst longer than refine_span + reps*P needs no gap for the claim rule's sake. It does not mean zero is wise: a zero gap is a continuous stream rather than a burst link (the design's own non-goal), and it measures 88% at a geometry where this reads 0.

The prose this replaces said max(0, refine_span - burst_len) and was short by the whole detection-lag term 32 samples against 528 at the C suite's geometry (doppler#1172).


variable n_bursts

uint64_t burst_capture_state_t::n_bursts;

Windows emitted, lifetime.


variable pending

size_t burst_capture_state_t::pending;

Detections held because their burst window has NOT fully arrived the caller-facing "there is not enough data yet" read-back. push() deliberately emits nothing for these: a window is returned when it is complete, not when it is guessed at. What it exists for is the other end a caller closing a file while this is non-zero is discarding a burst that would have been captured.


variable preamble_start

uint64_t burst_capture_state_t::preamble_start;

Stream-absolute preamble start. Never late.


variable q

burst_capture_pending_t* burst_capture_state_t::q;

Detections, oldest first; q_cap long.


variable q_cap

size_t burst_capture_state_t::q_cap;

DERIVED, not a constant. Entries sit at least refine_span apart within retain_span of the head, so the count scales with burst_len/refine_span about 1 at a short-burst test geometry but 5.5x at a real link. A fixed 8 silently dropped the hit AND the rest of the batch on anything else.


variable q_head

size_t burst_capture_state_t::q_head;

Index of the oldest entry.


variable recovered

int burst_capture_state_t::recovered;

Non-zero when create() found the backing file already holding a ring of exactly this geometry, so its samples ARE the look-back. Zero when the file was created or resized, which zeroes it and then a blob claiming retained history has nothing to reach back into, which set_state() refuses rather than resuming into silence.


variable ref_sign

float* burst_capture_state_t::ref_sign;

One code period of +-1 chip signs, spc-expanded. Real, so the per-period correlation is a signed sum rather than a complex multiply.


variable refine_margin

double burst_capture_state_t::refine_margin;

Winning preamble correlation over its nearest whole-period competitor. Near 1 means the period was NOT resolved.


variable refine_span

size_t burst_capture_state_t::refine_span;

Candidate offsets searched, in samples: (k_lo + k_hi + reps) * code_period. Read it rather than restating the formula the design doc's own prose for it was 2.4x low at reps=5 until it was measured.

The merge test compares two resolved code epochs burst START against burst START so it bounds start-to-start separation, NOT the dead air between bursts (doppler#1085). The gap actually required is NOT max(0, refine_span - burst_len) either: swept, a pair needs about two code periods of dead air, against the 32 samples that formula gives at the test geometry (doppler#1172).


variable released

uint8_t* burst_capture_state_t::released;

Per row of ev: the consumer said "not a burst". Scratch, like the rows.


variable reps

size_t burst_capture_state_t::reps;

Preamble code repetitions.


variable retain_span

size_t burst_capture_state_t::retain_span;

Samples that must stay reachable: refine span + one whole burst. Also the caller-facing minimum TRAILING context a burst closer than this to the end of what has been pushed is not emitted until more samples arrive.


variable samples_fed

uint64_t burst_capture_state_t::samples_fed;

Stream position: total samples ever pushed. What makes an epoch stream-ABSOLUTE, and the reason preamble_start is a quantity only this object can compute.


variable spc

size_t burst_capture_state_t::spc;

Samples per chip.


variable suppress_base

uint64_t burst_capture_state_t::suppress_base;

suppress_until as the last push() began: what EARLIER pushes' windows own, which a release() of this push's window must not give back.


variable suppress_until

uint64_t burst_capture_state_t::suppress_until;

Detections below this stream position fall inside a burst already EMITTED, so they are the payload firing against the acquisition code rather than new bursts. Armed when a window is emitted refine resolved a start here and this object handed out the whole span, which is the fact it owns. Arming it on every DETECTION instead let one spurious hit blind the search for a whole burst and discard the next real one (doppler#1004). Coalescing the several frames of ONE preamble is a separate job, done by refine_span proximity plus a greatest-of tie-break.


variable underpowered

int burst_capture_state_t::underpowered;

The search cannot meet the requested pd at this cn0_dbhz and geometry. It still builds a best-effort grid, so the symptom is bursts that are never captured rather than an error.


variable win

float _Complex* burst_capture_state_t::win;

Emitted windows, burst_len apart.


variable win_cap

size_t burst_capture_state_t::win_cap;

Allocated samples.



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