File wfm_surface.h¶
File List > doppler > wfm > wfm_surface.h
Go to the documentation of this file
/*
* wfm_surface.h — GENERATED by scripts/gen_wfm_defaults.py
*
* Do not edit. One row per wfm source or segment field that a
* face other than Python exposes, generated from `just-makeit.toml`
* (the rows that declare `cli`) and the headers it names. Every
* face that reads a field by name reads it from here, so a field
* cannot be spelled, typed or bounded two ways
* (docs/design/wfmgen.md, "One surface table"; doppler#853).
*/
#ifndef WFM_SURFACE_H
#define WFM_SURFACE_H
#include <stddef.h>
#include "doppler/wfm/wfm_compose.h"
#include "doppler/wfm/wfm_names.h"
/* Which struct a row's offsets are into. */
typedef enum
{
WFM_SURF_SOURCE, /* wfm_source_t */
WFM_SURF_SEGMENT, /* wfm_segment_t */
} wfm_surf_owner_t;
/* What kind of value a row holds. */
typedef enum
{
WFM_SV_DOUBLE,
WFM_SV_INT,
WFM_SV_SIZE,
WFM_SV_U32,
WFM_SV_U64,
WFM_SV_CHOICE, /* an int index into `choices` */
WFM_SV_SYMBOLS, /* float _Complex *, its count at `len_off` */
WFM_SV_FIELD, /* a wfm_seq_t, as a Field (wfm_frame.h) */
WFM_SV_BESPOKE, /* a pointer each face reads with its own code;
the generic readers and writers skip it */
} wfm_sv_kind_t;
typedef struct
{
const char *name; /* the struct member */
const char *cli; /* the flag; NULL = not on the CLI */
wfm_surf_owner_t owner;
wfm_sv_kind_t kind;
size_t off; /* offsetof the member */
unsigned range_bit; /* WFM_RANGE_*; 0 = not ranged */
size_t hi_off; /* `<name>_hi`, if ranged */
size_t len_off; /* WFM_SV_SYMBOLS: the count */
size_t reps_off; /* WFM_SV_FIELD: where *REPS goes;
0 = the field does not repeat */
const char *const *choices; /* WFM_SV_CHOICE: the names */
int n_choices;
int unit_interval; /* require 0 < v <= 1 */
const char *json; /* the scene/record key */
int json_required; /* absent/unknown: refuse */
int json_omit; /* not written at its default */
int json_bool; /* written as true/false */
int has_when; /* written only when ... */
int when_row; /* ... this row's choice ... */
int when_value; /* ... is this index */
} wfm_surface_row_t;
/* A row's index: WFM_SURFACE_<owner>_<name>. */
enum
{
WFM_SURFACE_source_type,
WFM_SURFACE_source_freq,
WFM_SURFACE_source_snr,
WFM_SURFACE_source_snr_mode,
WFM_SURFACE_source_seed,
WFM_SURFACE_source_sps,
WFM_SURFACE_source_pn_length,
WFM_SURFACE_source_pn_poly,
WFM_SURFACE_source_lfsr,
WFM_SURFACE_source_level,
WFM_SURFACE_source_background,
WFM_SURFACE_source_f_end,
WFM_SURFACE_source_span,
WFM_SURFACE_source_doppler,
WFM_SURFACE_source_doppler_rate,
WFM_SURFACE_source_carrier_hz,
WFM_SURFACE_source_doppler_lifetime,
WFM_SURFACE_source_modulation,
WFM_SURFACE_source_pulse,
WFM_SURFACE_source_rrc_beta,
WFM_SURFACE_source_rrc_span,
WFM_SURFACE_source_symbols,
WFM_SURFACE_source_acq_code,
WFM_SURFACE_source_data_code,
WFM_SURFACE_source_symbol_rate,
WFM_SURFACE_source_dsss_code_only,
WFM_SURFACE_source_frame,
WFM_SURFACE_source_data_from_file,
WFM_SURFACE_source_data,
WFM_SURFACE_source_data_len,
WFM_SURFACE_source_fill,
WFM_SURFACE_source_code_only_symbols,
WFM_SURFACE_source_frame_symbols,
WFM_SURFACE_segment_fs,
WFM_SURFACE_segment_num_samples,
WFM_SURFACE_segment_off_samples,
WFM_SURFACE_segment_repeats,
WFM_SURFACE_segment_delay_samples,
WFM_SURFACE_segment_gap_noise,
WFM_SURFACE_N
};
static const wfm_surface_row_t WFM_SURFACE[WFM_SURFACE_N] = {
[WFM_SURFACE_source_type] = {
.name = "type",
.cli = "--type",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_source_t, type),
.choices = TYPE_NAMES,
.n_choices = (int)(sizeof TYPE_NAMES / sizeof *TYPE_NAMES),
.json = "type",
.json_required = 1,
},
[WFM_SURFACE_source_freq] = {
.name = "freq",
.cli = "--freq",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, freq),
.range_bit = WFM_RANGE_FREQ,
.hi_off = offsetof (wfm_source_t, freq_hi),
.json = "freq",
},
[WFM_SURFACE_source_snr] = {
.name = "snr",
.cli = "--snr",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, snr),
.range_bit = WFM_RANGE_SNR,
.hi_off = offsetof (wfm_source_t, snr_hi),
.json = "snr",
},
[WFM_SURFACE_source_snr_mode] = {
.name = "snr_mode",
.cli = "--snr-mode",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_source_t, snr_mode),
.choices = MODE_NAMES,
.n_choices = (int)(sizeof MODE_NAMES / sizeof *MODE_NAMES),
.json = "snr_mode",
},
[WFM_SURFACE_source_seed] = {
.name = "seed",
.cli = "--seed",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_U32,
.off = offsetof (wfm_source_t, seed),
.json = "seed",
},
[WFM_SURFACE_source_sps] = {
.name = "sps",
.cli = "--sps",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_INT,
.off = offsetof (wfm_source_t, sps),
.json = "sps",
},
[WFM_SURFACE_source_pn_length] = {
.name = "pn_length",
.cli = "--pn-length",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_INT,
.off = offsetof (wfm_source_t, pn_length),
.json = "pn_length",
},
[WFM_SURFACE_source_pn_poly] = {
.name = "pn_poly",
.cli = "--pn-poly",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_U64,
.off = offsetof (wfm_source_t, pn_poly),
.json = "pn_poly",
},
[WFM_SURFACE_source_lfsr] = {
.name = "lfsr",
.cli = "--lfsr",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_source_t, lfsr),
.choices = LFSR_NAMES,
.n_choices = (int)(sizeof LFSR_NAMES / sizeof *LFSR_NAMES),
.json = "lfsr",
},
[WFM_SURFACE_source_level] = {
.name = "level",
.cli = "--level",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, level),
.range_bit = WFM_RANGE_LEVEL,
.hi_off = offsetof (wfm_source_t, level_hi),
.json = "level",
.json_omit = 1,
},
[WFM_SURFACE_source_background] = {
.name = "background",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_INT,
.off = offsetof (wfm_source_t, background),
.json = "background",
.json_omit = 1,
.json_bool = 1,
},
[WFM_SURFACE_source_f_end] = {
.name = "f_end",
.cli = "--f-end",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, f_end),
.range_bit = WFM_RANGE_FEND,
.hi_off = offsetof (wfm_source_t, f_end_hi),
.json = "f_end",
.has_when = 1,
.when_row = WFM_SURFACE_source_type,
.when_value = 5,
},
[WFM_SURFACE_source_span] = {
.name = "span",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_source_t, span),
.json = "span",
.json_omit = 1,
.has_when = 1,
.when_row = WFM_SURFACE_source_type,
.when_value = 5,
},
[WFM_SURFACE_source_doppler] = {
.name = "doppler",
.cli = "--doppler",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, doppler),
.range_bit = WFM_RANGE_DOPPLER,
.hi_off = offsetof (wfm_source_t, doppler_hi),
.json = "doppler",
.json_omit = 1,
},
[WFM_SURFACE_source_doppler_rate] = {
.name = "doppler_rate",
.cli = "--doppler-rate",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, doppler_rate),
.range_bit = WFM_RANGE_DOPPLER_RATE,
.hi_off = offsetof (wfm_source_t, doppler_rate_hi),
.json = "doppler_rate",
.json_omit = 1,
},
[WFM_SURFACE_source_carrier_hz] = {
.name = "carrier_hz",
.cli = "--carrier-hz",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, carrier_hz),
.json = "carrier_hz",
.json_omit = 1,
},
[WFM_SURFACE_source_doppler_lifetime] = {
.name = "doppler_lifetime",
.cli = "--doppler-lifetime",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_source_t, doppler_lifetime),
.choices = DOPPLER_LIFETIME_NAMES,
.n_choices = (int)(sizeof DOPPLER_LIFETIME_NAMES / sizeof *DOPPLER_LIFETIME_NAMES),
.json = "doppler_lifetime",
.json_omit = 1,
},
[WFM_SURFACE_source_modulation] = {
.name = "modulation",
.cli = "--modulation",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_source_t, modulation),
.choices = BITMOD_NAMES,
.n_choices = (int)(sizeof BITMOD_NAMES / sizeof *BITMOD_NAMES),
.json = "modulation",
.has_when = 1,
.when_row = WFM_SURFACE_source_type,
.when_value = 6,
},
[WFM_SURFACE_source_pulse] = {
.name = "pulse",
.cli = "--pulse",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_source_t, pulse),
.choices = PULSE_NAMES,
.n_choices = (int)(sizeof PULSE_NAMES / sizeof *PULSE_NAMES),
.json = "pulse",
.json_omit = 1,
},
[WFM_SURFACE_source_rrc_beta] = {
.name = "rrc_beta",
.cli = "--rrc-beta",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, rrc_beta),
.unit_interval = 1,
.json = "rrc_beta",
.has_when = 1,
.when_row = WFM_SURFACE_source_pulse,
.when_value = 1,
},
[WFM_SURFACE_source_rrc_span] = {
.name = "rrc_span",
.cli = "--rrc-span",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_INT,
.off = offsetof (wfm_source_t, rrc_span),
.json = "rrc_span",
.has_when = 1,
.when_row = WFM_SURFACE_source_pulse,
.when_value = 1,
},
[WFM_SURFACE_source_symbols] = {
.name = "symbols",
.cli = "--symbols-file",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_SYMBOLS,
.off = offsetof (wfm_source_t, symbols),
.len_off = offsetof (wfm_source_t, n_symbols),
},
[WFM_SURFACE_source_acq_code] = {
.name = "acq_code",
.cli = "--acq-code",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_FIELD,
.off = offsetof (wfm_source_t, acq_code),
.reps_off = offsetof (wfm_source_t, acq_reps),
.json = "acq_code",
},
[WFM_SURFACE_source_data_code] = {
.name = "data_code",
.cli = "--data-code",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_FIELD,
.off = offsetof (wfm_source_t, data_code),
.json = "data_code",
},
[WFM_SURFACE_source_symbol_rate] = {
.name = "symbol_rate",
.cli = "--symbol-rate",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_source_t, symbol_rate),
.json = "symbol_rate",
.json_omit = 1,
.has_when = 1,
.when_row = WFM_SURFACE_source_type,
.when_value = 8,
},
[WFM_SURFACE_source_dsss_code_only] = {
.name = "dsss_code_only",
.cli = "--code-only",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_INT,
.off = offsetof (wfm_source_t, dsss_code_only),
.json = "code_only",
.json_omit = 1,
.json_bool = 1,
},
[WFM_SURFACE_source_frame] = {
.name = "frame",
.cli = "--frame",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_BESPOKE,
.off = offsetof (wfm_source_t, frame),
.json = "frame",
},
[WFM_SURFACE_source_data_from_file] = {
.name = "data_from_file",
.cli = "--data-from-file",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_BESPOKE,
.off = offsetof (wfm_source_t, data_from_file),
.json = "data_from_file",
},
[WFM_SURFACE_source_data] = {
.name = "data",
.cli = "--data",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_FIELD,
.off = offsetof (wfm_source_t, data),
.json = "data",
},
[WFM_SURFACE_source_data_len] = {
.name = "data_len",
.cli = "--data-len",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_source_t, data_len),
.json = "data_len",
.json_omit = 1,
},
[WFM_SURFACE_source_fill] = {
.name = "fill",
.cli = "--fill",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_FIELD,
.off = offsetof (wfm_source_t, fill),
.json = "fill",
},
[WFM_SURFACE_source_code_only_symbols] = {
.name = "code_only_symbols",
.cli = "--code-only-symbols",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_source_t, code_only_symbols),
.json = "code_only_symbols",
.json_omit = 1,
.has_when = 1,
.when_row = WFM_SURFACE_source_type,
.when_value = 8,
},
[WFM_SURFACE_source_frame_symbols] = {
.name = "frame_symbols",
.cli = "--frame-symbols",
.owner = WFM_SURF_SOURCE,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_source_t, frame_symbols),
.json = "frame_symbols",
.json_omit = 1,
.has_when = 1,
.when_row = WFM_SURFACE_source_type,
.when_value = 8,
},
[WFM_SURFACE_segment_fs] = {
.name = "fs",
.cli = "--fs",
.owner = WFM_SURF_SEGMENT,
.kind = WFM_SV_DOUBLE,
.off = offsetof (wfm_segment_t, fs),
.json = "fs",
},
[WFM_SURFACE_segment_num_samples] = {
.name = "num_samples",
.cli = "--count",
.owner = WFM_SURF_SEGMENT,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_segment_t, num_samples),
.range_bit = WFM_RANGE_NUM_SAMPLES,
.hi_off = offsetof (wfm_segment_t, num_samples_hi),
.json = "num_samples",
},
[WFM_SURFACE_segment_off_samples] = {
.name = "off_samples",
.cli = "--off",
.owner = WFM_SURF_SEGMENT,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_segment_t, off_samples),
.range_bit = WFM_RANGE_OFF_SAMPLES,
.hi_off = offsetof (wfm_segment_t, off_samples_hi),
.json = "off_samples",
},
[WFM_SURFACE_segment_repeats] = {
.name = "repeats",
.cli = "--repeats",
.owner = WFM_SURF_SEGMENT,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_segment_t, repeats),
.json = "repeats",
.json_omit = 1,
},
[WFM_SURFACE_segment_delay_samples] = {
.name = "delay_samples",
.cli = "--delay",
.owner = WFM_SURF_SEGMENT,
.kind = WFM_SV_SIZE,
.off = offsetof (wfm_segment_t, delay_samples),
.range_bit = WFM_RANGE_DELAY_SAMPLES,
.hi_off = offsetof (wfm_segment_t, delay_samples_hi),
.json = "delay_samples",
.json_omit = 1,
},
[WFM_SURFACE_segment_gap_noise] = {
.name = "gap_noise",
.cli = "--gap-noise",
.owner = WFM_SURF_SEGMENT,
.kind = WFM_SV_CHOICE,
.off = offsetof (wfm_segment_t, gap_noise),
.choices = GAP_NOISE_NAMES,
.n_choices = (int)(sizeof GAP_NOISE_NAMES / sizeof *GAP_NOISE_NAMES),
.json = "gap_noise",
.json_omit = 1,
},
};
/* Two rows no face takes together, and the reason, spelled for each
face that can be given both: the CLI (both flags), a scene (both
keys), the object (both members set). NULL: that face cannot
carry one of the two, so it has nothing to refuse. */
typedef struct
{
int a, b; /* WFM_SURFACE_<owner>_<name> */
const char *cli_why;
const char *json_why;
const char *obj_why;
} wfm_surface_exclusive_t;
#define WFM_SURFACE_N_EXCLUSIVE 1
static const wfm_surface_exclusive_t
WFM_SURFACE_EXCLUSIVE[1] = {
{
.a = WFM_SURFACE_source_data,
.b = WFM_SURFACE_source_data_from_file,
.cli_why = "--data and --data-from-file cannot both be given: a "
"payload has one data source",
.json_why = "\"data\" and \"data_from_file\" cannot both be given: a "
"payload has one data source",
.obj_why = "a source's data and data_from_file cannot both be set:"
" a payload has one data source",
},
};
/* Whether a row's member holds a value: the object face's
"given". Only the kinds an exclusion may name (the generator
refuses any other) have an unset value to test for. */
static inline int
wfm_surface_row_is_set (const wfm_surface_row_t *r,
const void *base)
{
const char *m = (const char *)base + r->off;
switch (r->kind)
{
case WFM_SV_FIELD:
return ((const wfm_seq_t *)m)->len != 0;
case WFM_SV_BESPOKE:
return *(const void *const *)m != NULL;
case WFM_SV_SYMBOLS:
return *(const size_t *)((const char *)base + r->len_off)
!= 0;
default:
return 0;
}
}
/* A Field row with no repetition count refuses *REPS: only the
rows with `field_reps` repeat (a preamble). One reason per face.
*/
#define WFM_SURFACE_REPS_WHY_CLI \
"only --acq-code repeats (a preamble): drop the *REPS"
#define WFM_SURFACE_REPS_WHY_JSON \
"only \"acq_code\" repeats (a preamble): drop the *REPS"
/* --help option lines, one string per USAGE section. */
#define WFM_SURFACE_HELP_SIGNAL \
" --fs HZ Sample rate in Hz, one per segment and shared by all its\n" \
" sources. (default 1.0)\n" \
" --count N[:N] Segment on-time in samples, before the trailing gap: 0\n" \
" derives it from the sources, or 1024 when they set none.\n" \
" (default 0)\n" \
" --off N[:N] Trailing gap after the on-time, in samples. (default 0)\n" \
" --repeats N Play the segment this many times back-to-back (each instance\n" \
" = delay + on-time + trailing gap) before advancing.\n" \
" (default 1)\n" \
" --delay N[:N] Leading gap before the on-time, in samples: the burst arrives\n" \
" after this delay, and the gap carries the noise floor like\n" \
" off_samples. (default 0)\n" \
" --gap-noise M Gap policy for this segment's delay and trailing gap. One of:\n" \
" auto | off. (default auto)\n" \
" --freq HZ[:HZ] Carrier or offset frequency in Hz; for chirp, the sweep\n" \
" start. (default 0.0)\n" \
" --seed N PRNG and LFSR seed for the noise and PN streams. (default 0)\n" \
" --sps N Samples per symbol (PSK) or per chip (PN): the oversampling\n" \
" factor. (default 1)\n" \
" --f-end HZ[:HZ] Chirp end frequency in Hz; ignored by other types.\n" \
" (default 0.0)\n"
#define WFM_SURFACE_HELP_TYPE \
" --type TYPE Waveform type. One of: tone | noise | pn | bpsk | qpsk |\n" \
" chirp | bits | symbols | dsss. (default tone)\n"
#define WFM_SURFACE_HELP_NOISE \
" --snr DB[:DB] Signal-to-noise ratio in dB, interpreted per snr_mode.\n" \
" (default 100.0)\n" \
" --snr-mode MODE How snr is interpreted. One of: auto | fs | ebno | esno.\n" \
" (default auto)\n"
#define WFM_SURFACE_HELP_PN \
" --pn-length N PN LFSR register length in bits, 2 to 64 for the PN-bearing\n" \
" types; the sequence period is 2^pn_length - 1. (default 15)\n" \
" --pn-poly N PN generator polynomial, in the Galois bit-vector convention;\n" \
" 0 selects a maximal-length (MLS) polynomial for pn_length.\n" \
" (default 0)\n" \
" --lfsr TYPE PN LFSR realisation. One of: galois | fibonacci.\n" \
" (default galois)\n"
#define WFM_SURFACE_HELP_AMPLITUDE \
" --level DB[:DB] Source power in dBFS (<= 0; 0 is unit power). (default 0.0)\n"
#define WFM_SURFACE_HELP_DOPPLER \
" --doppler PPM[:PPM]\n" \
" Clock Doppler in ppm: the received time base is rescaled by 1\n" \
" + doppler*1e-6, so the symbol and chip rates move with the\n" \
" carrier and a timing loop sees the error a carrier-only\n" \
" `freq` offset hides. (default 0.0)\n" \
" --doppler-rate PPM_S[:PPM_S]\n" \
" Linear ramp on `doppler`, in ppm per second of elapsed stream\n" \
" time. (default 0.0)\n" \
" --carrier-hz HZ RF carrier in Hz that the ppm figures are referred to.\n" \
" (default 0.0)\n" \
" --doppler-lifetime L\n" \
" How long this source's Doppler channel lives. One of:\n" \
" per_instance | persist. (default per_instance)\n"
#define WFM_SURFACE_HELP_BITS \
" --modulation M Symbol mapping of a bits pattern. One of: none | bpsk | qpsk.\n" \
" (default bpsk)\n" \
" --data-from-file PATH\n" \
" A data source read from a file of packed octets, MSB first,\n" \
" or `-` for stdin, instead of data. Not with --data.\n" \
" --data FIELD A frame's payload drawn from a data source: a Field on the\n" \
" command line and in a scene, a bit array in Python. Not with\n" \
" --data-from-file.\n" \
" --data-len BITS Bits of the data source per frame: the data:LEN of the common\n" \
" frame [preamble x reps | sync | data:LEN | crc]. (default 0)\n" \
" --fill FIELD The bits that pad a data source's last frame when it does not\n" \
" divide into data_len-bit frames, tiled from their first bit;\n" \
" stdin on a framed source always needs them.\n"
#define WFM_SURFACE_HELP_PULSE \
" --pulse SHAPE Pulse shape per symbol or chip, for\n" \
" pn/bpsk/qpsk/bits/symbols/dsss. One of: rect | rrc.\n" \
" (default rect)\n" \
" --rrc-beta R RRC roll-off factor, in (0, 1], when pulse=rrc.\n" \
" (default 0.35)\n" \
" --rrc-span N RRC filter support in symbols when pulse=rrc, ONE-SIDED: the\n" \
" filter has 2*rrc_span*sps + 1 taps, unit energy (sum of h^2 =\n" \
" 1). (default 8)\n"
#define WFM_SURFACE_HELP_SYMBOLS \
" --symbols-file F\n" \
" For type=symbols: a complex constellation stream.\n"
#define WFM_SURFACE_HELP_DSSS_BURST \
" --acq-code FIELD\n" \
" The preamble code, sent acq_reps times at the head of the\n" \
" frame (a Field's *REPS on the command line and in a scene) --\n" \
" the coherent pull-in target BurstDespreader.set_acq and\n" \
" BurstDemod.set_preamble lock to.\n" \
" --data-code FIELD\n" \
" For type=dsss: the payload spreading code, a second code\n" \
" distinct from acq_code.\n"
#define WFM_SURFACE_HELP_DSSS_CONT \
" --symbol-rate HZ\n" \
" For type=dsss: > 0 selects CONTINUOUS asynchronous mode.\n" \
" (default 0.0)\n" \
" --code-only Continuous dsss data source: 1 = code-only (the pure\n" \
" spreading code, no data modulation); 0 = data-modulated (the\n" \
" payload when supplied, else the seeded PN). (default 0)\n" \
" --code-only-symbols N\n" \
" Continuous dsss: pure-code symbols opening each frame of\n" \
" frame_symbols symbols. (default 0)\n" \
" --frame-symbols N\n" \
" Continuous dsss: the frame, in symbols, that\n" \
" code_only_symbols opens; give it with code_only_symbols, or\n" \
" both 0 for no window. (default 0)\n"
#define WFM_SURFACE_HELP_CODED \
" --frame FILE A frame DESCRIPTION, the whole frame: fields in wire order,\n" \
" and stages that each name the span they cover (crc16, rs,\n" \
" randomise, interleave, conv, or a kind of your own).\n"
/* The keys each object of a scene takes, generated from the schema's
`properties` (docs/schema/wfmgen.schema.json). The reader refuses any
other key by name: the schema and the reader are one table (#1153). */
typedef enum
{
WFM_JSON_ROOT,
WFM_JSON_INLINE_SEGMENT,
WFM_JSON_SUM_SEGMENT,
WFM_JSON_SOURCE,
WFM_JSON_FRAME,
WFM_JSON_FIELD,
WFM_JSON_STAGE,
WFM_JSON_N_LEVELS
} wfm_json_level_t;
static const char *const WFM_JSON_KEYS_ROOT[] = {
"continuous",
"headroom",
"repeat",
"seed_advance",
"segments",
"version",
NULL
};
static const char *const WFM_JSON_KEYS_INLINE_SEGMENT[] = {
"acq_code",
"background",
"carrier_hz",
"code_only",
"code_only_symbols",
"data",
"data_code",
"data_from_file",
"data_len",
"data_sent",
"delay_samples",
"doppler",
"doppler_lifetime",
"doppler_rate",
"f_end",
"fill",
"frame",
"frame_symbols",
"freq",
"fs",
"gap_noise",
"level",
"lfsr",
"modulation",
"num_samples",
"off_samples",
"pn_length",
"pn_poly",
"pulse",
"repeats",
"rrc_beta",
"rrc_span",
"seed",
"snr",
"snr_mode",
"span",
"sps",
"symbol_rate",
"symbols",
"type",
NULL
};
static const char *const WFM_JSON_KEYS_SUM_SEGMENT[] = {
"delay_samples",
"fs",
"gap_noise",
"num_samples",
"off_samples",
"repeats",
"sum",
NULL
};
static const char *const WFM_JSON_KEYS_SOURCE[] = {
"acq_code",
"background",
"carrier_hz",
"code_only",
"code_only_symbols",
"data",
"data_code",
"data_from_file",
"data_len",
"data_sent",
"doppler",
"doppler_lifetime",
"doppler_rate",
"f_end",
"fill",
"frame",
"frame_symbols",
"freq",
"level",
"lfsr",
"modulation",
"pn_length",
"pn_poly",
"pulse",
"rrc_beta",
"rrc_span",
"seed",
"snr",
"snr_mode",
"span",
"sps",
"symbol_rate",
"symbols",
"type",
NULL
};
static const char *const WFM_JSON_KEYS_FRAME[] = {
"fields",
"stages",
NULL
};
static const char *const WFM_JSON_KEYS_FIELD[] = {
"bits",
"derived_by",
"name",
"spec",
NULL
};
static const char *const WFM_JSON_KEYS_STAGE[] = {
"depth",
"emit_den",
"emit_num",
"first_field",
"kind",
"n_fields",
"unit_bits",
NULL
};
static const char *const *const WFM_JSON_KEYS[WFM_JSON_N_LEVELS] = {
WFM_JSON_KEYS_ROOT,
WFM_JSON_KEYS_INLINE_SEGMENT,
WFM_JSON_KEYS_SUM_SEGMENT,
WFM_JSON_KEYS_SOURCE,
WFM_JSON_KEYS_FRAME,
WFM_JSON_KEYS_FIELD,
WFM_JSON_KEYS_STAGE,
};
#endif /* WFM_SURFACE_H */