Bind sw::dsp::sdr::Constellation and its free helpers — the symbol mapper
and demapper at the head of the SDR chain.
Upstream source: include/sw/dsp/sdr/constellation.hpp (closes upstream #95).
Upstream tests: tests/test_sdr_constellation.cpp.
Surface
enum class Modulation { bpsk, qpsk, psk8, qam16, qam64, qam256 } plus
to_string.
Free functions:
bits_per_symbol(Modulation) -> 1, 2, 3, 4, 6, 8
modulation_order(Modulation) -> 2^bits
is_square_qam(Modulation)
binary_to_gray(std::size_t), gray_to_binary(std::size_t, nbits)
Constellation<T>:
symbol(index), index_of(bits), bits_of(index, out)
map(std::span<const std::uint8_t> bits) -> symbol
demap_hard(symbol) -> index, demap_hard_bits(symbol, out)
demap_llr(symbol, noise_variance, out) — exact
demap_llr_maxlog(symbol, noise_variance, out) — max-log approximation
average_power(), order()
Binding notes
Modulation should be a proper nb::enum_, not a string key — it is a
signal-structure parameter, not an arithmetic config, and it recurs in
metrics.hpp (theoretical_ber_awgn) and analysis/sdr_precision.hpp
(SdrLinkConfig). Bind it once here and reuse.
std::span<const std::uint8_t> bit vectors map to uint8 ndarrays. This is
the first non-float64 array type at the boundary in this repo — the
np_f64_ro typedefs in src/_binding_helpers.hpp need a uint8
counterpart with the same c_contig copy-on-noncontiguous behaviour.
- The LLR outputs are written into caller-provided
std::span<T>. Bindings
should allocate and return instead, via make_f64_array — and per
src/BINDING_PATTERNS.md, any property returning a capsule-owned ndarray
needs explicit nb::rv_policy::take_ownership.
- Add block-level convenience wrappers (map/demap a whole symbol vector) rather
than forcing per-symbol Python loops. A 2000-symbol link at one Python call
per symbol is not usable.
Constellation<T> is single-scalar, so it dispatches on plain dtype=. It
does not need the scalar-pair scheme.
Depends on
Foundations issue (complex marshalling — symbol_type is complex).
Deliverables
Part of the SDR binding epic #130.
Bind
sw::dsp::sdr::Constellationand its free helpers — the symbol mapperand demapper at the head of the SDR chain.
Upstream source:
include/sw/dsp/sdr/constellation.hpp(closes upstream #95).Upstream tests:
tests/test_sdr_constellation.cpp.Surface
enum class Modulation { bpsk, qpsk, psk8, qam16, qam64, qam256 }plusto_string.Free functions:
bits_per_symbol(Modulation)-> 1, 2, 3, 4, 6, 8modulation_order(Modulation)-> 2^bitsis_square_qam(Modulation)binary_to_gray(std::size_t),gray_to_binary(std::size_t, nbits)Constellation<T>:symbol(index),index_of(bits),bits_of(index, out)map(std::span<const std::uint8_t> bits)-> symboldemap_hard(symbol)-> index,demap_hard_bits(symbol, out)demap_llr(symbol, noise_variance, out)— exactdemap_llr_maxlog(symbol, noise_variance, out)— max-log approximationaverage_power(),order()Binding notes
Modulationshould be a propernb::enum_, not a string key — it is asignal-structure parameter, not an arithmetic config, and it recurs in
metrics.hpp(theoretical_ber_awgn) andanalysis/sdr_precision.hpp(
SdrLinkConfig). Bind it once here and reuse.std::span<const std::uint8_t>bit vectors map touint8ndarrays. This isthe first non-float64 array type at the boundary in this repo — the
np_f64_rotypedefs insrc/_binding_helpers.hppneed auint8counterpart with the same
c_contigcopy-on-noncontiguous behaviour.std::span<T>. Bindingsshould allocate and return instead, via
make_f64_array— and persrc/BINDING_PATTERNS.md, any property returning a capsule-owned ndarrayneeds explicit
nb::rv_policy::take_ownership.than forcing per-symbol Python loops. A 2000-symbol link at one Python call
per symbol is not usable.
Constellation<T>is single-scalar, so it dispatches on plaindtype=. Itdoes not need the scalar-pair scheme.
Depends on
Foundations issue (complex marshalling —
symbol_typeis complex).Deliverables
src/sdr_bindings.cppcreated; forward-decl + call insrc/bindings.cpp;source listed in
nanobind_add_module(_core ...)inCMakeLists.txt.python/mpdsp/__init__.py.tests/test_sdr_constellation.py, mirroring the binding file 1:1.scripts/build_api_ref.pyCATEGORIES/CLASSESanddocs/api_reference.mdregenerated (never hand-edited).Part of the SDR binding epic #130.