Skip to content

Bind sdr::CarrierRecovery — Costas carrier loop #124

Description

@Ravenwater

Bind sw::dsp::sdr::CarrierRecovery — the Costas / decision-directed carrier
loop.

Upstream source: include/sw/dsp/sdr/carrier_recovery.hpp (closes upstream
#99). Upstream tests: tests/test_sdr_carrier_recovery.cpp.

Surface

  • enum class CarrierDetector { bpsk, qpsk, decision_directed }
  • CarrierRecoveryConfig<T>loop_bandwidth, damping, detector_gain,
    max_frequency, detector, enable_afc, afc_gain, lock_threshold,
    lock_average_symbols
  • CarrierRecovery<StateScalar, SampleScalar>process(in), reset(),
    invariants_hold(), lock metric accessor

Binding notes

  • Reuses PiLoopFilter bound by the timing-recovery issue. Do not bind it
    twice.
  • max_frequency is in radians per symbol and also bounds the integrator.
    Note the unit in the docstring — this repo has already been bitten once by a
    units mismatch in a phase accumulator (the NCO documented as radians while
    actually stepping in normalized cycles, corrected in
    src/acquisition_bindings.cpp). Verify against the header before writing the
    docstring, and add a test that pins the unit.
  • AFC (enable_afc, afc_gain) widens acquisition beyond the phase detector's
    pull-in range. A test with an initial frequency offset outside pull-in,
    passing with AFC on and failing with it off, documents the feature better
    than prose.
  • Block process method required, same argument as the timing loop.
  • Same type-erased pattern; same scalar-pair scheme as AGC and timing.

Depends on

Foundations issue; PiLoopFilter from the timing-recovery issue.

Deliverables

  • Bindings in src/sdr_bindings.cpp.
  • Exported by explicit name in python/mpdsp/__init__.py.
  • tests/test_sdr_carrier_recovery.py — lock from a phase offset for each
    detector, AFC pull-in beyond the phase detector's range, integrator
    bounded by max_frequency.
  • scripts/build_api_ref.py tables updated, docs/api_reference.md
    regenerated.

Part of the SDR binding epic #130.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions