Skip to content

File wfm_core.h

FileList > inc > wfm > wfm_core.h

Go to the source code of this file

Wfmgen module — public C API.

  • #include "clib_common.h"

Public Functions

Type Name
void bpsk_map (const uint8_t * bits, size_t bits_len, float complex * out)
Map binary bits {0, 1} to BPSK constellation symbols (cf32). The mapping is: 0 -> +1 + 0j, 1 -> -1 + 0j. Output is unit-power (each symbol has magnitude 1). The imaginary component is always zero. Typically used before a carrier multiply and noise addition to build a BPSK burst without the full Synth engine.
void dsss_spread (const float complex * syms, size_t syms_len, const uint8_t * code, size_t code_len, int sf, float complex * out)
uint64_t mls_poly (uint32_t n)
Maximal-length-sequence primitive polynomial for a length- n LFSR. Returns the tap mask (in the same bit convention the synth/PN engine uses forpn_poly = 0 ) that drives ann-stage Fibonacci LFSR through its full 2^n - 1 state period. Thin public alias over the synth engine's MLS table; valid forn in 2..64 and returns 0 otherwise.
void qpsk_map (const uint8_t * syms, size_t syms_len, float complex * out)
Map QPSK symbol indices {0, 1, 2, 3} to Gray-coded symbols (cf32). Gray coding: adjacent indices differ in exactly one bit, minimising BER at low SNR. Bit 0 (LSB) controls I, bit 1 controls Q: I = (1 - 2*b_i) / sqrt(2), Q = (1 - 2*b_q) / sqrt(2). Output is unit-power (|sym| = 1.0 exactly). The four constellation points lie at the cardinal diagonals of the IQ plane.
void rrc_taps (double beta, int sps, int span, float * out)
float wfm_awgn_amplitude (float snr_db, float signal_power)
Compute the per-component AWGN amplitude for a target SNR. The AWGN engine uses equal-power I and Q noise: complex noise power is 2 * amplitude². This function inverts that relationship for a given signal_power andsnr_db (measured over the full sample-rate bandwidth): amplitude = sqrt(signal_power / (2 * 10^(snr_db / 10))). Pass the result directly toawgn_create to get the exact noise level that corresponds to the requested SNR.
float wfm_ebno_to_snr_db (float ebno_db, int bits_per_symbol, float samples_per_symbol)
Convert Eb/No (dB) to SNR (dB) over the full sample-rate band. Digital communication systems are typically specified in Eb/No; doppler uses an fs-band SNR internally. The conversion is: SNR_fs = Eb/No + 10 log10(bits_per_symbol) - 10 log10(samples_per_symbol) For BPSK (bits_per_symbol=1, sps=8) at Eb/No=10 dB this gives ~0.97 dB. For QPSK (bits_per_symbol=2, sps=8) at Eb/No=10 dB this gives ~3.98 dB.

Public Functions Documentation

function bpsk_map

Map binary bits {0, 1} to BPSK constellation symbols (cf32). The mapping is: 0 -> +1 + 0j, 1 -> -1 + 0j. Output is unit-power (each symbol has magnitude 1). The imaginary component is always zero. Typically used before a carrier multiply and noise addition to build a BPSK burst without the full Synth engine.

void bpsk_map (
    const uint8_t * bits,
    size_t bits_len,
    float complex * out
) 

Parameters:

  • bits Array of uint8 values; only the LSB of each byte is used.
  • bits_len Number of elements in bits.
  • out Output buffer of at least bits_len cf32 elements.
    >>> from doppler.wfm import bpsk_map
    >>> import numpy as np
    >>> bits = np.array([0, 1, 0, 1], dtype=np.uint8)
    >>> bpsk_map(bits).tolist()
    [(1+0j), (-1+0j), (1+0j), (-1+0j)]
    

function dsss_spread

void dsss_spread (
    const float complex * syms,
    size_t syms_len,
    const uint8_t * code,
    size_t code_len,
    int sf,
    float complex * out
) 

function mls_poly

Maximal-length-sequence primitive polynomial for a length- n LFSR. Returns the tap mask (in the same bit convention the synth/PN engine uses forpn_poly = 0 ) that drives ann-stage Fibonacci LFSR through its full 2^n - 1 state period. Thin public alias over the synth engine's MLS table; valid forn in 2..64 and returns 0 otherwise.

uint64_t mls_poly (
    uint32_t n
) 

Parameters:

  • n LFSR length in stages (2..64).

Returns:

Primitive-polynomial tap mask, or 0 if n is out of range.

>>> from doppler.wfm import mls_poly
>>> hex(mls_poly(7))
'0x41'


function qpsk_map

Map QPSK symbol indices {0, 1, 2, 3} to Gray-coded symbols (cf32). Gray coding: adjacent indices differ in exactly one bit, minimising BER at low SNR. Bit 0 (LSB) controls I, bit 1 controls Q: I = (1 - 2*b_i) / sqrt(2), Q = (1 - 2*b_q) / sqrt(2). Output is unit-power (|sym| = 1.0 exactly). The four constellation points lie at the cardinal diagonals of the IQ plane.

void qpsk_map (
    const uint8_t * syms,
    size_t syms_len,
    float complex * out
) 

Parameters:

  • syms Array of uint8 symbol indices; values must be in {0,1,2,3}. Bits above position 1 are ignored.
  • syms_len Number of elements in syms.
  • out Output buffer of at least syms_len cf32 elements.
    >>> from doppler.wfm import qpsk_map
    >>> import numpy as np
    >>> idx = np.array([0, 1, 2, 3], dtype=np.uint8)
    >>> out = qpsk_map(idx)
    >>> [round(float(v.real), 4) for v in out]
    [0.7071, -0.7071, 0.7071, -0.7071]
    >>> [round(float(v.imag), 4) for v in out]
    [0.7071, 0.7071, -0.7071, -0.7071]
    

function rrc_taps

void rrc_taps (
    double beta,
    int sps,
    int span,
    float * out
) 

function wfm_awgn_amplitude

Compute the per-component AWGN amplitude for a target SNR. The AWGN engine uses equal-power I and Q noise: complex noise power is 2 * amplitude². This function inverts that relationship for a given signal_power andsnr_db (measured over the full sample-rate bandwidth): amplitude = sqrt(signal_power / (2 * 10^(snr_db / 10))). Pass the result directly toawgn_create to get the exact noise level that corresponds to the requested SNR.

float wfm_awgn_amplitude (
    float snr_db,
    float signal_power
) 

Parameters:

  • snr_db Target SNR in dB, referenced to the full sample rate.
  • signal_power RMS power of the signal (e.g. 1.0 for unit-power complex tones or unit-energy BPSK/QPSK symbols).

Returns:

Per-component AWGN amplitude (sigma for one I or Q channel).

>>> from doppler.wfm import wfm_awgn_amplitude
>>> round(float(wfm_awgn_amplitude(10.0, 1.0)), 6)
0.223607
>>> round(float(wfm_awgn_amplitude(0.0, 1.0)), 6)
0.707107


function wfm_ebno_to_snr_db

Convert Eb/No (dB) to SNR (dB) over the full sample-rate band. Digital communication systems are typically specified in Eb/No; doppler uses an fs-band SNR internally. The conversion is: SNR_fs = Eb/No + 10 log10(bits_per_symbol) - 10 log10(samples_per_symbol) For BPSK (bits_per_symbol=1, sps=8) at Eb/No=10 dB this gives ~0.97 dB. For QPSK (bits_per_symbol=2, sps=8) at Eb/No=10 dB this gives ~3.98 dB.

float wfm_ebno_to_snr_db (
    float ebno_db,
    int bits_per_symbol,
    float samples_per_symbol
) 

Parameters:

  • ebno_db Eb/No in dB (energy per bit over noise spectral density).
  • bits_per_symbol Bits carried per modulation symbol: 1 for BPSK, 2 for QPSK.
  • samples_per_symbol Oversampling ratio (sps), e.g. 8.0.

Returns:

SNR in dB measured over the full sample-rate bandwidth.

>>> from doppler.wfm import wfm_ebno_to_snr_db
>>> round(float(wfm_ebno_to_snr_db(10.0, 2, 8.0)), 4)
3.9794
>>> round(float(wfm_ebno_to_snr_db(10.0, 1, 8.0)), 4)
0.9691



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