File specan_core.h¶
FileList > doppler > specan > specan_core.h
Go to the source code of this file
Specan — natural-parameter spectrum analyzer (DDC + averaging PSD). More...
#include "doppler/ddc/ddc_core.h"#include "doppler/psd/psd_core.h"#include "doppler/dp_state.h"#include "doppler/dp_complex.h"#include <stddef.h>#include "doppler/lo/lo_core.h"#include "doppler/RateConverter/RateConverter_core.h"#include "doppler/resamp/resamp_core.h"#include "doppler/hbdecim/hbdecim_core.h"#include "doppler/cic/cic_core.h"#include "doppler/fir/fir_core.h"#include "doppler/resample/resample_core.h"#include "doppler/acc_trace/acc_trace_core.h"#include "doppler/fft/fft_core.h"#include "doppler/spectral/spectral_core.h"#include "doppler/agc/agc_core.h"#include "doppler/dp_tlm/dp_tlm_core.h"
Classes¶
| Type | Name |
|---|---|
| struct | dp_specan_state_t Specan state. Allocate with dp_specan_create() . |
Public Functions¶
| Type | Name |
|---|---|
| dp_specan_state_t * | dp_specan_create (double fs, double span, double rbw, double src_center, double center, double offset_db, double full_scale, size_t bits, size_t navg) Create a natural-parameter spectrum analyzer. |
| void | dp_specan_destroy (dp_specan_state_t * state) Destroy a Specan instance and release all memory. |
| size_t | dp_specan_execute (dp_specan_state_t * state, const float _Complex * x, size_t x_len, float * out, size_t max_out) Mix, decimate, average and return one display spectrum, or nothing. |
| size_t | dp_specan_execute_max_out (dp_specan_state_t * state) Output capacity hint for dp_specan_execute() ; equals disp_n. |
| void | dp_specan_get_state (const dp_specan_state_t * state, void * blob) |
| void | dp_specan_reset (dp_specan_state_t * state) Drop pending samples and the running average; LO/filter history zero. |
| void | dp_specan_retune (dp_specan_state_t * state, double center) Retune the display center without rebuilding the chain. |
| int | dp_specan_set_state (dp_specan_state_t * state, const void * blob) |
| size_t | dp_specan_state_bytes (const dp_specan_state_t * state) |
Macros¶
| Type | Name |
|---|---|
| define | SPECAN_STATE_MAGIC [**DP\_FOURCC**](dp__state_8h.md#define-dp_fourcc) ('S','P','A','N') |
| define | SPECAN_STATE_VERSION 1u |
Detailed Description¶
A streaming spectrum analyzer that speaks the instrument parameters an operator already knows — center frequency, span, resolution bandwidth (RBW), and reference level — instead of the DSP knobs (transform length, Kaiser beta) underneath them. It is the C-first home for the mapping that doppler.specan's engine used to hand-roll in Python.
It composes the existing library, re-implementing nothing:
cf32 in (fs_in) → Ddc (mix center→DC, decimate to fs_out = span·1.28)
→ PSD (Kaiser window → FFT → cg²-normalised power,
averaged over `navg` segments)
→ crop to the central ±span/2 display band
→ dB + ref offset → float display spectrum
- dp_ddc_state_t is the tuner/decimator (LO mix + RateConverter cascade); retuning the center is a cheap, seamless LO phase change.
- dp_psd_state_t is the one averaging-PSD core shared with the measurement suite;
navg = 1gives a responsive single-periodogram frame, largernavgtrades update rate for a smoother, lower-variance trace.
The display band length and the bin→frequency map are fixed at create time: bin i of the returned spectrum maps to center + (i − disp_n/2)·fs_out/nfft Hz. Peaks are intentionally NOT computed here — compose dp_find_peaks_f32 on the returned trace.
Lifecycle: create → (execute / retune / reset)* → destroy.
// 200 kHz span, 500 Hz RBW around DC of a 2.048 MHz cf32 stream
dp_specan_state_t *sa = dp_specan_create(2.048e6, 200e3, 500.0, 0.0, 0.0,
0.0, 1.0, 0, 1);
float disp[8192];
size_t n = dp_specan_execute(sa, iq, 65536, disp, 8192); // 0 until a frame
dp_specan_destroy(sa);
Public Functions Documentation¶
function dp_specan_create¶
Create a natural-parameter spectrum analyzer.
dp_specan_state_t * dp_specan_create (
double fs,
double span,
double rbw,
double src_center,
double center,
double offset_db,
double full_scale,
size_t bits,
size_t navg
)
Derives the DSP from the instrument parameters (docs/design/specan.md):
fs_out = 1.28·span, so ±span/2 lands exactly on bin ±nfft/2.56. A span the input cannot supply is clamped tofs/1.28.- The window
nis the smallest power of two (at least 16) whose narrowest RBW,2·fs_out/n(a Kaiser ENBW of 2 bins, beta ~12, sidelobes ~-90 dB), does not exceedrbw. The transform isnfft = max(n, 512): zero-padded only when the window is shorter than the 512 points the display needs (401 bins). - Kaiser
betawidens the ENBW, from 2 up to 4 bins, to meetrbw. The widest RBW is 4 bins of the shortest window,fs_out/4; wider is clamped. Auto (rbw0) isspan/100.
dp_specan_state_t::rbw and dp_specan_state_t::span hold what was realised, which a clamp can make differ from the request.
Parameters:
fsInput sample rate (Hz). Must be > 0.spanDisplay span (Hz). 0 = auto, the whole input band (fs/1.28); negative is refused.rbwResolution bandwidth (Hz). 0 = auto (span/100); negative is refused.src_centerSource center frequency (Hz); the input band is centred here, so the analyzer mixes (center − src_center) to DC.centerDesired display center frequency (Hz).offset_dbAdditive dB offset on the display spectrum, applied on top of dBFS (e.g. a dBm calibration the application computes from a reference level).full_scaleAmplitude that reads 0 dBFS (> 0). Ignored if bits > 0.bitsADC depth: bits>0 sets the 0-dBFS reference to 2^(bits-1) in the shared PSD core (the single source of truth for the dBFS reference).navgSegments averaged per emitted frame (>= 1).
Returns:
Heap-allocated state, or NULL on invalid argument or OOM.
Note:
Caller must call dp_specan_destroy() when done. Argument order keeps the required parameters (fs, span, rbw) first, matching the generated constructor's hoisting of jm required init params.
>>> from doppler.analyzer import Specan
>>> sa = Specan(fs=2.048e6, span=200e3, rbw=500.0)
>>> sa.fs_out
256000.0
>>> sa.nfft, sa.display_size
(1024, 801)
>>> round(sa.rbw)
500
function dp_specan_destroy¶
Destroy a Specan instance and release all memory.
Parameters:
stateMay be NULL (no-op).
function dp_specan_execute¶
Mix, decimate, average and return one display spectrum, or nothing.
size_t dp_specan_execute (
dp_specan_state_t * state,
const float _Complex * x,
size_t x_len,
float * out,
size_t max_out
)
Feeds x through the Ddc, buffers the decimated output, and once n·navg decimated samples are available windows + FFTs + averages them into a fresh frame, crops the central ±span/2 band and writes it in dB (+ ref_db). Returns 0 (writing nothing) until a frame is ready — the binding maps that to Python None.
Parameters:
stateMust be non-NULL.xcf32 input block (C-only; the binding passes it).x_lenNumber of input samples (C-only).outDisplay-spectrum buffer, dB (C-only).max_outCapacity ofout(C-only); >= disp_n is sufficient.
Returns:
Display bins written (disp_n), or 0 if no frame is ready yet.
>>> from doppler.analyzer import Specan
>>> import numpy as np
>>> sa = Specan(fs=2.048e6, span=200e3, rbw=500.0, navg=1)
>>> sa.execute(np.zeros(64, dtype=np.complex64)) is None # too few
True
>>> frame = sa.execute(np.zeros(65536, dtype=np.complex64))
>>> frame.shape, frame.dtype
((801,), dtype('float32'))
function dp_specan_execute_max_out¶
Output capacity hint for dp_specan_execute() ; equals disp_n.
function dp_specan_get_state¶
function dp_specan_reset¶
Drop pending samples and the running average; LO/filter history zero.
Parameters:
stateMust be non-NULL.
function dp_specan_retune¶
Retune the display center without rebuilding the chain.
Updates the Ddc LO phase increment (seamless across blocks — no resampler or window reset) and drops pending samples so the next frame reflects only the new tuning. Changing the span or RBW requires a destroy + create (the decimation rate and window length change).
Parameters:
stateMust be non-NULL.centerNew display center frequency (Hz).
function dp_specan_set_state¶
function dp_specan_state_bytes¶
Macro Definition Documentation¶
define SPECAN_STATE_MAGIC¶
define SPECAN_STATE_VERSION¶
The documentation for this class was generated from the following file native/inc/doppler/specan/specan_core.h