""" Decoder v1: nibble-pair signed deltas in 10 NN blocks, 4-channel round-robin. """ import sys sys.path.insert(0, ".") from analysis.load_bundle import load_bundle def s4(n): return n if n < 8 else n - 16 def walk_blocks(body, start): i = start blocks = [] while i + 1 < len(body): t0, t1 = body[i], body[i + 1] if t0 == 0x10 and t1 % 4 == 0 and 0 < t1 <= 0xFC: length = t1 // 2 + 2 data = bytes(body[i + 2 : i + length]) blocks.append(("10", t1, data)) i += length elif t0 == 0x20 and t1 % 4 == 0 and 0 < t1 <= 0xFC: length = t1 + 2 data = bytes(body[i + 2 : i + length]) blocks.append(("20", t1, data)) i += length elif t0 == 0x00 and t1 % 4 == 0: blocks.append(("00", t1, b"")) i += 2 elif t0 == 0x30 and t1 % 4 == 0 and 0 < t1 <= 0x10: length = t1 * 4 data = bytes(body[i + 2 : i + length]) blocks.append(("30", t1, data)) i += length elif t0 == 0x40 and t1 == 0x02: length = 20 data = bytes(body[i + 2 : i + length]) blocks.append(("40", t1, data)) i += length else: blocks.append(("??", t0, bytes(body[i:i+8]))) break return blocks def decode_v1(body, start, n_samples): """Decode by accumulating nibble-pair deltas from all 10 NN blocks.""" blocks = walk_blocks(body, start) # 4 channels: T, V, L, M cur = [0, 0, 0, 0] out = [[], [], [], []] sample_index = 0 # how many sample-sets emitted for typ, NN, data in blocks: if typ == "10": # 2 nibbles per byte, round-robin TVLM for byte in data: for nib in ((byte >> 4) & 0xF, byte & 0xF): ch = sample_index % 4 cur[ch] += s4(nib) out[ch].append(cur[ch]) sample_index = (sample_index + 1) // 4 * 4 + (sample_index + 1) % 4 # ? sample_index += 1 # We emit per-nibble, but the structure is unclear elif typ == "20": # int8 absolute or delta? for byte in data: v = byte if byte < 128 else byte - 256 ch = sample_index % 4 cur[ch] = v # treat as absolute out[ch].append(cur[ch]) sample_index += 1 return out def main(): b = load_bundle("event-c") body = b.body truth_T = [round(v * 200) for v in b.samples["Tran"]] truth_V = [round(v * 200) for v in b.samples["Vert"]] truth_L = [round(v * 200) for v in b.samples["Long"]] # Find start for s in range(15): if body[s] == 0x10 and body[s+1] % 4 == 0 and 0 < body[s+1] <= 0xFC: start = s break blocks = walk_blocks(body, start) # Print block-by-block what's in each print(f"Total blocks: {len(blocks)}") bytes_processed = 0 for typ, NN, data in blocks[:30]: print(f" type={typ} NN=0x{NN:02x} data_len={len(data)} data_hex={data[:32].hex(' ')}{'...' if len(data) > 32 else ''}") if __name__ == "__main__": main()