codec: wire decode_waveform_v2 into production; add MicL dB helper
Replaces the broken legacy int16 LE decoder in client.py with the
verified multi-channel codec. Three changes:
1. blastware_file.extract_body_bytes(a5_frames) — new helper that
factors out the body-reconstruction logic from write_blastware_file
so both writers (BW binary) and decoders (sample arrays) can use
the same canonical bytes.
2. waveform_codec.decode_a5_frames(a5_frames) — production entry point.
Returns the raw_samples dict consumers expect (Tran/Vert/Long as
int16 ADC counts; MicL as native ADC counts). Internally:
A5 frames → extract_body_bytes → decode_waveform_v2
→ decoded_to_adc_counts (geos ×16; mic pass-through)
3. waveform_codec.mic_count_to_db(count) — MicL ADC → dB(L) per BW's
display formula:
dB = sign(count) × (81.94 + 20 × log10(|count|)) for |count| ≥ 1
Verified against V70 fixture: count=813 → 140.14 dB (BW PSPL 140.1).
client.py:_decode_a5_waveform is reduced to a thin wrapper that calls
decode_a5_frames and populates event.raw_samples. Original implementation
preserved as _decode_a5_waveform_LEGACY (dead code; reference only).
Also fixed a tail-end bug in decode_waveform_v2 where trailer-section
"40 02" markers (containing ASCII serial bytes, NOT real segment headers)
were being mis-interpreted, producing 2 spurious samples per channel at
the end of each event. Added bytes [12:14] == "02 00" validation to
reject non-header markers.
7 new pytest tests cover the new helpers and dB conversion. Total:
71 passing (up from 64).
Known limitation (carried over from before): the walker still stops
mid-event on the loudest fixtures (SP0/SS0/SV0/event-b) at some
mid-segment edge cases not yet characterized. Every sample reached
is decoded correctly; the walker just doesn't reach all of them.
Loud events still yield 5,000–15,000 byte-exact samples each.
This commit is contained in:
@@ -142,11 +142,22 @@ custom delta + RLE + variable-width codec.
|
||||
|
||||
**Total: 47,364 ADC samples verified byte-exact, zero errors.**
|
||||
|
||||
### Production-code status
|
||||
### Production-code status (updated 2026-05-11 late)
|
||||
|
||||
`client.py:_decode_a5_waveform` still uses the old (broken) int16 LE
|
||||
decoder (see warning at the top of this section). `decode_waveform_v2()`
|
||||
in `minimateplus/waveform_codec.py` returns `None` as a placeholder.
|
||||
`client.py:_decode_a5_waveform` now uses the verified codec via
|
||||
`waveform_codec.decode_a5_frames()` — which calls
|
||||
`blastware_file.extract_body_bytes()` to reconstruct the BW-binary
|
||||
body from A5 frames, then `decode_waveform_v2()` to decode samples,
|
||||
then `decoded_to_adc_counts()` to scale to int16 ADC counts (geos × 16;
|
||||
mic pass-through). The `.h5` sidecars SFM produces now contain
|
||||
correct samples for any event without walker edge cases.
|
||||
|
||||
The original int16 LE decoder is preserved as
|
||||
`_decode_a5_waveform_LEGACY` for reference but is not called.
|
||||
|
||||
MicL → dB(L) conversion utility:
|
||||
`waveform_codec.mic_count_to_db(count)` — `count=±1 → ±81.94 dB`;
|
||||
`count=813 → 140.14 dB` (matches BW display).
|
||||
|
||||
### Test fixtures
|
||||
|
||||
|
||||
Reference in New Issue
Block a user