El_Chaderino

WinEEG magic header

Aug 27th, 2025 (edited)
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.91 KB | None | 0 0
  1. 📂 Mitsar / WinEEG File Notes
  2.  
  3. EEG stack is 3 parts:
  4.  
  5. .EEG = raw stream (INT16 LE, multiplexed frames)
  6.  
  7. .ERD/.VHDR = meta, offsets, chans, fs, calibration pointers
  8.  
  9. .EVT/.VMRK = event / marker table
  10.  
  11. Diff from BrainVision: Mitsar doesn’t keep all calibration in the sidecar. Some of it lives inside the .EEG header itself.
  12.  
  13. 🧩 .EEG Layout (reverse-engineered)
  14.  
  15. Header (0x000–0x3FF)
  16.  
  17. Magic words: 0x0F0E, 0xB7CC, 0x0065 → loader sanity check
  18.  
  19. Channel count, fs, frame size values
  20.  
  21. Calibration table: 1 byte per chan at 0x0326–0x0338
  22.  
  23. EEG chans: 0x0C = 12 µV/bit (default sensitivity)
  24.  
  25. Reduced sets: 0x03 = 3 µV/bit
  26.  
  27. Marker chans untouched (0x0A, 0x00)
  28.  
  29. Some garbage/patient/reserved blocks we don’t care about
  30.  
  31. Data section
  32.  
  33. Multiplexed INT16 LE
  34.  
  35. Frame = n_chans * 2 bytes
  36.  
  37. Alignment is strict: (filesize – header – trailer) % frame_size == 0
  38.  
  39. Trailer
  40.  
  41. Tiny footer/pad/CRC-ish block
  42.  
  43. Size varies (2–34 bytes observed)
  44.  
  45. LB EO EEG → 34 bytes, NP EC → 2 bytes
  46.  
  47. Wrong trailer = loader chokes (seek fail)
  48.  
  49. âš¡ Calibration Hack
  50.  
  51. Breakthrough = those single-byte µV/bit values.
  52.  
  53. Stock = 0x0C (12 µV/bit)
  54.  
  55. Low-sens = 0x03 (3 µV/bit)
  56.  
  57. Ratio checks out (12/3 = 4×).
  58.  
  59. WinEEG multiplies sample × calib byte → µV.
  60.  
  61. If you don’t patch → WinEEG thinks everything is ~0 amplitude → blank grid.
  62.  
  63. Patch EEG chans to 0x01 (1 µV/bit) → traces appear, scaling knob works.
  64.  
  65. 🔧 EDF → Mitsar .EEG Conversion Flow
  66.  
  67. Parse EDF
  68.  
  69. Pull chan count, fs, sample count
  70.  
  71. EDF must be uniform fs across chans (Mitsar doesn’t handle mixed rates)
  72.  
  73. Export raw INT16 LE
  74.  
  75. Scale EDF float → int16
  76.  
  77. Interleave channels (frame-major)
  78.  
  79. Splice into Mitsar template
  80.  
  81. Take a known-good Mitsar .EEG (same chan count)
  82.  
  83. Copy header/trailer verbatim
  84.  
  85. Overwrite middle frames w/ EDF samples
  86.  
  87. Keep head+tail frames if paranoid
  88.  
  89. Patch calibration bytes
  90.  
  91. EEG chans → 0x01 (1 µV/bit)
  92.  
  93. Marker chans (0 + 18) untouched
  94.  
  95. Validate trailer alignment
  96.  
  97. (filesize – 1024 – trailer) % (n_chans*2) == 0
  98.  
  99. Auto-detect trailer size if needed
  100.  
  101. ✅ Rules of the Road
  102.  
  103. Header magics intact → otherwise WinEEG throws seek failed
  104.  
  105. Trailer correct → else misaligned, loader dies
  106.  
  107. Calibration patched → else invisible traces
  108.  
  109. Data is raw int16 LE multiplexed → big endian or planar = nope
  110.  
  111. Sampling interval exact (µs precision) → even tiny fs mismatch = bugged
  112.  
  113. 🎯 EDF → Mitsar Recipe (final)
  114.  
  115. Load EDF + convert → raw int16
  116.  
  117. Grab template .EEG (match chan count)
  118.  
  119. Copy header + trailer unchanged
  120.  
  121. Replace data block (keep markers intact)
  122.  
  123. Patch 0x0327–0x0337 = 0x01 (EEG chans)
  124.  
  125. Save, check alignment, done
  126.  
  127. 👉 TL;DR:
  128. Mitsar .EEG is a template-driven container:
  129. magic header + 1-byte calibration table + raw INT16 frames + fixed-len trailer.
  130.  
  131. Calibration patch was the last lock. Once you flip those bytes, EDF → EEG works and WinEEG plays nice.
Advertisement
Add Comment
Please, Sign In to add comment