Vital File Format

Vital File Format Specification

Introduction

  • The vital file is a binary file format used by VitalRecorder for saving vital signs and waveforms.
  • It is a single gzip-compressed binary file starting with 1F 8B 08 00.
  • It contains a header and a body part.
  • Multi-byte variables are encoded using little-endian byte order.
  • All data structures are aligned on 1-byte boundaries.
    • Caution: Some compilers use 4-byte alignment implicitly. For Visual Studio, use #pragma pack(push, 1) / #pragma pack(pop).

Data Formats

String

  • Strings are encoded in UTF-8.
  • A string field consists of a 4-byte length (excluding the length field itself) followed by a character array of the specified length.
  • Caution: The string does not include a trailing NULL (\0) character.

Time

  • Times are stored in UTC.
  • UTC can be converted to local time using the time zone bias (offset) in the header:
    • UTC = local_time + tzbias
  • All time values are represented as the number of seconds since 1970-01-01 00:00:00 UTC in IEEE 754 double format.
  • This is compatible with Unix timestamps and convenient for arithmetic operations.
  • The decimal part represents sub-second precision. Because the Unix timestamp for year 2020 is approximately 1,606,780,800 (requiring 31 bits for the integer part) and IEEE 754 double has 52 bits of fraction, approximately 21 bits remain for sub-second representation, giving roughly 1 microsecond resolution.

The total length of the header is 10 + headerlen bytes.

The vital file does not include the number or length of tracks in the header. You must parse the body to discover tracks and records. This is because VitalRecorder cannot know when recording will stop, and tracks can be added at any time during recording.

The header can be extended by increasing headerlen. Parsers should use headerlen to determine which optional fields are present.

NameTypeLengthDescription
signBYTE[4]4"VITA"
format_verDWORD4File format version, currently 3
headerlenWORD2Header length after this field, currently 27
tzbiasshort2Time zone bias: the difference, in minutes, between UTC and local time. For example, Korea (UTC+9) uses -540.
inst_idDWORD4Instance ID assigned when the program starts. Used to verify whether multiple vital files were recorded continuously in the same VitalRecorder session. Files with the same inst_id can share track IDs.
prog_verDWORD4VitalRecorder version
dtstartdouble8(optional, headerlen >= 26) File start time as Unix timestamp
dtenddouble8(optional, headerlen >= 26) File end time as Unix timestamp
packedBYTE1(optional, headerlen >= 27) 0 = streaming format (default), 1 = packed storage format

Time Zone Conversion Example

time_t t = (time_t)(dt - tzbias * 60);  // UTC -> local time in seconds
struct tm *ptm = gmtime(&t);            // seconds -> year, month, day, hour, minute, second

Packed Mode (packed = 1)

When packed is set to 1, the file uses packed storage format with these guarantees:

  • WAV tracks: All waveform records for each track are merged into a single REC. Gaps between consecutive records are filled with NaN samples (see table below). This allows direct sample access by index: sample_time = trk_dtstart + sample_index / srate.
  • NUM/STR tracks: Records for each track appear consecutively and are sorted by time.
  • Track grouping: All RECs belonging to the same track are stored consecutively (track by track).
  • TRKINFO fields: Each TRKINFO includes reclen, dtstart, and dtend for the track.

NaN Values by Format Type

FormatNaN ValueDescription
FMT_FLOAT (1)NaNIEEE 754 NaN
FMT_DOUBLE (2)NaNIEEE 754 NaN
FMT_CHAR (3)-128signed byte min
FMT_BYTE (4)255unsigned byte max
FMT_SHORT (5)-32768signed short min
FMT_WORD (6)65535unsigned short max
FMT_LONG (7)-2147483648signed long min
FMT_DWORD (8)4294967295unsigned long max

Body

The body is a sequence of packets. Since packet lengths are not constant, there is no way to directly index a specific packet without reading sequentially. However, you can skip unwanted packet types using the datalen field.

Packet Structure

NameTypeLengthDescription
typeBYTE1Packet type (see below)
datalenDWORD4Length of data (excludes type and datalen fields). For unknown types, skip datalen bytes.
dataBYTE[]datalenContents depend on type

Packet Types

ValueNameDescription
0SAVE_TRKINFOTrack information
1SAVE_RECData record (waveform, numeric, or string)
6SAVE_CMDCommand
9SAVE_DEVINFODevice information
10SAVE_RAWRaw protocol data (for debugging; contains timestamp, port name, direction flag, and raw bytes)

DEVINFO (type = 9)

Stores device information. Must be saved before the corresponding devid is used in any TRKINFO.

  • If devid is 0, it indicates VitalRecorder itself (e.g., filter-generated tracks, event markers).
  • A new DEVINFO can appear for the same devid within a file; the new values overwrite the previous ones.
  • devid and trkid are meaningful only within the same file.
  • VitalRecorder assigns the same devid to the same device type connected to the same physical port, even across program restarts.
NameTypeLengthDescription
devidDWORD4Device identifier
typenamestring4+lenDevice type (e.g., BIS, Intellivue)
devnamestring4+lenDevice name
portstring4+lenPort information (e.g., COM1, 192.168.1.100:4343). Devices with the same type and port are generally considered the same device.

TRKINFO (type = 0)

Stores track information. Must appear before the first REC with the corresponding trkid. Records with an unknown trkid should be ignored.

  • Tracks are identified by trkid, a 2-byte integer. The numeric value itself has no inherent meaning and may change between program executions.
  • Track display order is determined by order of appearance and the CMD_TRK_ORDER command, not by trkid value.
  • A track with devid = 0 and name EVENT is treated specially: it is displayed in the event bar rather than as a separate track.
NameTypeLengthDescription
trkidWORD2Track ID
rec_typeBYTE1TYPE_WAV = 1, TYPE_NUM = 2, TYPE_STR = 5
recfmtBYTE1Data format (see below)
namestring4+lenTrack name
unitstring4+lenUnit (e.g., bpm, mmHg, mV)
minvalfloat4Display minimum value
maxvalfloat4Display maximum value
colorDWORD44-byte ARGB color
sratefloat4Sample rate (Hz), used for WAV tracks
adc_gaindouble8measured_value = adc_offset + saved_value * adc_gain
adc_offsetdouble8See above
montypeBYTE1Physiologic meaning of the track (see montype table)
devidDWORD4Device ID that created this track
reclenDWORD4(optional, packed mode) Total byte length of all REC packets for this track
trk_dtstartdouble8(optional, packed mode) Start time of the first record
trk_dtenddouble8(optional, packed mode) End time of the last record

Record Format (recfmt)

ValueNameSizeDescription
0FMT_NULL0For TYPE_STR
1FMT_FLOAT432-bit IEEE 754 float
2FMT_DOUBLE864-bit IEEE 754 double
3FMT_CHAR1Signed 8-bit integer
4FMT_BYTE1Unsigned 8-bit integer
5FMT_SHORT2Signed 16-bit integer
6FMT_WORD2Unsigned 16-bit integer
7FMT_LONG4Signed 32-bit integer
8FMT_DWORD4Unsigned 32-bit integer

REC (type = 1)

Stores time-stamped data (measured samples, sample arrays, or strings).

NameTypeLengthDescription
infolenWORD2Length of the record header, currently 10
dtdouble8Measurement timestamp (Unix time, UTC)
trkidWORD2Track ID
valuesBYTE[]datalen - infolen - 2Record-type-specific values (see below)

WAV Record Values

Samples continuously measured from time dt, stored as an array. The sample rate and data type come from the TRKINFO.

NameTypeLengthDescription
numDWORD4Number of samples
valsrecfmt[num]sizeof(recfmt) * numSample data

NUM Record Values

NameTypeLengthDescription
valrecfmtsizeof(recfmt)Single numeric value

STR Record Values

NameTypeLengthDescription
unusedDWORD4Not used
svalstring4+lenString value

CMD (type = 6)

Command packets. Unknown commands should be skipped using the packet's datalen.

NameTypeLengthDescription
cmdBYTE1Command type

CMDTRKORDER (cmd = 5)

Defines the display order of tracks.

NameTypeLengthDescription
cntWORD2Number of tracks
trkidsWORD[cnt]cnt * 2Array of track IDs in display order

CMDRESETEVENTS (cmd = 6)

Removes all event markers prior to this command. No additional data.


Monitor Type Codes (montype)

The montype field in TRKINFO specifies the physiologic meaning of the track. This enables applications to identify and display parameters consistently regardless of track naming conventions.

ECG

ValueNameDescription
1ECG_WAVECG waveform
2ECG_HRHeart rate
3ECG_PVCPVC count

Arterial Blood Pressure (Invasive)

ValueNameDescription
4IABP_WAVABP waveform
5IABP_SBPABP systolic
6IABP_DBPABP diastolic
7IABP_MBPABP mean

Pulse Oximetry (PLETH)

ValueNameDescription
8PLETH_WAVPleth waveform
9PLETH_HRPulse rate
10PLETH_SPO2SpO2

Respiration

ValueNameDescription
11RESP_WAVRespiration waveform
12RESP_RRRespiratory rate

CO2

ValueNameDescription
13CO2_WAVCO2 waveform
14CO2_RRCO2 respiratory rate
15CO2_CONCEtCO2 concentration

Non-Invasive Blood Pressure

ValueNameDescription
16NIBP_SBPNIBP systolic
17NIBP_DBPNIBP diastolic
18NIBP_MBPNIBP mean

Temperature

ValueNameDescription
19BTBody temperature

Central Venous Pressure

ValueNameDescription
20CVP_WAVCVP waveform
21CVP_CVPCVP value

EEG / Brain Monitoring

ValueNameDescription
22EEG_BISBIS index
23EEG_SEFSpectral Edge Frequency
24EEG_MFMedian Frequency
25EEG_SRSuppression Ratio
26EEG_EMGEMG power
27EEG_SQISignal Quality Index
28EEG_WAVEEG waveform

Airway

ValueNameDescription
29AWP_WAVAirway pressure waveform
30PEEPPEEP
31PIPPeak inspiratory pressure
32TVTidal volume
33MVMinute ventilation
34COMPLIANCELung compliance
35RESISTANCEAirway resistance

Anesthetic Agents

ValueNameDescription
36AGENT1_NAMEAgent 1 name (string)
37AGENT1_CONCAgent 1 concentration
38AGENT2_NAMEAgent 2 name (string)
39AGENT2_CONCAgent 2 concentration
40AGENT3_NAMEAgent 3 name (string)
41AGENT3_CONCAgent 3 concentration

Drug Infusion

ValueNameDescription
42DRUG1_NAMEDrug 1 name (string)
43DRUG1_CEDrug 1 effect-site concentration
44DRUG1_RATEDrug 1 infusion rate
45DRUG2_NAMEDrug 2 name (string)
46DRUG2_CEDrug 2 effect-site concentration
47DRUG2_RATEDrug 2 infusion rate
48DRUG3_NAMEDrug 3 name (string)
49DRUG3_CEDrug 3 effect-site concentration
50DRUG3_RATEDrug 3 infusion rate
51DRUG4_NAMEDrug 4 name (string)
52DRUG4_CEDrug 4 effect-site concentration
53DRUG4_RATEDrug 4 infusion rate

Cerebral Oximetry

ValueNameDescription
54RSO2_LRegional cerebral O2 saturation (left)
55RSO2_RRegional cerebral O2 saturation (right)

Additional EEG

ValueNameDescription
56ENT_SEState Entropy
57ENT_REResponse Entropy
58PSIPatient State Index
59EEG_SEFLSEF left
60EEG_SEFRSEF right
61EEGL_WAVEEG left waveform
62EEGR_WAVEEG right waveform

Advanced Pulse Oximetry

ValueNameDescription
63PVIPleth Variability Index
64SPHBSpHb (non-invasive hemoglobin)
65ORIOxygen Reserve Index

Pulmonary Artery

ValueNameDescription
66PAP_WAVPA waveform
67PAP_SBPPA systolic
68PAP_MBPPA mean
69PAP_DBPPA diastolic

Femoral Artery

ValueNameDescription
70FEM_WAVFemoral artery waveform
71FEM_SBPFemoral systolic
72FEM_MBPFemoral mean
73FEM_DBPFemoral diastolic

Intracranial Pressure

ValueNameDescription
74ICP_WAVICP waveform
75ICPICP value
76CPPCerebral perfusion pressure

Neuromuscular Monitoring

ValueNameDescription
77TOF_RATIOTrain-of-Four ratio
78TOF_CNTTOF count
79PTC_CNTPost-tetanic count

SKNA (Skin Sympathetic Nerve Activity)

ValueNameDescription
80ISKNA_WAVIntegrated SKNA waveform
81SKNA_WAVSKNA waveform
82ASKNAAverage SKNA

Miscellaneous

ValueNameDescription
83ALARM_LEVELAlarm level
84ALARM_MSGAlarm message (string)
85ANIIANI instantaneous
86ANIMANI mean
87HPIHypotension Prediction Index
88EEG_QCONqCON index
89EEG_QNOXqNOX index
90RRARespiratory rate acoustic
91RRA_WAVRRA waveform

Additional Waveforms

ValueNameDescription
92FLOW_WAVFlow waveform
93VOLUME_WAVVolume waveform

Fetal Monitoring

ValueNameDescription
94FETAL_HRFetal heart rate
95UACTUterine activity

Filter Outputs

ValueNameDescription
96-111FILT11 .. FILT82Filter output channels (8 filters x 2 outputs each)

Note: Applications should treat unknown montype values gracefully; new types may be added in future versions.