Code to read and write EEG-edf+ files. I modified existing code to read simple edf-files for support of edf+ (including annotations)
fhz (2020). Read / Write EDF+-Files (https://www.mathworks.com/matlabcentral/fileexchange/36530-read-write-edf-files), MATLAB Central File Exchange. Retrieved .
I would recommand extreme care if using this library. I used it to save data in EDF+ format and I had weird results while doing my analysese. When I changed the EDF writing function for the one proposed here (https://ch.mathworks.com/matlabcentral/fileexchange/36530-read---write-edf+-files), it solved my issues. If you are serious about writing EDF files in Matlab, it might be worth comparing the output of these two library and make some sanity checks.
An updated version of lab_write_edf can be found here: http://www.mathworks.com/matlabcentral/fileexchange/61189
The updated version can be found here: http://www.mathworks.com/matlabcentral/fileexchange/61189
Crashes on line 185 when the original file contains only annotations and data is  at this point. Need to put a check in for this. Thanks.
Error using reshape
Size can only have one unknown dimension.
Error in ReadEDF (line 66)
Ch_data=reshape(Ch_data, , header.records);
Thank you for the code! small bug fix.
insert line 166 in lab_write_edf with:
header.second = 0;
adjust line 251 to:
fprintf(fid, '%02i.%02i.%02i', header.hour, header.minute, header.second); % time as hh.mm.ss
I modified the write function for using the full range of values for each signals.
Before the physical max & min were the same for all signals and set to the highest and lowest values.
Now these values are determined for each signal, separately, and data is expanded or shrank to cover the full range of values.
Replace the lines 81-104 of lab_write_edf with :
% Scale and convert to in16 (data)
% Rounds max-min to the highest nearest int
% Works for most of the cases, but we should consider using scientific
% notation for very little values
maxV = ceil(max(data, , 2));
minV = floor(min(data, , 2));
% Physical max can't be equal to physical min
eqInd = find(maxV == minV);
maxV(eqInd) = maxV(eqInd) + 1;
maxVc = repmat(32767,size(data,1),1);
minVc = repmat(-32767,size(data,1),1);
Scale = (maxV - minV) ./ (maxVc - minVc);
offset = maxV - (Scale .*maxVc);
data = data - repmat(offset, 1, size(data,2));
data = bsxfun(@rdivide, data, Scale);
data = int16(data);
clearvars Scale offset
Thank you for your work.
Bug in line 134: Please move line 128 below the 128-130 if statement, as the statement will chance eventchannels and prevent a proper reshape due to size change.
Good work, but I find some bugs:
In lab_read_edf.m, lines 83-84: positions are repeated from line 82, thus mistaken. They should be (180:181) and (183:184), respectively.
In lab_read_edf.m, line 139:
data = reshape(data,hdr.numbersperrecord(1),hdr.channels,hdr.records);
I get an error. It is because the number of samples may be different in each record.
Corrected a bug in lab_write_edf (last lines of code had to be deleted)
8.7.2013: corrected bug in lab_write_edf (thanks to Rune Paamand)
updated lab_read_edf to support again edf-files without annotations (broken since last update)
updated read_edf to support misc 'number of records'
Optimized read_edf to support scale and DC of data
fixed some bugs in write_edf