0001 function data = LoadBinary(filename,varargin)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 nChannels = 1;
0046 precision = 'int16';
0047 skip = 0;
0048 frequency = 20000;
0049 channels = [];
0050 start = 0;
0051 duration = Inf;
0052 offset = 0;
0053 nRecords = Inf;
0054 time = false;
0055 records = false;
0056
0057 if nargin < 1 | mod(length(varargin),2) ~= 0,
0058 error('Incorrect number of parameters (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0059 end
0060
0061
0062 for i = 1:2:length(varargin),
0063 if ~ischar(varargin{i}),
0064 error(['Parameter ' num2str(i+3) ' is not a property (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).']);
0065 end
0066 switch(lower(varargin{i})),
0067 case 'frequency',
0068 frequency = varargin{i+1};
0069 if ~isdscalar(frequency,'>0'),
0070 error('Incorrect value for property ''frequency'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0071 end
0072 case 'start',
0073 start = varargin{i+1};
0074 if ~isdvector(start),
0075 error('Incorrect value for property ''start'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0076 end
0077 if start < 0, start = 0; end
0078 time = true;
0079 case 'duration',
0080 duration = varargin{i+1};
0081 if ~isdvector(duration,'>=0'),
0082 error('Incorrect value for property ''duration'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0083 end
0084 time = true;
0085 case 'offset',
0086 offset = varargin{i+1};
0087 if ~isivector(offset),
0088 error('Incorrect value for property ''offset'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0089 end
0090 if offset < 0, offset = 0; end
0091 records = true;
0092 case {'nrecords','samples'},
0093 nRecords = varargin{i+1};
0094 if ~isivector(nRecords,'>=0'),
0095 error('Incorrect value for property ''nRecords'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0096 end
0097 if length(nRecords) > 1 && any(isinf(nRecords(1:end-1))),
0098 error('Incorrect value for property ''nRecords'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0099 end
0100 records = true;
0101 case 'nchannels',
0102 nChannels = varargin{i+1};
0103 if ~isiscalar(nChannels,'>0'),
0104 error('Incorrect value for property ''nChannels'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0105 end
0106 case 'channels',
0107 channels = varargin{i+1};
0108 if ~isivector(channels,'>=0'),
0109 error('Incorrect value for property ''channels'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0110 end
0111 case 'precision',
0112 precision = varargin{i+1};
0113 if ~isastring(precision),
0114 error('Incorrect value for property ''precision'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0115 end
0116 case 'skip',
0117 skip = varargin{i+1};
0118 if ~isiscalar(skip,'>=0'),
0119 error('Incorrect value for property ''skip'' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0120 end
0121 otherwise,
0122 error(['Unknown property ''' num2str(varargin{i}) ''' (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).']);
0123 end
0124 end
0125
0126
0127 if time && records,
0128 error(['Data subset can be specified either in time or in records, but not both (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).']);
0129 end
0130
0131
0132 if isempty(channels),
0133 channels = 1:nChannels;
0134 end
0135
0136
0137 if any(channels>nChannels),
0138 error('Cannot load specified channels (listed channel IDs inconsistent with total number of channels).');
0139 end
0140
0141
0142 if ~exist(filename),
0143 error(['File ''' filename ''' not found.']);
0144 end
0145 f = fopen(filename,'r');
0146 if f == -1,
0147 error(['Cannot read ' filename ' (insufficient access rights?).']);
0148 end
0149
0150
0151 sampleSize = 0;
0152 switch precision,
0153 case {'uchar','unsigned char','schar','signed char','int8','integer*1','uint8','integer*1'},
0154 sampleSize = 1;
0155 case {'int16','integer*2','uint16','integer*2'},
0156 sampleSize = 2;
0157 case {'int32','integer*4','uint32','integer*4','single','real*4','float32','real*4'},
0158 sampleSize = 4;
0159 case {'int64','integer*8','uint64','integer*8','double','real*8','float64','real*8'},
0160 sampleSize = 8;
0161 end
0162
0163
0164 if time,
0165 if length(duration) == 1,
0166 duration = repmat(duration,length(start),1);
0167 elseif length(duration) ~= length(start),
0168 error('Start and duration lists have different lengths (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0169 end
0170 dataOffset = floor(start*frequency)*nChannels*sampleSize;
0171 nRecords = floor(duration*frequency);
0172 else
0173 if length(nRecords) == 1,
0174 nRecords = repmat(nRecords,size(offset,1),1);
0175 elseif length(nRecords) ~= length(offset),
0176 error('Offset and number of records lists have different lengths (type ''help <a href="matlab:help LoadBinary">LoadBinary</a>'' for details).');
0177 end
0178 dataOffset = offset*nChannels*sampleSize;
0179 end
0180
0181
0182 fileStart = ftell(f);
0183 status = fseek(f,0,'eof');
0184 if status ~= 0,
0185 fclose(f);
0186 error('Error reading the data file (possible reasons include trying to read past the end of the file).');
0187 end
0188 fileStop = ftell(f);
0189
0190
0191 if isinf(nRecords(end)),
0192 status = fseek(f,dataOffset(end),'bof');
0193 if status ~= 0,
0194 fclose(f);
0195 error('Error reading the data file (possible reasons include trying to read past the end of the file).');
0196 end
0197 lastOffset = ftell(f);
0198 lastNRecords = floor((fileStop-lastOffset)/nChannels/sampleSize);
0199 nRecords(end) = lastNRecords;
0200 end
0201
0202
0203 data = zeros(sum(nRecords)/(skip+1),length(channels));
0204
0205
0206 i = 1;
0207 for k = 1:length(dataOffset),
0208
0209
0210 status = fseek(f,dataOffset(k),'bof');
0211 fileOffset = ftell(f);
0212 if status ~= 0,
0213 fclose(f);
0214 error('Could not start reading (possible reasons include trying to read past the end of the file).');
0215 end
0216
0217
0218 maxNRecords = floor((fileStop-fileOffset)/nChannels/sampleSize);
0219 if nRecords(k) > maxNRecords, nRecords(k) = maxNRecords; end
0220
0221
0222 maxSamplesPerChunk = 10000;
0223 nSamples = nRecords(k)*nChannels;
0224 if nSamples <= maxSamplesPerChunk,
0225 d = LoadChunk(f,nChannels,channels,nRecords(k),precision,skip*sampleSize);
0226 [m,n] = size(d);
0227 if m == 0, break; end
0228 data(i:i+m-1,:) = d;
0229 i = i+m;
0230 else
0231
0232 nSamplesPerChunk = floor(maxSamplesPerChunk/nChannels)*nChannels;
0233 nChunks = floor(nSamples/nSamplesPerChunk)/(skip+1);
0234
0235 for j = 1:nChunks,
0236 d = LoadChunk(f,nChannels,channels,nSamplesPerChunk/nChannels,precision,skip*sampleSize);
0237 [m,n] = size(d);
0238 if m == 0, break; end
0239 data(i:i+m-1,:) = d;
0240 i = i+m;
0241 end
0242
0243 remainder = nSamples - nChunks*nSamplesPerChunk;
0244 if remainder ~= 0,
0245 d = LoadChunk(f,nChannels,channels,remainder/nChannels,precision,skip*sampleSize);
0246 [m,n] = size(d);
0247 if m == 0, break; end
0248 data(i:i+m-1,:) = d;
0249 i = i+m;
0250 end
0251 end
0252 end
0253
0254 fclose(f);
0255
0256
0257
0258 function data = LoadChunk(fid,nChannels,channels,nSamples,precision,skip)
0259
0260 if skip ~= 0,
0261 data = fread(fid,[nChannels nSamples],[int2str(nChannels) '*' precision],skip*nChannels);
0262 else
0263 data = fread(fid,[nChannels nSamples],precision);
0264 end
0265 data = data';
0266
0267 if isempty(data),
0268 warning('No data read (trying to read past file end?)');
0269 elseif ~isempty(channels),
0270 data = data(:,channels);
0271 end