Skip to main content

ModulationParams

Trait ModulationParams 

Source
pub trait ModulationParams:
    Copy
    + Default
    + 'static {
Show 16 associated constants and 0 method const NTONES: u32; const BITS_PER_SYMBOL: u32; const NSPS: u32; const SYMBOL_DT: f32; const TONE_SPACING_HZ: f32; const GRAY_MAP: &'static [u8]; const GFSK_BT: f32; const GFSK_HMOD: f32; const NFFT_PER_SYMBOL_FACTOR: u32; const NSTEP_PER_SYMBOL: u32; const NDOWN: u32; const LLR_SCALE: f32 = 2.83; const LLR_NSYM_MAX: u32 = 3; const LLR_NSYM_MID: Option<u32> = None; const INFO_SCRAMBLE_RVEC: Option<&'static [u8]> = None; const SPECTRUM_WINDOW: SpectrumWindow = SpectrumWindow::Rectangular;
}
Expand description

Baseband modulation parameters (tones, symbol rate, Gray mapping, Gaussian shaping and the tunable DSP ratios the pipeline reads per protocol).

All constants are evaluated at compile time; the trait carries no data so implementors are typically zero-sized types.

Required Associated Constants§

Source

const NTONES: u32

Number of FSK tones (M in M-ary FSK).

Source

const BITS_PER_SYMBOL: u32

Information bits carried per modulated symbol (= log2(NTONES)).

Source

const NSPS: u32

Samples per symbol at the 12 kHz pipeline sample rate.

Source

const SYMBOL_DT: f32

Symbol duration in seconds (= NSPS / 12000).

Source

const TONE_SPACING_HZ: f32

Spacing between adjacent tones, in Hz.

Source

const GRAY_MAP: &'static [u8]

Gray-code map: GRAY_MAP[tone_index] returns the NATURAL-bit pattern for that tone. The map covers at least the data alphabet (2^BITS_PER_SYMBOL entries) and at most the full tone set (NTONES entries). Protocols whose sync tones are part of the data alphabet (FT8 / FT4 / FST4 / WSPR) have len() == NTONES == 2^BITS_PER_SYMBOL; protocols that reserve additional sync-only tones (JT9, JT65, Q65) either trim the map to the data alphabet (JT9: 8 entries for 9 tones) or extend it with identity over the sync slots (JT65 / Q65). Pinned by tests/protocol_invariants.rs.

Source

const GFSK_BT: f32

Gaussian bandwidth-time product. FT8 = 2.0, FT4 = 1.0, FST4 ≈ 1.0.

Source

const GFSK_HMOD: f32

Modulation index h — the phase increment per symbol is 2π · h. FT8 and FT4 both use 1.0 (orthogonal tones at 1/T spacing).

Source

const NFFT_PER_SYMBOL_FACTOR: u32

Per-symbol FFT size = NSPS * NFFT_PER_SYMBOL_FACTOR. FT8 = 2 (window is 2·NSPS), FT4 = 4 (window is 4·NSPS) — trade-off between frequency resolution and time localisation.

Source

const NSTEP_PER_SYMBOL: u32

Coarse-sync time-step = NSPS / NSTEP_PER_SYMBOL. FT8 = 4 (quarter-symbol resolution), FT4 = 1 (symbol-granular).

Source

const NDOWN: u32

Downsample decimation factor: baseband rate = 12 000 / NDOWN Hz. FT8 = 60 (→200 Hz), FT4 = 18 (→667 Hz). Proportional to tone spacing.

Provided Associated Constants§

Source

const LLR_SCALE: f32 = 2.83

LLR scale factor applied after standard-deviation normalisation. FT8 uses 2.83 (empirical, from WSJT-X ft8b.f90). Different bits-per-symbol counts may shift the optimum — FT4’s 2-bit LLR dynamics are not identical to FT8’s 3-bit case.

Source

const LLR_NSYM_MAX: u32 = 3

Maximum coherent-integration depth for the 3rd LLR variant. compute_llr builds three variants llra/llrb/llrc from nsym{1, 2, LLR_NSYM_MAX} symbol blocks. WSJT-X uses nsym=1, 2, 4 for FT4 (get_ft4_bitmetrics.f90:69-71); we default to nsym=3 (FT8 path is calibrated to it). FT4 overrides to 4 for an extra ~3 dB SNR boost on stable signals — closes the recall gap on real-WAV recordings. FST4 overrides to 8, matching WSJT-X’s own 1/2/4/8-symbol correlation ladder in get_fst4_bitmetrics.f90 (issue #146 — FST4 had silently been using the uncalibrated FT8 default of 3, never wired to its own bit-metric depth). Any value ≥ 1 works — nt = NTONES^nsym combination hypotheses are computed generically, no per-nsym lookup table — but cost grows exponentially with nsym, so keep it at the WSJT-X-matched depth for the protocol rather than raising it further.

Source

const LLR_NSYM_MID: Option<u32> = None

Optional extra coherent-integration depth strictly between the nsym=2 and nsym=LLR_NSYM_MAX variants, populating LlrSet’s llre slot. None for every protocol whose ladder has no gap (FT8: {1,2,3}; FT4: {1,2,4}) — llre stays empty and costs nothing. FST4 overrides to Some(4): WSJT-X’s get_fst4_bitmetrics.f90 tries all four of nsym ∈ {1,2,4,8} (fst4_decode.f90:429-433), but LLR_NSYM_MAX=8 alone only gives compute_llr_generic two depths + the deepest ({1,2,8}) — nsym=4 would otherwise never run. Diagnostic measurement (issue #146, fst4_diag_nsym4_ladder in tests/fst4_sweep.rs) found a real but modest effect: a standalone nsym=4 pass recovered 4/43 (~9%) of near-threshold FST4-30 AWGN failures and 2/38 (~5%) of FST4-300’s, over and above the existing {1,2,8,d} ladder.

Source

const INFO_SCRAMBLE_RVEC: Option<&'static [u8]> = None

Optional 77-bit pre-LDPC scrambler. WSJT-X applies an FT4-specific scrambler in genft4.f90:64 (msgbits=mod(msgbits+rvec,2)) before computing CRC-14 and running LDPC encode; the receiver removes it after LDPC decode + CRC verify (ft4_decode.f90:430). Without this our decoder converges on a valid codeword whose unscrambled payload is the WSJT-X-transmitted message — but emerges as nonsense because we never undo the XOR.

Default None (FT8 / others don’t scramble); FT4 and FST4 both override to the same 77-element rvec (WSJT-X genfst4.f90:29-31 uses the identical array to genft4.f90’s). Length must be 77 when set.

Source

const SPECTRUM_WINDOW: SpectrumWindow = SpectrumWindow::Rectangular

Window function applied per NSPS-sample chunk in crate::core::sync::compute_spectra before the NFFT1 FFT. Default = SpectrumWindow::Rectangular (preserves FT8’s existing synth-roundtrip behaviour); FT4 overrides to SpectrumWindow::Nuttall4 to match WSJT-X getcandidates4.f90:22 and suppress sidelobe leakage that otherwise inflates the per-bin baseline near strong signals.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl ModulationParams for Fst4s15

Source§

impl ModulationParams for Fst4s30

Source§

impl ModulationParams for Fst4s60

Source§

impl ModulationParams for Fst4s120

Source§

impl ModulationParams for Fst4s300

Source§

impl ModulationParams for Ft4

Source§

const NTONES: u32 = 4

Source§

const BITS_PER_SYMBOL: u32 = 2

Source§

const NSPS: u32 = 576

Source§

const SYMBOL_DT: f32 = 0.048

Source§

const TONE_SPACING_HZ: f32 = 20.833

Source§

const GRAY_MAP: &'static [u8]

Source§

const GFSK_BT: f32 = 1.0

Source§

const GFSK_HMOD: f32 = 1.0

Source§

const NFFT_PER_SYMBOL_FACTOR: u32 = 4

Source§

const NSTEP_PER_SYMBOL: u32 = 2

Source§

const NDOWN: u32 = 18

Source§

const SPECTRUM_WINDOW: SpectrumWindow = crate::core::SpectrumWindow::Rectangular

Source§

const LLR_NSYM_MAX: u32 = 4

Source§

const INFO_SCRAMBLE_RVEC: Option<&'static [u8]>

Source§

impl ModulationParams for Ft8

Source§

impl ModulationParams for Jt9

Source§

impl ModulationParams for Jt65

Source§

impl ModulationParams for Q65a30

Source§

impl ModulationParams for Q65a60

Source§

impl ModulationParams for Q65b60

Source§

impl ModulationParams for Q65c60

Source§

impl ModulationParams for Q65d60

Source§

impl ModulationParams for Q65e60

Source§

impl ModulationParams for UvExpress

Source§

impl ModulationParams for UvRobust

Source§

impl ModulationParams for UvStandard

Source§

impl ModulationParams for UvUltraRobust

Source§

impl ModulationParams for Wspr