Run the full ISO 532-1 Annex B loudness validation from in-repo signals (#90)
* test: run the full ISO 532-1 Annex B validation from in-repo signals
Commit the ISO 532-1:2017 electronic-attachment validation data under
tests/data/iso532_1/ with a README documenting provenance, ISO copyright,
the source URL and a removal policy. This turns the twelve previously
skipped Annex B.5 technical-signal tests into always-on checks:
- Add the twelve recorded B.5 technical signals (byte-identical to the ISO
attachment) and gather the existing tone-pulse/level/expected fixtures
into the same folder.
- Read the WAVs with the stdlib `wave` module (no soundfile dependency) and
scale per Annex B.1 (full scale = 100 dB SPL -> 2*sqrt(2) Pa peak).
- Validate each signal in the sound field its ISO results workbook was
computed in; signal 15 (vehicle interior) is diffuse, the rest free. This
was the sole failing case and it is a field mismatch, not an algorithm
error. Nmax now reproduces the workbook to < 0.01 % on all twelve, so the
Nmax tolerance is tightened from 5 % to 0.1 %.
- Add two Annex B.5 rows (free + diffuse technical recording) to the
numerical conformance report; docs/CONFORMANCE.md regenerated (34/34).
Also clean the pre-existing mypy --strict debt in scripts/ (13 findings in
conformance_report.py, generate_graphs.py and generate_diagrams.py) and
extend the lint gate and CI to type-check scripts/ alongside src/ so it
cannot regress.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* test: harden ISO 532-1 WAV loading and graceful data absence (PR review)
Addresses the PR #90 bot review:
- Read WAVs with the little-endian dtype '<i2' (RIFF is little-endian, not
host-native) and keep only channel 0 of any multi-channel file, in both
the test reader and the conformance helper.
- Load the Annex B expected-values JSON defensively: the module no longer
crashes on import when the ISO data folder is absent; the six data-backed
tests carry a `requires_iso_data` skip marker instead, honouring the
README's removal policy while the synthetic-signal tests keep running.
- Raise a clear FileNotFoundError (not an IndexError) in the conformance
helper when no Annex B.5 WAV matches.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* test: unify the ISO 532-1 data root behind ISO532_1_TESTDATA (PR review)
CodeRabbit noted the presence gate and expected-values JSON were tied to
the hard-coded in-repo path while the Annex B.5 lookup honoured the
ISO532_1_TESTDATA override, so a valid override with the packaged JSON
absent would still skip. Derive the single DATA root from the override
(defaulting to the in-repo fixtures) and read the JSON, the presence gate
and the B.5 recordings all from it; drop the separate ISO_DIR.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP
* fix: mypy --strict on PR-C script code surfaced by the merged gate
Merging main (PR #89) brought the ISO 9613-2/9612 figure and conformance
helpers under this branch's extended `mypy src scripts` gate for the first
time: annotate the ISO 9612 Annex D task builder's return type and cast a
numpy int bar-label position to float.
Claude-Session: https://claude.ai/code/session_01HUHMx4dxDes2t5UPQ25djP