Skip to content

Design

Architecture decisions, API contracts, and the algorithm rationale behind shipped features — for anyone who wants the "why" and "how it works" underneath a feature they're already using, not just contributors. (Repo layout and forward-looking roadmaps live under Contributing instead.)

  • API Taxonomy — the DSP building-block hierarchy and its naming axis, plus concrete rename proposals
  • The NCO — the 32-bit phase accumulator every rate in the library stands on: why an integer register instead of a double, the one float boundary, and how carrier and timing read the same thing
  • Exponential Moving Average — the running average every estimator in the library is built on: which of its two algebraic forms is the right one and why that was measured, what its boundaries guarantee, and why an EMA is not a loop filter
  • The Loop Filter — the second-order PI every tracking loop in the library embeds by value: where its gains come from, the unit condition its bn promise depends on, and what it deliberately does not bound
  • Quantization — fixed-point pipeline design
  • CIC Decimator — the fixed-point input budget: DC gain and PAPR headroom
  • Measurement Suite — tone, NPR, and IMD metric internals
  • Spectrum Analyzer — how span and RBW set the rate, the transform length and the Kaiser beta, and why every RBW gets the same −90 dB skirt
  • State Serialization — the standard bytes interface for bit-exact checkpoint/resume
  • Telemetry — zero-cost scalar taps (loop stress, AGC gain) for running pipelines
  • Streaming — the transport contract: the 96-byte SIGS envelope every role shares, how a frame too big for the broker is chunked and reassembled, the subjects and JetStream objects derived from an endpoint, and who owns which buffer
  • Ending a Wait — one contract for network, memory and disk: why "no data right now" is indistinguishable from "no data ever" on all three, the interrupt primitive that already exists and is misnamed, and the end-of-stream marker that does not
  • The Ring Buffer — zero-copy, wrap-free, lock-free: what each promise means, the blocking and non-blocking surfaces, and the two streaming patterns.
  • The Ring Buffer — measurements — the dated record: what the ring costs per sample, what the non-blocking surface adds, and the three premises that were wrong.
  • The Spectrogram — chunks in, rows out: the use cases, the seven guarantees and the six things not yet known, why a spectrogram is PSD per frame rather than a second kernel, and the order the program is built in
  • The Spectrogram — measurements — the dated record: PSD's kernel promoted byte-for-byte, a timing that turned out bimodal, and the prototype that found a bug in its own test
  • The Doppler Channel — one parameter drives the dilation and the carrier: why a Doppler shift is not a frequency offset, the scalar and the profile forms, how the carrier is read off the resampler so it cannot depend on chunking, and how the composer and the Plan share one renderer.
  • The Doppler Channel — measurements — the dated record: the first profile that was withdrawn and why, the resampler's 32-bit step against the closed form, the gap that carried the signal, and the Plan's speed against compose().
  • Capture Files — the file I/O subsystem underneath Reader/Writer: why the file type is decided by content, why one keyword codec serves both directions, why provenance is a value rather than a caveat, and what a streaming writer costs at close
  • Ending a Capture — the disk third of that contract: spooling an endless stream to disk while reading it back, why Ctrl+C must reach the reader through the file rather than around it, and what owning both ends of the file buys
  • The Polynomial-Phase Estimator — the feedforward frequency/chirp-rate estimate a burst gets exactly one of: why the search is two-dimensional and coherent, why the transform is 4x its input, and why the caller strips the modulation
  • DSSS Acquisition — stateless, parallel, dynamics-capable acquisition architecture + roadmap
  • AsyncDsssReceiver — what the parallel design's receiver is built on: the spec, the two acquisition front doors and the acq_handoff_t hand-off, the asynchronous despreader and its look-back, the receiver's states, the lock-detector release, and the status record a holder reads; the pool as built (§5–§9, §11.1) is retired to the page as it stood
  • AsyncDsssReceiver — the measurement record — the dated record behind the design page's §12: every step's harness, numbers, wrong guesses and corrections, under the same section numbers
  • Parallel Asynchronous-Data DSSS Receivers — AsyncDsssPool redesigned as N independent AsyncDsssReceivers, one per CPU, under a simple controller: the signals, the receiver's search-and-track state machine, the controller's rules, what it costs, and why the pool as built is replaced
  • Parallel Asynchronous-Data DSSS Receivers — the measurement record — the dated runs behind the design page: arrival to tracking, what one receiver costs tracking and searching, and where the pool as built spends its time, under the same section numbers
  • DsssBurstReceiver — the burst chain composed in C: the three-stage search → refine → demod shape, why the hand-off needs a never-late epoch, and what a burst DetectionEvent must carry to stand alone
  • BurstCapture — acquisition's output turned into aligned burst samples: why the period-resolving refine and the look-back need a home outside the receiver, why the object owns its own engine rather than taking foreign detections, and the one behaviour that changes
  • BurstBank — the coarse-Doppler bank as one C object: why its cross-channel claim rule belongs beside the capture's, the layout rule now that the engine searches to its edge, rings named by centre so a pod can hold one channel, and the unknowns the characterization measures
  • CoarseChannel — question 1 of the bank design: is a channel its own object or a slice of the bank, judged against the two primary use cases (one process runs the whole bank; one pod runs one channel), with the trades and the work that answers it
  • Automatic Gain Control — the log-domain level loop every receiver stands on: why the filter is in dB and the detector is not, why the loop must be total under any input, and what level alone cannot tell it
  • Detection Sizing — the four statistical laws behind one det_ prefix: which one a statistic actually obeys, why non-coherent looks raise their own threshold, and the 41x an estimated noise reference costs
  • Lock Detection — the sizing chain every lock detector shares, and the independence it assumes
  • Timing Lock Detector — SymbolSync's Gardner/DTTL lock statistic and sizing formula
  • Symbol Timing on a Rate Cascade — RateSync: why the matched filter and the interpolator are one dot product, why ctrl is referenced to the terminal stage's rate, and why the T/2 parity resolves itself
  • MPSK Receiver — streaming M-PSK receiver architecture and carrier-recovery design, the constellation primitive it reuses (§9, soft decisions included), and the record of the collapse that made the real face a view (§12)
  • The Viterbi Decoder — the CCSDS inner code decoded: the trellis in the encoder's own terms, the branch metric it inherits, and why 5·K traceback is 33 % above the floor
  • Reed-Solomon — the outer code as a description: the two offsets a textbook omits (j0 != 1, and a root stride that is not 1), why Chien iterates positions rather than field elements, and what a refusal is not
  • The FEC Receive Half — the Viterbi, the node sync it needs first, and the lock detector's two error probabilities: why the code's transparency means polarity cannot be resolved by the decoder
  • Interleaving — spreading a burst across codewords — the permutation, the three ways to reason about it wrongly, and the measured gain: E to E×depth, and the bound that still bites
  • A Frame as a Description — a frame as a list of fields and a list of stages, each stage carrying the span it covers: why a chain of optional transforms is the representation that cannot express CCSDS, how a caller adds a stage doppler has never heard of, how far that openness actually reaches, and the Field: one text form for a run of bits, passed by every face
  • A Frame as a Description — the measurement record — the dated record behind it: the survey that counted seven spellings of a field, the prototype that proved one grammar lossless, and how the CCSDS sites were settled, under the same section letters
  • The Payload as a Data Source — a frame declares data:LEN and --data names where the bits come from (a file, a literal, stdin, a seeded stream): fill, idle frames, run length, what is deleted, and the unknowns
  • The Payload as a Data Source — the measurement record — the chunker prototyped before any C, and the three rules it changed
  • A Receiver Built from a Frame Description — BurstDemod and DsssBurstReceiver told the frame instead of its length: the sync word, the frame and burst lengths and the CRC verdict derived from one description, the callers that compute them by hand today, and the order of work
  • Receiver Test Harness — inventory of the stimulus, measurement and gate layers a receiver measurement rests on, and where they do not yet meet
  • Corr2D Interpolated Inverse — decoupled, pffft-friendly inverse FFT size + free sub-bin interpolation
  • Spectral & Measurement API Map — module dependency graph
  • wfmgen — the waveform generator — the spine for the tool: modulations, impairments and output streams from three interchangeable faces, what it promises and which gate keeps each promise, the seventeen primitives it composes rather than re-implements, and the eight things still unknown about it — including that it states no throughput and no certified envelope
  • Waveform Amplitude & Composition — level/power conventions for wfmgen
  • One Home for the Waveform Enum Tables — a name table's ORDER is the C enum value, so a second copy mis-maps a flag instead of failing: what owns the tables, and the gate that holds the manifest, the header and the C enums to each other
  • Continuously Variable Resampler — polyphase resampler architecture, testing, and performance optimizations
  • Acquisition Kernel — pure-functional acquisition kernel for the elastic fleet