From 00edb0cfb8f38ebd990dc91697047d2b55e489fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=B9=96=CC=B6=CC=B6=CC=B6=DB=A3=DB=A3=DB=9C=DB=9C=CD=9C?= =?UTF-8?q?=CE=B6=CD=9C=CD=A1=20Sage?= Date: Mon, 29 Dec 2025 21:12:11 +0300 Subject: [PATCH 1/2] Create Agilent/Rigol pattern waveform parser feat(patterns): add Agilent/Rigol wavebin waveform parser Adds a new Pattern Language script to parse `.bin` waveform files exported from Agilent, Keysight, and Rigol oscilloscopes. Features: - Supports File Header versions 1, 3, and 10. - Parses nested Waveform and Data headers. - Automatically handles variable-length data buffers (float32 and u8). - Includes auto-load pragmas for magic bytes 'AG' and 'RG'. - Organizes sample data into inspectable arrays in the Pattern Data view. Based on https://github.com/sam210723/wavebin/ --- patterns/wavebin.hexpat | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 patterns/wavebin.hexpat diff --git a/patterns/wavebin.hexpat b/patterns/wavebin.hexpat new file mode 100644 index 00000000..a67897ff --- /dev/null +++ b/patterns/wavebin.hexpat @@ -0,0 +1,80 @@ +#pragma pattern_name Agilent/Rigol Waveform +#pragma file_extension bin +#pragma magic [ 41 47, 52 47 ] @ 0x00 // Matches "AG" or "RG" at offset 0 + +#include + +// Helper: Convert ASCII version string to integer +fn version_to_int(u32 addr) { + u8 tens = u8(std::mem::read_unsigned(addr, 1)) - 48; + u8 ones = u8(std::mem::read_unsigned(addr + 1, 1)) - 48; + return (tens * 10) + ones; +}; + +struct FileHeader { + char magic[2]; + char version_string[2]; + u16 v_val = version_to_int(addressof(version_string)); + + if (v_val == 1 || v_val == 10) { + u32 file_size; + u32 num_waveforms; + } else if (v_val == 3) { + u64 file_size; + u32 num_waveforms; + } +} [[static]]; + +FileHeader header @ 0x00; + +struct WaveformHeader { + u8 length; + s32 wave_type; + s32 buffers; + s32 points; + s32 average; + float x_d_range; + double x_d_origin; + double x_increment; + double x_origin; + s32 x_units; + s32 y_units; + char date[16]; + char time[16]; + char frame[24]; + char label[16]; + double time_tags; + u32 segment; +} [[static]]; + +struct DataHeader { + u8 length; + s16 data_type; + s16 bits_per_pixel; + + if (header.v_val == 3) { + u64 buffer_length; + } else { + u32 buffer_length; + } +} [[static]]; + +struct Waveform { + WaveformHeader wave_header; + DataHeader data_header; + + // Calculate sample count + u32 sample_count = (data_header.data_type == 6) ? + data_header.buffer_length : + (data_header.buffer_length / 4); + + // This block parses the actual voltage/digital values + if (data_header.data_type == 6) { + u8 samples[sample_count] [[name("Digital Samples"), color("00FF00")]]; + } else { + float samples[sample_count] [[name("Analog Samples"), color("00FFFF")]]; + } +} [[static]]; + +// Placement of the waveform array +Waveform waveforms[header.num_waveforms] @ $; \ No newline at end of file From ad704994997dcdf781255364c53605ccdeca75ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E0=B9=96=CC=B6=CC=B6=CC=B6=DB=A3=DB=A3=DB=9C=DB=9C=CD=9C?= =?UTF-8?q?=CE=B6=CD=9C=CD=A1=20Sage?= Date: Mon, 29 Dec 2025 21:43:34 +0300 Subject: [PATCH 2/2] Minor fixup --- patterns/wavebin.hexpat | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/patterns/wavebin.hexpat b/patterns/wavebin.hexpat index a67897ff..c908f3c6 100644 --- a/patterns/wavebin.hexpat +++ b/patterns/wavebin.hexpat @@ -1,7 +1,9 @@ -#pragma pattern_name Agilent/Rigol Waveform +#pragma author kenkit +#pragma description Agilent/Rigol Waveform #pragma file_extension bin #pragma magic [ 41 47, 52 47 ] @ 0x00 // Matches "AG" or "RG" at offset 0 + #include // Helper: Convert ASCII version string to integer