feat(chirp): Down Chirp — the exact time-mirror of the Up Chirp (ticket 40) #36

Merged
ykp merged 1 commit from down-chirp into master 2026-09-27 18:00:10 +02:00
Owner

Backlog ticket 40 (chirp-directions round, second ticket). Adds the Down Chirp waveform on the SAME two-phase core as the Up Chirp, differing only by the sweep direction.

Operator-confirmed semantics

  • Same parameter set (ChirpDuration / ChirpIsCsteBT / ChirpMode), same guard / blend / COLA behavior — only the direction differs.
  • Multiband Down Chirp = ONE contiguous DESCENDING ramp over the union span (operator decision): the band order reverses (highest band first) and each band's sweep runs fmax→fmin. The reversed order keeps the seams frequency-contiguous, so the phase-1 COLA blend stays flat exactly like the up chirp's ascending ramp (no intrinsic frequency jumps — measured seam envelope flat to 1e-16; the per-band alternative was measured to beat with envelope dips up to 0.84 and was rejected).
  • The mirror is exact: |down[n]| == |up[N−1−n]| (max diff 4.4e-16).

Implementation (code-reuse architecture)

  • chirp.py: SWEEP_UP (+1) / SWEEP_DOWN (−1) direction constants (validated); _prepare lays the band segments in the direction's order; _assemble_base walks the direction-ordered sequence (per-band start edge fmax/fmin, negative rate); phase continuity (Q2) stays generic in (a, k) — verified at the blend midpoint with negative rates; generate_chirp and the new generate_down_chirp both delegate to the shared _generate_sweep core.
  • model.py: WAVEFORM_DOWN_CHIRP (7 options) + CHIRP_WAVEFORM_TYPES family tuple.
  • Dispatch (generate.py), validation (L7/L8/L16 via the family tuple), UI policy (chirp controls + hints, neutral labels), GUI Down-Chirp generate test.
  • spec.md: §5.2.1b Down Chirp, §3.3 row, 7 options, §5.0 phase-1 table, L8 wording.

Gate

  • pytest: 1189 passed / 63 skipped (headless tier), coverage 95.32 %
  • ruff + mypy: clean
  • New tests/test_down_chirp.py (16 tests): mirror symmetry, contiguous descending ramp (analytic-line probes), seam flatness, Q2a 0.75 level dip, BT mode, band-isolated reversed concatenation, determinism, memory preflight, dispatch, invalid direction.
Backlog ticket 40 (chirp-directions round, second ticket). Adds the **Down Chirp** waveform on the SAME two-phase core as the Up Chirp, differing only by the sweep direction. ## Operator-confirmed semantics - Same parameter set (`ChirpDuration` / `ChirpIsCsteBT` / `ChirpMode`), same guard / blend / COLA behavior — only the direction differs. - **Multiband Down Chirp = ONE contiguous DESCENDING ramp over the union span** (operator decision): the band order reverses (highest band first) and each band's sweep runs fmax→fmin. The reversed order keeps the seams **frequency-contiguous**, so the phase-1 COLA blend stays flat exactly like the up chirp's ascending ramp (no intrinsic frequency jumps — measured seam envelope flat to 1e-16; the per-band alternative was measured to beat with envelope dips up to 0.84 and was rejected). - The mirror is **exact**: `|down[n]| == |up[N−1−n]|` (max diff 4.4e-16). ## Implementation (code-reuse architecture) - `chirp.py`: `SWEEP_UP` (+1) / `SWEEP_DOWN` (−1) direction constants (validated); `_prepare` lays the band segments in the direction's order; `_assemble_base` walks the direction-ordered sequence (per-band start edge `fmax`/`fmin`, negative rate); phase continuity (Q2) stays generic in `(a, k)` — verified at the blend midpoint with negative rates; `generate_chirp` and the new `generate_down_chirp` both delegate to the shared `_generate_sweep` core. - `model.py`: `WAVEFORM_DOWN_CHIRP` (7 options) + `CHIRP_WAVEFORM_TYPES` family tuple. - Dispatch (`generate.py`), validation (L7/L8/L16 via the family tuple), UI policy (chirp controls + hints, neutral labels), GUI Down-Chirp generate test. - `spec.md`: §5.2.1b Down Chirp, §3.3 row, 7 options, §5.0 phase-1 table, L8 wording. ## Gate - `pytest`: **1189 passed / 63 skipped** (headless tier), coverage **95.32 %** - `ruff` + `mypy`: clean - New `tests/test_down_chirp.py` (16 tests): mirror symmetry, contiguous descending ramp (analytic-line probes), seam flatness, Q2a 0.75 level dip, BT mode, band-isolated reversed concatenation, determinism, memory preflight, dispatch, invalid direction.
feat(chirp): Down Chirp — the exact time-mirror of the Up Chirp (ticket 40)
Some checks failed
test / test (ubuntu-latest) (pull_request) Failing after 2m42s
a4b6e8d905
Adds the "Down Chirp" waveform on the SAME two-phase core as the Up
Chirp, differing only by the sweep direction (operator-confirmed:
same parameter set, same guard/blend/COLA behavior; multiband = ONE
continuous descending ramp over the union span):

- chirp.py: direction parameterization (SWEEP_UP +1 / SWEEP_DOWN -1,
  validated); _prepare lays the band segments in the direction's order
  (up = table order sorted by Fmin; down = REVERSED order, highest band
  first) so the seams stay frequency-contiguous — the phase-1 COLA
  blend remains flat and the mirror is EXACT (measured
  |down[n]| == |up[N-1-n]|, max diff 4.4e-16); per-band sweeps descend
  fmax->fmin with negative rate; phase continuity (Q2) generic in
  (a, k), verified at the midpoint with negative rates; new public
  generate_down_chirp (generate_chirp delegates to the shared
  _generate_sweep core)
- model.py: WAVEFORM_DOWN_CHIRP (2nd slot of WAVEFORM_TYPES, 7 options)
  + CHIRP_WAVEFORM_TYPES (the shared chirp family tuple)
- generate.py: dispatch branch (same post chain + write); Multi IQ /
  Other IQ still raise NotImplementedError
- validation.py: L7/L8/L16 chirp branches cover the whole family via
  CHIRP_WAVEFORM_TYPES
- ui/policy.py + main_window.py: chirp controls (BT checkbox, constant
  BT, chirp-duration visibility), duration hints and the chirp-periods
  note cover the whole family; labels stay neutral
- tests: new tests/test_down_chirp.py (16 tests: mirror symmetry,
  contiguous descending ramp, seam flatness to 1e-9, Q2a level dip
  0.75, BT mode, band-isolated reversed concatenation, determinism,
  memory preflight, dispatch, invalid direction); premise tests updated
  (7 options, __all__ surface); GUI Down Chirp generate test added
- spec.md: section 5.2.1b Down Chirp, section 3.3 row, 7 options,
  section 5.0 phase-1 table, L8 wording ('all chirp types')

Gate: pytest 1189 passed / 63 skipped (headless tier), coverage 95.32%;
ruff + mypy clean.
ykp merged commit 79623a620c into master 2026-09-27 18:00:10 +02:00
Sign in to join this conversation.
No description provided.