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 <stdlib.h>
00027 #include <openedf.h>
00028 #include <string.h>
00029 #include <sys/time.h>
00030 #include <pctimer.h>
00031 #include <nsutil.h>
00032 #include <nsnet.h>
00033
00034 const char *helpText =
00035 "readedf v 0.43 by Rudi Cilibrasi\n"
00036 "\n"
00037 "Usage: readedf [options] <filename>\n"
00038 "\n"
00039 " -p port Port number to use (default 8336)\n"
00040 " -n hostname Host name of the NeuroCaster server to connect to\n"
00041 " (this defaults to 'localhost')\n"
00042 " -c numlist Numlist must be a comma-separated list of integers\n"
00043 " that specify what channels to send. The first\n"
00044 " channel is numbered 0. The default is all channels.\n"
00045 " -f Fast Mode. Send data at maximum speed.\n"
00046 " Default behavior sends data at EDF sampling rate.\n"
00047 ;
00048
00049 struct Options {
00050 int isMaxSpeed;
00051 int userSpecifiedChannels;
00052 int channelReadFlags[MAXCHANNELS];
00053 char hostname[MAXLEN];
00054 char filename[MAXLEN];
00055 int isFilenameSet;
00056 unsigned short port;
00057 };
00058
00059 struct Options opts;
00060
00061 struct OutputBuffer ob;
00062 struct InputBuffer ib;
00063
00064 #define SPEEDUPFACTOR 4.0
00065
00066 void printHeader(const struct EDFDecodedHeader *hdr)
00067 {
00068 printf("The data record count is %d\n", hdr->dataRecordCount);
00069 printf("The data record channels is %d\n", hdr->dataRecordChannels);
00070 printf("The data record seconds is %f\n", hdr->dataRecordSeconds);
00071 }
00072
00073 void handleSamples(sock_t sock_fd, int packetCounter, int chan, short *vals)
00074 {
00075 char buf[MAXLEN];
00076 int bufPos = 0;
00077 int i;
00078 bufPos += sprintf(buf+bufPos, "! %d %d", packetCounter, chan);
00079 for (i = 0; i < chan; ++i)
00080 bufPos += sprintf(buf+bufPos, " %d", vals[i]);
00081 bufPos += sprintf(buf+bufPos, "\r\n");
00082 writen(sock_fd, buf, bufPos, &ob);
00083
00084 }
00085
00086 int main(int argc, char **argv)
00087 {
00088 char EDFPacket[MAXHEADERLEN];
00089 double speedup = 1;
00090 int wantedChannels[MAXCHANNELS];
00091 int EDFLen = MAXHEADERLEN;
00092 struct EDFDecodedConfig cfg, normalized, forNC;
00093 struct EDFInputIterator *edfi;
00094 FILE *fp;
00095 int i;
00096 double t0;
00097 sock_t sock_fd;
00098 int retval;
00099 int chunksize;
00100 strcpy(opts.hostname, DEFAULTHOST);
00101 opts.port = DEFAULTPORT;
00102 for (i = 1; i < argc; ++i) {
00103 char *opt = argv[i], *cur;
00104 if (opt[0] == '-') {
00105 switch (opt[1]) {
00106 case 'c':
00107 for (cur = strtok(argv[i+1], ", ");cur;cur=strtok(NULL,", "))
00108 opts.channelReadFlags[atoi(cur)] = 1;
00109 opts.userSpecifiedChannels = 1;
00110 i += 1;
00111 break;
00112 case 'h':
00113 printf("%s", helpText);
00114 exit(0);
00115 break;
00116 case 'f':
00117 opts.isMaxSpeed = 1;
00118 break;
00119 case 'n':
00120 strcpy(opts.hostname, argv[i+1]);
00121 i += 1;
00122 break;
00123 case 'p':
00124 opts.port = atoi(argv[i+1]);
00125 i += 1;
00126 break;
00127 }
00128 }
00129 else {
00130 if (opts.isFilenameSet) {
00131 fprintf(stderr, "Error: only one edf file allowed: %s and %s\n",
00132 opts.filename, argv[i]);
00133 exit(1);
00134 }
00135 strcpy(opts.filename, argv[i]);
00136 opts.isFilenameSet = 1;
00137 }
00138 }
00139 rinitNetworking();
00140 if (!opts.userSpecifiedChannels) {
00141 for (i = 0; i < MAXCHANNELS; ++i)
00142 opts.channelReadFlags[i] = 1;
00143 }
00144 if (!opts.isFilenameSet) {
00145 fprintf(stderr, "Must supply the filename of the EDF to read.\n");
00146 exit(1);
00147 }
00148 fp = fopen(opts.filename, "rb");
00149 assert(fp != NULL && "Cannot open file!");
00150 retval = readEDF(fileno(fp), &cfg);
00151 printHeader(&cfg.hdr);
00152 makeREDFConfig(&normalized, &cfg);
00153 forNC = normalized;
00154 forNC.hdr.dataRecordChannels = 0;
00155 for (i = 0; i < normalized.hdr.dataRecordChannels; ++i) {
00156 if (opts.channelReadFlags[i]) {
00157 memcpy(&forNC.chan[forNC.hdr.dataRecordChannels], &normalized.chan[i], sizeof(normalized.chan[0]));
00158 wantedChannels[forNC.hdr.dataRecordChannels] = i;
00159 forNC.hdr.dataRecordChannels += 1;
00160 }
00161 }
00162 if (forNC.hdr.dataRecordChannels == 0) {
00163 fprintf(stderr, "Must specify some channels to read (e.g. -c 0,1 ).\n");
00164 exit(1);
00165 }
00166
00167 setEDFHeaderBytes(&forNC);
00168
00169 sock_fd = rsocket();
00170 if (sock_fd < 0) {
00171 perror("socket");
00172 rexit(1);
00173 }
00174
00175 retval = rconnectName(sock_fd, opts.hostname, opts.port);
00176 if (retval != 0) {
00177 rprintf("connect error\n");
00178 rexit(1);
00179 }
00180 rprintf("Socket connected.\n");
00181 fflush(stdout);
00182
00183 writeEDFString(&forNC, EDFPacket, &EDFLen);
00184 writeString(sock_fd, "eeg\n", &ob);
00185 writeString(sock_fd, "setheader ", &ob);
00186 writeBytes(sock_fd, EDFPacket, EDFLen, &ob);
00187 writeString(sock_fd, "\n", &ob);
00188 fflush(stdout);
00189 writeEDF(1, &forNC);
00190 rprintf("There are %f samples per second\n", getSamplesPerSecond(&forNC, 0));
00191 chunksize = getDataRecordChunkSize(&cfg);
00192
00193 printf("The chunk size is %d\n", chunksize);
00194 printf("The header size is %d\n", cfg.hdr.headerRecordBytes);
00195 edfi = newEDFInputIterator(&cfg);
00196 t0 = pctimer();
00197 i = 0;
00198 if (opts.isMaxSpeed)
00199 speedup = SPEEDUPFACTOR;
00200 for (;;) {
00201 int retval, j;
00202 short samples[MAXCHANNELS], tosend[MAXCHANNELS];
00203 retval = fetchSamples(edfi, samples, fp);
00204 if (retval != 0) break;
00205 for (j = 0; j < forNC.hdr.dataRecordChannels; ++j)
00206 tosend[j] = samples[wantedChannels[j]];
00207 handleSamples(sock_fd, i%64, forNC.hdr.dataRecordChannels, tosend);
00208 while (t0 + (double) i / (getSamplesPerSecond(&forNC, 0) * speedup) > pctimer()) {
00209 rsleep(20);
00210 }
00211 i += 1;
00212 if (i % 1000 == 0) {
00213 printf("Read %d timesamples and on datarecord %05d:%04d\n", i, edfi->dataRecordNum, edfi->sampleNum);
00214 fflush(stdout);
00215 }
00216 stepEDFInputIterator(edfi);
00217 getResponseCode(sock_fd, &ib);
00218 }
00219
00220 fclose(fp);
00221 freeEDFInputIterator(edfi);
00222 return 0;
00223 }