feat(pipeline): single final normalization just before write and display #49
No reviewers
Labels
No labels
accessibility
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
ykp/gensig!49
Loading…
Reference in a new issue
No description provided.
Delete branch "final-normalization"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Operator directive: "Find all normalization steps in the code and optimize for a single final normalization just before write and display."
The normalization inventory (what was found)
chirp.generate_double_chirp(ticket 41b)cfr.cfr_reducecomb.generate_combpeak == max(|scales|)— the Level definition for tones (kept)sig_io.write_sigclip(round(v·2¹⁵))— over-full-scale signals clip (distortion)The gap: only the double chirp normalized — every other over-scale combination (AGWN's ~4σ noise peaks, Level-100 waveforms after the band/notch filter's passband ripple nudged the peak) hit the writer's clip or landed off-scale.
The fix — one normalization point
pipeline.apply_post_chainends with a scale-down-only peak guard (after windowing, before returning — both the SigV3.1 write and the preview display see it):> 1.0 + 1e-9→ scaled to exactly full scale (no clipping; the 41b semantics generalized to every waveform)Level= % of full scale is preserved (a Level-50 comb stays at 0.5; a Level-100 chirp sits at its post-filter peak, now pinned to 1.0)1 + 2e-16) must not trigger a pointless renormalization — the writer's 1-ulp clip is invisiblechirp.generate_double_chirpdrops its base-level step (subsumed; the COLA repeat is linear, so the later division is equivalent) — the generator is scale-faithful. CFR's per-pass renormalization stays (its own §5.3.1 semantics).Test updates (the pipeline contract changed by directive)
test_pipeline: the pinned fixtures move to sub-full-scale amplitudes (0.3·tones,0.2·noise,/1500arange) so the no-copy passthrough and bitwise contracts stay meaningful (the guard is a no-op at/below full scale)test_double_chirp: the single-block test asserts the raw phase-optimised sum (scale-faithful generator); the normalization test moved to the pipeline level (raw over-scale → chained peak == 1.0, single-block and repeated)Spec
New §5.3.5 Final normalization; the §5.3 chain diagram gains the step; §5.2.1c's level semantics point at the single guard.
Gate
pytest: 1288 passed / 64 skipped (headless tier), coverage 93.62 %ruff+mypy: clean