fix: update STRT parsing to extract additional bytes for total_samples and pretrig_samples
This commit is contained in:
@@ -171,25 +171,39 @@ the `b'STRT'` magic bytes:
|
||||
```
|
||||
+0..3 b'STRT' magic
|
||||
+4..5 flags 0xFF 0xFE (single-shot) or 0xFF 0xFD (continuous)
|
||||
+6..9 key4 4-byte event key
|
||||
+10..13 prev_key4
|
||||
+14..15 uint16 BE total_samples (full event sample-set count) ← confirmed 4-9-26
|
||||
+16..17 uint16 BE pretrig_samples (pre-trigger sample-set count)
|
||||
+6..9 next_key4 ← key of the NEXT stored event (NOT the current event) ← confirmed 2026-04-14
|
||||
+10..13 prev_key4 ← key of the PREVIOUS stored event ← confirmed 2026-04-14
|
||||
+14..15 UNKNOWN (values seen: 0xDA63=55907, 0xF38F=62351, 0x5685=22149) — NOT total_samples
|
||||
+16..17 UNKNOWN (values seen: 0x0122=290, 0x011A=282, 0x00FA=250) — NOT pretrig_samples
|
||||
+18 uint8 record-MODE byte — NOT rectime in seconds
|
||||
+19..20 typically 0x00 0x00
|
||||
+19..20 0x00 0x00
|
||||
```
|
||||
|
||||
**CONFIRMED field values (2026-04-14) from 3 desk-thump events, firmware S338.17:**
|
||||
|
||||
| Field | What it is | Confirmed |
|
||||
|---|---|---|
|
||||
| +4..5 | 0xFFFE single-shot / 0xFFFD continuous | ✅ |
|
||||
| +6..9 | next_event_key (NOT current) | ✅ 3 events |
|
||||
| +10..13 | prev_event_key | ✅ 3 events |
|
||||
| +18 | mode byte: 0x46 ('F') = single-shot, 0x0E = continuous | ✅ |
|
||||
|
||||
**UNCONFIRMED — total_samples and pretrig_samples locations unknown:**
|
||||
The prior documented offsets (+14..15 for total_samples, +16..17 for pretrig_samples) were
|
||||
WRONG — confirmed by cross-checking STRT-derived rectime against compliance record_time
|
||||
(4-14-26): all 3 events give STRT-derived rectime of 21–61 s vs actual 3.0 s (ratio 7–20×).
|
||||
The "confirmed 4-9-26" note in prior versions was incorrect.
|
||||
|
||||
The true offsets for total_samples and pretrig_samples within STRT have not been located.
|
||||
**Until they are found, `_decode_a5_waveform` relies on the compliance-config cross-check
|
||||
fallback for all total_samples and pretrig_samples values.**
|
||||
|
||||
**CRITICAL — strt[18] is a record-mode byte, NOT rectime_seconds (confirmed 2026-04-14):**
|
||||
Analysis of 15 distinct STRT records across the 4-9-26 ACH capture shows:
|
||||
- `flags=0xFFFE` (single-shot) → `strt[18] = 0x46` ('F') for EVERY event regardless of duration
|
||||
- `flags=0xFFFD` (continuous) → `strt[18] = 0x0E` for EVERY event regardless of duration
|
||||
|
||||
The actual record duration (post-trigger seconds) must be computed as:
|
||||
```python
|
||||
rectime_seconds = int(round((total_samples - pretrig_samples) / sample_rate))
|
||||
```
|
||||
`_decode_a5_waveform` uses `sample_rate=1024` as a default; the server overrides with
|
||||
`compliance_config.sample_rate` when available. Do NOT use `strt[18]` for rectime.
|
||||
Do NOT use `strt[18]` for rectime.
|
||||
|
||||
**Pre-trigger time is separate from record_time (confirmed 2026-04-14):**
|
||||
Blastware documentation states: "The default Time Scale is -0.25 second to 1 second — this
|
||||
@@ -197,17 +211,17 @@ negative number accounts for the pre-trigger set for compliance monitoring." Th
|
||||
- `record_time` (3.0 s) is POST-TRIGGER duration only
|
||||
- Pre-trigger = 0.25 s = 256 samples at 1024 sps (compliance monitoring standard default)
|
||||
- The pre-trigger field has NOT yet been located in the raw compliance config bytes
|
||||
- When STRT layout is invalid, `_decode_a5_waveform` falls back to pretrig = 0.25 × sr
|
||||
- `_decode_a5_waveform` falls back to pretrig = 0.25 × sr from compliance standard
|
||||
- TODO: locate pretrig_time offset in ComplianceConfig — search around anchor or channel blocks
|
||||
|
||||
The device bulk-streams zero-padded frames BEYOND the configured record window. The
|
||||
viewer clips `displayCount = total_samples = pretrig + post_trig` to exclude this padding.
|
||||
|
||||
**Sanity check — pretrig_samples must be less than total_samples:**
|
||||
If `pretrig_samples >= total_samples` the STRT parse is invalid. Possible causes:
|
||||
DLE-stuffed `0x10` byte within prev_key4 or key4 shifted field offsets, or a different
|
||||
STRT record variant. `_decode_a5_waveform` logs `raw strt[0:21]` at WARNING level and
|
||||
clamps `pretrig_samples = 0` so the viewer renders (showing the full waveform from t=0).
|
||||
**Validity checks in `_decode_a5_waveform`:**
|
||||
Check 1: `pretrig_samples >= total_samples` → invalid (original check).
|
||||
Check 2: STRT-derived rectime differs from `compliance_config.record_time` by more than 2×
|
||||
→ invalid. Both failures fall back to the compliance-config derived values.
|
||||
`_decode_a5_waveform` logs `raw strt[0:21]` at WARNING level on any failure.
|
||||
Observed once (2026-04-14) with `strt[16:18] = 0x41 0x01` → pretrig=16641 (impossible).
|
||||
Root cause not yet identified — capture the warning log hex dump to diagnose.
|
||||
|
||||
|
||||
@@ -1389,11 +1389,18 @@ def _decode_a5_waveform(
|
||||
#
|
||||
# NOTE: strt[8:10] is the LOWER 2 bytes of key4, NOT total_samples.
|
||||
# Confirmed from raw_rx capture (4-9-26): strt[14:16] = total_samples. ✅
|
||||
strt = w0[strt_pos : strt_pos + 21]
|
||||
# Extract 32 bytes so we can see past the first 21 — the true total_samples
|
||||
# and pretrig_samples offsets have not yet been confirmed and may be > +20.
|
||||
strt = w0[strt_pos : strt_pos + 32]
|
||||
if len(strt) < 21:
|
||||
log.warning("_decode_a5_waveform: STRT record truncated (%dB)", len(strt))
|
||||
return
|
||||
|
||||
log.info(
|
||||
"_decode_a5_waveform: STRT raw[0:32]: %s",
|
||||
strt[:32].hex(' '),
|
||||
)
|
||||
|
||||
total_samples = struct.unpack_from(">H", strt, 14)[0]
|
||||
pretrig_samples = struct.unpack_from(">H", strt, 16)[0]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user