File burst_capture_core.h¶
File List > burst_capture > burst_capture_core.h
Go to the documentation of this file
#ifndef DP_BURST_CAPTURE_CORE_H
#define DP_BURST_CAPTURE_CORE_H
#include "doppler/clib_common.h"
#include "doppler/jm_perf.h"
#include "doppler/buffer/buffer.h"
#include "doppler/dp_state.h"
#include "doppler/burst_acq/burst_acq_core.h"
#include "doppler/acq/acq_core.h"
#include "doppler/corr2d/corr2d_core.h"
#include "doppler/fft2d/fft2d_core.h"
#include "doppler/fft/fft_core.h"
#include "doppler/detection/detection_core.h"
#include "doppler/pn/pn_core.h"
#include "doppler/cvt/cvt_core.h"
#define BURST_CAPTURE_HITS 16u
#define BURST_CAPTURE_REFINE_INTERP 4u
#define BURST_CAPTURE_MAX_PHASES 4u
#define BURST_CAPTURE_EDGE_TWINS 4u
#define BURST_CAPTURE_STATE_MAGIC DP_FOURCC ('B', 'C', 'A', 'P')
#define BURST_CAPTURE_STATE_VERSION 6u
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint64_t preamble_start;
double doppler_hz_est;
double doppler_res_hz;
double cn0_dbhz_est;
double doppler_rate_hz_s;
} burst_capture_event_t;
typedef struct
{
uint64_t epoch;
double doppler_hz;
double cn0_dbhz;
double test_stat;
double peak_mag;
} burst_capture_detection_t;
typedef struct
{
uint64_t anchor;
uint64_t start;
double doppler_hz;
double cn0_dbhz;
double peak_mag;
uint32_t phase[BURST_CAPTURE_MAX_PHASES];
uint32_t n_phase;
int refined;
int shadowed;
double doppler_rate_hz_s;
} burst_capture_pending_t;
typedef struct
{
/* ── Configuration, copied at create() ──────────────────────────────── */
size_t reps;
/* ── Derived geometry ───────────────────────────────────────────────── */
size_t code_period;
size_t burst_len;
/* ── The composed child ─────────────────────────────────────────────── */
dp_burst_acq_state_t *acq;
/* ── Look-back (docs/design/dsss-burst-receiver.md §7.1) ────────────── */
dp_f32_t *hist;
uint64_t samples_fed;
/* ── The event describing the most recent window emitted ────────────── */
uint64_t preamble_start;
double doppler_hz_est;
double doppler_res_hz;
double cn0_dbhz_est;
double doppler_rate_hz_s;
/* ── Refine scratch (docs/design/dsss-burst-receiver.md §3.4) ───────── */
double _Complex *cell_buf;
double *cell_f;
double _Complex *rate_ph;
size_t rate_ph_n;
size_t max_cells;
size_t refine_span;
size_t corr_len;
size_t min_gap;
size_t retain_span;
size_t chunk_max;
size_t k_lo;
size_t k_hi;
/* ── Detections in flight ────────────────────────────────────────────
* In ANCHOR ORDER, which set_state() checks, and emitted in that order:
* an unshadowed detection whose window has arrived is emitted before
* push() returns unless one queued ahead of it has not arrived, and one a
* release() gave back after the push is emitted by the next push first. A
* detection whose history is gone is swept, counted in `dropped` unless
* it was shadowed. That is what bounds retention (see the trim rule in the
* implementation). */
burst_capture_pending_t *q;
size_t q_cap;
size_t q_head;
size_t pending;
/* ── The windows of the LAST push ────────────────────────────────────
* Scratch, deliberately NOT serialized: it describes the most recent
* push() only, so keeping it out of the blob is what lets state_bytes()
* stay a pure function of configuration.
*
* The windows are COPIED here rather than left in the ring. A window in
* the ring is a borrow whose lifetime the retention rule would have to
* extend across the whole call, and one push can complete several bursts
* -- so the ring would have to hold every one of them at once, which its
* derived capacity does not promise. The cost is one memcpy per BURST,
* not per sample, which is a different order of magnitude from the copy
* §6.1 weighs (that one is the whole stream). It is also what lets a C
* consumer borrow a window through dp_burst_capture_window() and hand it
* onward with no further copy. */
burst_capture_detection_t *det;
size_t det_cap;
size_t det_len;
float _Complex *win;
size_t win_cap;
burst_capture_event_t *ev;
size_t ev_cap;
size_t ev_len;
uint8_t *released;
uint64_t suppress_until;
uint64_t horizon;
uint64_t suppress_base;
size_t acq_blob_max;
/* ── Persistence (docs/design/burst-capture.md §9) ───────────────────── */
int backed;
int recovered;
/* ── Diagnostics ────────────────────────────────────────────────────
* Mirrored from the engine at create() rather than read through it on
* demand, because jm's declared warning needs a bare field on THIS
* struct; the sibling BurstAcquisition carries its own `underpowered`
* field for the same reason. */
int underpowered;
/* ── Bookkeeping ────────────────────────────────────────────────────── */
uint64_t dropped;
uint64_t n_bursts;
/*<<property_struct_fields>>*/
} dp_burst_capture_state_t;
dp_burst_capture_state_t *dp_burst_capture_create (
const float _Complex *preamble, size_t preamble_len, size_t burst_len,
size_t reps,
double fs, double cn0_dbhz, double doppler_uncertainty, double pfa,
double pd, int noise_mode, double doppler_rate, size_t rate_hypotheses);
dp_burst_capture_state_t *dp_burst_capture_create_backed (
const char *path, const float _Complex *preamble, size_t preamble_len,
size_t burst_len, size_t reps, double fs, double cn0_dbhz,
double doppler_uncertainty, double pfa, double pd, int noise_mode,
double doppler_rate, size_t rate_hypotheses);
void dp_burst_capture_destroy (dp_burst_capture_state_t *state);
void dp_burst_capture_reset (dp_burst_capture_state_t *state);
size_t dp_burst_capture_push_max_out (dp_burst_capture_state_t *state,
size_t x_len);
size_t dp_burst_capture_push (dp_burst_capture_state_t *state,
const float _Complex *x, size_t x_len,
float _Complex *out, size_t max_out);
size_t dp_burst_capture_detections_max_out (dp_burst_capture_state_t *state,
size_t n);
size_t dp_burst_capture_detections (dp_burst_capture_state_t *state, size_t n,
burst_capture_detection_t *out,
size_t max_out);
size_t dp_burst_capture_events_max_out (dp_burst_capture_state_t *state, size_t n);
size_t dp_burst_capture_events (dp_burst_capture_state_t *state, size_t n,
burst_capture_event_t *out, size_t max_out);
size_t dp_burst_capture_ready (const dp_burst_capture_state_t *state);
const float _Complex *dp_burst_capture_window (const dp_burst_capture_state_t *state,
size_t i);
const burst_capture_event_t *
dp_burst_capture_event_at (const dp_burst_capture_state_t *state, size_t i);
int dp_burst_capture_release (dp_burst_capture_state_t *state, size_t i);
int dp_burst_capture_configure_search_raw (dp_burst_capture_state_t *state,
size_t doppler_bins,
size_t n_noncoh);
/* ── Serializable state — the elastic / pure-transducer face ──────────── */
/* ── The search this capture will do, as numbers ──────────────────────
*
* A capture is only as good as the search under it, and a caller sizing a
* link needs to see that search rather than infer it. These forward the
* engine's own figures: what a detection must clear, how deep the sizer
* went, and how wide in Doppler and code phase it will look.
*
* They are read-backs, not knobs -- every one is derived at create() from
* the parameters above, and `configure_search_raw()` is the one call that
* moves them. */
size_t dp_burst_capture_get_min_gap (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_eta (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_eta_nc (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_straddle_loss (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_pd_predicted (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_pd_burst (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_psl_db (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_doppler_rate (const dp_burst_capture_state_t *state);
size_t dp_burst_capture_get_rate_hypotheses (
const dp_burst_capture_state_t *state);
size_t dp_burst_capture_get_doppler_bins (const dp_burst_capture_state_t *state);
size_t dp_burst_capture_get_n_noncoh (const dp_burst_capture_state_t *state);
size_t dp_burst_capture_get_code_bins (const dp_burst_capture_state_t *state);
double dp_burst_capture_get_doppler_span_hz (const dp_burst_capture_state_t *state);
size_t dp_burst_capture_state_bytes (const dp_burst_capture_state_t *state);
void dp_burst_capture_get_state (const dp_burst_capture_state_t *state, void *blob);
int dp_burst_capture_set_state (dp_burst_capture_state_t *state, const void *blob);
uint64_t dp_burst_capture_get_preamble_start(const dp_burst_capture_state_t *state);
double dp_burst_capture_get_doppler_hz_est(const dp_burst_capture_state_t *state);
double dp_burst_capture_get_doppler_res_hz(const dp_burst_capture_state_t *state);
double dp_burst_capture_get_cn0_dbhz_est(const dp_burst_capture_state_t *state);
double dp_burst_capture_get_doppler_rate_hz_s(const dp_burst_capture_state_t *state);
size_t dp_burst_capture_get_pending(const dp_burst_capture_state_t *state);
uint64_t dp_burst_capture_get_dropped(const dp_burst_capture_state_t *state);
uint64_t dp_burst_capture_get_n_bursts(const dp_burst_capture_state_t *state);
#ifdef __cplusplus
}
#endif
#endif /* BURST_CAPTURE_CORE_H */