Your recording, as numbers.

Convert EEG and biosignal files to CSV in one command.

npx edf2csv recording.edf
signals.csv4 of 23 channels · 256 Hz
FP1-F7F7-T7T7-P7P7-O1

See what is in the file before you write 108 MB of it

An eight hour sleep study at 100 Hz becomes three million rows. Run it with --info and the tool reads only the header, prints the channel table, estimates the output, and writes nothing.

$ edf2csv sleep-study.edf --info

File       sleep-study.edf
Format     EDF+ (continuous)
Recorded   2002-03-02 23:10:00
Duration   8h 00m 0s  (28,800 records of 1s)
Size       18.7 MB
Patient    X X X X
Recording  Startdate 02-MAR-2002 X X X

Channels   5 signals + 1 annotation channel

#  COLUMN          LABEL           UNIT  RATE    RANGE        OUTPUT
0  EEG Fpz-Cz      EEG Fpz-Cz      uV    100 Hz  -250 to 250  signals_100hz.csv
1  EEG Pz-Oz       EEG Pz-Oz       uV    100 Hz  -250 to 250  signals_100hz.csv
2  EOG horizontal  EOG horizontal  uV    100 Hz  -250 to 250  signals_100hz.csv
3  Resp oro-nasal  Resp oro-nasal  V     10 Hz   -1 to 1      signals_10hz.csv
4  Temp rectal     Temp rectal     degC  1 Hz    34 to 40     signals_1hz.csv

Sampling rates differ, so channels are written to 3 files, one per rate. No
channel is resampled.
Would write 3,196,800 rows, roughly 108 MB, and annotations.csv.

warning: Channels use 3 different sampling rates (100 Hz, 10 Hz, 1 Hz).
         They are written to one file per rate so no channel is resampled.
warning: At least one output file will have more than 1,048,576 rows, which is more than Excel or Numbers can open.
         Use --start and --duration to convert a section, or read the file with
         pandas or R.

It will not invent samples that were never recorded

EDF files routinely mix rates: EEG at 100 Hz next to a thermistor at 1 Hz. One wide table cannot hold both without making the slow channel up, so each rate gets its own file instead.

What the sensor recorded3 samples · 1 Hz · 3 seconds

edf2csv writes exactly these three rows to signals_1hz.csv.

What a resampling reader reports768 values · 765 of them interpolated

Average that column, count its samples, or plot it, and the numbers are not the ones the thermistor produced. No warning is issued.

What lands on disk

A directory named after the recording. Pick a file to see what is inside it.

sleep-study_csv/

One file per sampling rate

The three channels recorded at 100 Hz share a time base, so they share a table. Column names are the labels the file itself uses, spaces and all.

time_s,EEG Fpz-Cz,EEG Pz-Oz,EOG horizontal
0.000,0.061,0.061,0.061
0.010,1.648,1.404,0.916

Checked against the reference reader

Values are compared against pyEDFlib, the reader most of the field already trusts. Not close to it. Identical to it, down to the last bit of the double.

16,943
sample values verified bit-for-bit identical to pyEDFlib
1.4s
to turn a 40 MB recording into a 159 MB CSV
48 MB
heap cap the conversion still completes under
0
runtime dependencies, network calls, or telemetry

Documentation

Getting started
Install edf2csv, convert your first recording, and understand each of the files it writes
CLI reference
Every edf2csv flag, its default and its behaviour, plus exit codes and the stdout versus stderr contract
Output files
Every file a conversion writes, column by column, including time semantics, column naming and value precision
Mixed sampling rates
Why edf2csv writes one CSV per sampling rate instead of resampling, and how to work with the files it produces
EDF+ annotations and gaps
How edf2csv reads the EDF+ annotations channel, exports events, and preserves the real timing of discontinuous recordings
Warnings and errors
Every diagnostic and error code edf2csv can raise, what causes it in a real recording, and what to do about it
How correctness is verified
What edf2csv checks, how it is compared against pyEDFlib, why the conversion formula is arranged the way it is, and what is not claimed
Recipes
Short, tested snippets for loading, scripting and querying the CSV that edf2csv writes
Programmatic API
Read EDF headers, stream raw samples and run conversions from JavaScript or TypeScript, with the real signatures
The EDF format
How EDF, EDF+ and BDF store a recording on disk: the header fields, the record layout, the calibration, and the quirks real files have
Questions and troubleshooting
Answers to common questions, from several signals files to patient data in metadata.json
For AI assistants
The entire documentation as one plain-text file, llms-full.txt, ready to paste into a coding agent.