00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include <assert.h>
00026 #include <time.h>
00027 #include <stdio.h>
00028 #include <malloc.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031 #include <stdarg.h>
00032 #include <stddef.h>
00033 #include <openedf.h>
00034 #include <unistd.h>
00035 #include <edfmacros.h>
00036 #include <nsutil.h>
00037
00038 #define MAXERRORLEN 1024
00039
00040 static char errorBuffer[MAXERRORLEN];
00041
00042 void setLastError(const char *fmt, ...);
00043
00044 int EDFUnpackInt(const char *inp, int fieldLen)
00045 {
00046 return atoi(EDFUnpackString(inp, fieldLen));
00047 }
00048
00049 double EDFUnpackDouble(const char *inp, int fieldLen)
00050 {
00051 return atof(EDFUnpackString(inp, fieldLen));
00052 }
00053
00054 const char *EDFUnpackString(const char *inp, int fieldLen)
00055 {
00056 static char retbuf[256];
00057 strncpy(retbuf, inp, fieldLen);
00058 retbuf[fieldLen] = '\0';
00059 return retbuf;
00060 }
00061
00062 void storeEDFString(char *packet, size_t memsize, const char *str)
00063 {
00064 char fmt[8];
00065 char buf[257];
00066 sprintf(fmt, "%%- %ds", memsize);
00067 sprintf(buf, fmt, str);
00068 memcpy(packet, buf, memsize);
00069 }
00070
00071
00072 void storeEDFDouble(char *packet, size_t memsize, double d)
00073 {
00074 char buf[64];
00075 sprintf(buf, "%g", d);
00076 storeEDFString(packet, memsize, buf);
00077 }
00078
00079 void storeEDFInt(char *packet, size_t memsize, int i)
00080 {
00081 char buf[64];
00082 sprintf(buf, "%d", i);
00083 storeEDFString(packet, memsize, buf);
00084 }
00085
00086 int EDFEncodePacket(char *packet, const struct EDFDecodedConfig *cfg)
00087 {
00088 int whichChannel, totalChannels;
00089 STOREHFS(dataFormat, cfg->hdr.dataFormat);
00090 STOREHFS(localPatient, cfg->hdr.localPatient);
00091 STOREHFS(localRecorder, cfg->hdr.localRecorder);
00092 STOREHFS(recordingStartDate, cfg->hdr.recordingStartDate);
00093 STOREHFS(recordingStartTime, cfg->hdr.recordingStartTime);
00094 STOREHFI(headerRecordBytes, cfg->hdr.headerRecordBytes);
00095 STOREHFS(manufacturerID, cfg->hdr.manufacturerID);
00096 STOREHFI(dataRecordCount, cfg->hdr.dataRecordCount);
00097 STOREHFD(dataRecordSeconds, cfg->hdr.dataRecordSeconds);
00098 STOREHFI(dataRecordChannels, cfg->hdr.dataRecordChannels);
00099 totalChannels = cfg->hdr.dataRecordChannels;
00100 packet += 256;
00101 for (whichChannel = 0; whichChannel < totalChannels; whichChannel++) {
00102 STORECFS(label, cfg->chan[whichChannel].label);
00103 STORECFS(transducer, cfg->chan[whichChannel].transducer);
00104 STORECFS(dimUnit, cfg->chan[whichChannel].dimUnit);
00105 STORECFD(physMin, cfg->chan[whichChannel].physMin);
00106 STORECFD(physMax, cfg->chan[whichChannel].physMax);
00107 STORECFD(digiMin, cfg->chan[whichChannel].digiMin);
00108 STORECFD(digiMax, cfg->chan[whichChannel].digiMax);
00109 STORECFS(prefiltering, cfg->chan[whichChannel].prefiltering);
00110 STORECFI(sampleCount, cfg->chan[whichChannel].sampleCount);
00111 STORECFS(reserved, cfg->chan[whichChannel].reserved);
00112 }
00113 return 0;
00114 }
00115
00116 void EDFDecodeChannelHeader(struct EDFDecodedChannelHeader *result, const char *packet, int whichChannel, int totalChannels)
00117 {
00118 memset((char *) result, 0, sizeof(*result));
00119 LOADCFS(label);
00120 LOADCFS(transducer);
00121 LOADCFS(dimUnit);
00122 LOADCFD(physMin);
00123 LOADCFD(physMax);
00124 LOADCFD(digiMin);
00125 LOADCFD(digiMax);
00126 LOADCFS(prefiltering);
00127 LOADCFI(sampleCount);
00128 LOADCFS(reserved);
00129 }
00130
00131 void EDFDecodeHeaderPreamble(struct EDFDecodedHeader *result, const char *packet) {
00132 memset((char *) result, 0, sizeof(*result));
00133 LOADHFS(dataFormat);
00134 LOADHFS(localPatient);
00135 LOADHFS(localRecorder);
00136 LOADHFS(recordingStartDate);
00137 LOADHFS(recordingStartTime);
00138 LOADHFI(headerRecordBytes);
00139 LOADHFS(manufacturerID);
00140 LOADHFI(dataRecordCount);
00141 LOADHFD(dataRecordSeconds);
00142 LOADHFI(dataRecordChannels);
00143 }
00144
00145 int readEDFString(struct EDFDecodedConfig *cfg, const char *buf, int len)
00146 {
00147 int i;
00148 if (len >= 256)
00149 EDFDecodeHeaderPreamble(&cfg->hdr, buf);
00150 else {
00151 rprintf("Header too small\n");
00152 return 1;
00153 }
00154 assert(cfg->hdr.dataRecordChannels > 0);
00155 assert(cfg->hdr.dataRecordChannels < MAXCHANNELS);
00156 setEDFHeaderBytes(cfg);
00157 if (len < cfg->hdr.headerRecordBytes) {
00158 rprintf("Header too small\n");
00159 return 1;
00160 }
00161 for (i = 0; i < cfg->hdr.dataRecordChannels; ++i) {
00162 EDFDecodeChannelHeader(&cfg->chan[i], buf+256, i, cfg->hdr.dataRecordChannels);
00163 }
00164 return 0;
00165 }
00166
00167 int writeEDFString(const struct EDFDecodedConfig *cfg, char *buf, int *buflen)
00168 {
00169 int retval;
00170 char pktbuf[(MAXCHANNELS+1) * 256];
00171 retval = EDFEncodePacket(pktbuf, cfg);
00172 if (retval) return retval;
00173 if (cfg->hdr.headerRecordBytes <= *buflen) {
00174 *buflen = cfg->hdr.headerRecordBytes;
00175 memcpy(buf, pktbuf, *buflen);
00176 return 0;
00177 }
00178 else {
00179 *buflen = 0;
00180 return 1;
00181 }
00182 }
00183
00184 int writeEDF(int fd, const struct EDFDecodedConfig *cfg)
00185 {
00186 int retval;
00187 char pktbuf[(MAXCHANNELS+1) * 256];
00188 retval = EDFEncodePacket(pktbuf, cfg);
00189 if (retval) return retval;
00190 retval = write(fd, pktbuf, cfg->hdr.headerRecordBytes);
00191 if (retval != cfg->hdr.headerRecordBytes) {
00192 perror("write");
00193 return 1;
00194 }
00195 return 0;
00196 }
00197
00198 int setEDFHeaderBytes(struct EDFDecodedConfig *cfg)
00199 {
00200 cfg->hdr.headerRecordBytes = 256 * (cfg->hdr.dataRecordChannels + 1);
00201 return 0;
00202 }
00203
00204 int readEDF(int fd, struct EDFDecodedConfig *cfg)
00205 {
00206 int i;
00207 int retval;
00208 char pktbuf[(MAXCHANNELS+1) * 256];
00209 retval = read(fd, pktbuf, 256);
00210 if (retval != 256) {
00211 perror("read");
00212 return 1;
00213 }
00214 EDFDecodeHeaderPreamble(&cfg->hdr, pktbuf);
00215 assert(cfg->hdr.dataRecordChannels > 0);
00216 assert(cfg->hdr.dataRecordChannels < MAXCHANNELS);
00217 setEDFHeaderBytes(cfg);
00218 retval = read(fd, pktbuf+256, cfg->hdr.headerRecordBytes - 256);
00219 if (retval != cfg->hdr.headerRecordBytes - 256) {
00220 perror("read");
00221 return 1;
00222 }
00223 for (i = 0; i < cfg->hdr.dataRecordChannels; ++i) {
00224 EDFDecodeChannelHeader(&cfg->chan[i], pktbuf+256, i, cfg->hdr.dataRecordChannels);
00225 }
00226 return 0;
00227 }
00228
00229
00230 double getSecondsPerSample(const struct EDFDecodedConfig *cfg, int whichChan)
00231 {
00232 return (double) cfg->hdr.dataRecordSeconds / cfg->chan[whichChan].sampleCount;
00233 }
00234
00235 double getSamplesPerSecond(const struct EDFDecodedConfig *cfg, int whichChan)
00236 {
00237 return (double) cfg->chan[whichChan].sampleCount / cfg->hdr.dataRecordSeconds;
00238 }
00239
00240 int getDataRecordChunkSize(const struct EDFDecodedConfig *cfg)
00241 {
00242 int i, sum=0;
00243 for (i = 0; i < cfg->hdr.dataRecordChannels; ++i)
00244 sum += cfg->chan[i].sampleCount;
00245 return sum * BYTESPERSAMPLE;
00246 }
00247
00248 struct EDFInputIterator *newEDFInputIterator(const struct EDFDecodedConfig *cfg)
00249 {
00250 struct EDFInputIterator *edfi;
00251 edfi = calloc(1, sizeof(struct EDFInputIterator));
00252 assert(edfi && "out of memory!");
00253 edfi->cfg = *cfg;
00254 edfi->dataRecordNum = 0;
00255 edfi->sampleNum = 0;
00256 edfi->dataRecord = calloc(1, getDataRecordChunkSize(&edfi->cfg));
00257 assert(edfi->dataRecord && "out of memory!");
00258 return edfi;
00259 }
00260
00261 void freeEDFInputIterator(struct EDFInputIterator *edfi)
00262 {
00263 free(edfi->dataRecord);
00264 edfi->dataRecord = NULL;
00265 free(edfi);
00266 }
00267
00268 int stepEDFInputIterator(struct EDFInputIterator *edfi)
00269 {
00270 edfi->sampleNum += 1;
00271 if (edfi->sampleNum == edfi->cfg.chan[0].sampleCount) {
00272 edfi->sampleNum = 0;
00273 edfi->dataRecordNum += 1;
00274 }
00275 return 0;
00276 }
00277
00278
00279 int readDataRecord(const struct EDFInputIterator *edfi, FILE *fp)
00280 {
00281 int retval;
00282 retval = fseek(fp,
00283 edfi->cfg.hdr.headerRecordBytes +
00284 getDataRecordChunkSize(&edfi->cfg) * edfi->dataRecordNum,
00285 SEEK_SET);
00286 if (retval != 0) return retval;
00287 retval = fread(edfi->dataRecord, 1, getDataRecordChunkSize(&edfi->cfg), fp);
00288 if (retval != getDataRecordChunkSize(&edfi->cfg))
00289 return 1;
00290 return 0;
00291 }
00292
00293
00294 int fetchSamples(const struct EDFInputIterator *edfi, short *samples, FILE *fp)
00295 {
00296 int retval;
00297 int i;
00298 int sampleCount;
00299 if (edfi->sampleNum == 0) {
00300 retval = readDataRecord(edfi, fp);
00301 if (retval != 0) return retval;
00302 }
00303 sampleCount = edfi->cfg.chan[0].sampleCount;
00304 for (i = 0; i < edfi->cfg.hdr.dataRecordChannels; ++i) {
00305
00306 samples[i] = * (short *)
00307 (&edfi->dataRecord[BYTESPERSAMPLE*(edfi->sampleNum + i * sampleCount)]);
00308 }
00309 return 0;
00310 }
00311
00312 int isValidREDF(const struct EDFDecodedConfig *cfg)
00313 {
00314 int i;
00315
00316
00317
00318
00319
00320
00321 if (cfg->hdr.dataRecordChannels < 1) {
00322 setLastError("The data record must have at least one channel.");
00323 return 0;
00324 }
00325 if (cfg->chan[0].sampleCount < 1) {
00326 setLastError("Channel 0 must have at least one sample.");
00327 return 0;
00328 }
00329 for (i = 1; i < cfg->hdr.dataRecordChannels; ++i) {
00330 if (cfg->chan[i].sampleCount != cfg->chan[0].sampleCount) {
00331 setLastError("Channel %d has %d samples, but channel 0 has %d. These must be the same.", cfg->chan[i].sampleCount, cfg->chan[0].sampleCount);
00332 return 0;
00333 }
00334 }
00335 return 1;
00336 }
00337
00338 const char *getDMY(void)
00339 {
00340 static char buf[81];
00341 time_t t;
00342 struct tm *it;
00343 time(&t);
00344 it = localtime(&t);
00345 sprintf(buf, "%02d.%02d.%02d", it->tm_mday, it->tm_mon+1, it->tm_year % 100);
00346 return buf;
00347 }
00348
00349 const char *getHMS(void)
00350 {
00351 static char buf[81];
00352 time_t t;
00353 struct tm *it;
00354 time(&t);
00355 it = localtime(&t);
00356 sprintf(buf, "%02d.%02d.%02d", it->tm_hour, it->tm_min, it->tm_sec);
00357 return buf;
00358 }
00359
00360
00361
00362
00363
00364
00365
00366
00367 int makeREDFConfig(struct EDFDecodedConfig *result, const struct EDFDecodedConfig *source)
00368 {
00369
00370 *result = *source;
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 setEDFHeaderBytes(result);
00381 strcpy(result->hdr.recordingStartDate, getDMY());
00382 strcpy(result->hdr.recordingStartTime, getHMS());
00383 assert(isValidREDF(result));
00384 return 0;
00385 }
00386
00387 const char *getLastError(void)
00388 {
00389 return errorBuffer;
00390 }
00391
00392 void setLastError(const char *fmt, ...)
00393 {
00394 va_list ap;
00395 va_start(ap, fmt);
00396 vsnprintf(errorBuffer, MAXERRORLEN-1, fmt, ap);
00397 errorBuffer[MAXERRORLEN-1] = '\0';
00398 va_end(ap);
00399 }
00400