tomwalters@0: /* tomwalters@0: Copyright (c) Applied Psychology Unit, Medical Research Council. 1993 tomwalters@0: =========================================================================== tomwalters@0: tomwalters@0: Permission to use, copy, modify, and distribute this software without fee tomwalters@0: is hereby granted for research purposes, provided that this copyright tomwalters@0: notice appears in all copies and in all supporting documentation, and that tomwalters@0: the software is not redistributed for any fee (except for a nominal tomwalters@0: shipping charge). Anyone wanting to incorporate all or part of this tomwalters@0: software in a commercial product must obtain a license from the Medical tomwalters@0: Research Council. tomwalters@0: tomwalters@0: The MRC makes no representations about the suitability of this tomwalters@0: software for any purpose. It is provided "as is" without express or tomwalters@0: implied warranty. tomwalters@0: tomwalters@0: THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING tomwalters@0: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL tomwalters@0: THE A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES tomwalters@0: OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, tomwalters@0: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, tomwalters@0: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS tomwalters@0: SOFTWARE. tomwalters@0: */ tomwalters@0: /* saicut.c tomwalters@0: * ------------ tomwalters@0: * tomwalters@0: * Cuts out frames or channels (or both) from a .sai tomwalters@0: * output= .sai tomwalters@0: * tomwalters@0: * options: -frame (units=frame numbers; INCLUSIVE). tomwalters@0: * -channel (units=channel nos; INCLUSIVE). tomwalters@0: * (both arguments are needed). tomwalters@0: * tomwalters@0: * When using verbose, those frame numbers that are NOT kept are put in tomwalters@0: * round brackets (). tomwalters@0: * tomwalters@0: * tomwalters@0: * M Akeroyd. June 1993. v1.00 Revised Spring 1994. tomwalters@0: * Lots of extra options Winter 1995. tomwalters@0: */ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include tomwalters@0: #include "tip.h" tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* Function declarations */ tomwalters@0: /*-------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: void parsecommandline (int argc, char *argv[], char inputfn[], char outputfn[]); tomwalters@0: int readheader(FILE *inputfp); tomwalters@0: void checkheader(); tomwalters@0: void writeheader(FILE *outputfp); tomwalters@0: void changeheader(int no_frames, int new_pwidth, int new_nwidth, int framewidthsamples_output); tomwalters@0: void changeheader_B(int new_mincf, int new_maxcf, int new_channels); tomwalters@0: tomwalters@0: void writedata_output (FILE *outputfp, int samples_to_write); tomwalters@0: FILE *open_file (char filefn[], FILE *dir_default, int streamtype); tomwalters@0: tomwalters@0: tomwalters@0: /* Data Arrays */ tomwalters@0: /* ------------------------------------------------------------------------*/ tomwalters@0: short inputdata[MAX_DATA]; tomwalters@0: short inputbychannel[MAX_CHANNELS][MAX_DATA]; tomwalters@0: short outputfiguredata[MAX_DATA]; tomwalters@0: short outputgrounddata[MAX_DATA]; tomwalters@0: tomwalters@0: #define MAX_STROBES 2000 tomwalters@0: int strobelocation[MAX_STROBES]; tomwalters@0: tomwalters@0: /* variables read from header */ tomwalters@0: /*-------------------------------------------------------------------------*/ tomwalters@0: char header[MAX_LINES_HEADER][MAX_LINE_LENGTH]; tomwalters@0: int header_lines; tomwalters@0: tomwalters@0: /* .sai parameters */ tomwalters@0: int no_frames; tomwalters@0: int frameheight; /* number of channels */ tomwalters@0: int framewidth_samples; /* pwidth + nwidth * samplerate */ tomwalters@0: int frameshift_samples; /* frstep_aid * samplerate */ tomwalters@0: int pwidth; /* in msecs */ tomwalters@0: int nwidth; /* in msecs: NEGATIVE */ tomwalters@0: int width_win; /* pixels */ tomwalters@0: int height_win; /* pixels */ tomwalters@0: long samplerate; /* samples per sec */ tomwalters@0: int mincf; /* Hz */ tomwalters@0: int maxcf; /* Hz */ tomwalters@0: tomwalters@0: /* parameters read from command line*/ tomwalters@0: int framestart; tomwalters@0: int frameend; tomwalters@0: int minchannel; tomwalters@0: int maxchannel; tomwalters@0: tomwalters@0: int cut_timestart; tomwalters@0: int cut_timeend; tomwalters@0: int counter; tomwalters@0: float sum; tomwalters@0: float tempf; tomwalters@0: float timestart, timeend; tomwalters@0: tomwalters@0: /* misc */ tomwalters@0: /*-----------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: char progname[MAX_STRING_LENGTH]; tomwalters@0: char outputfigurefn[MAX_STRING_LENGTH]; tomwalters@0: char strobefn[MAX_STRING_LENGTH]; tomwalters@0: tomwalters@0: tomwalters@0: int verboseflag = OFF; /* -v */ tomwalters@0: int frameflag = OFF; /* -f */ tomwalters@0: int channelflag = OFF; /* -c */ tomwalters@0: int greyscaleflag = OFF; /* Not used: required for compilation */ tomwalters@0: int oppositearchflag = OFF; /* -oparch : see saigraph.c for info */ tomwalters@0: int sumflag = OFF; tomwalters@0: int averageflag = OFF; tomwalters@0: int timeflag = OFF; tomwalters@0: int headerflag = ON; tomwalters@0: int strobeflag = OFF; tomwalters@0: int strobevalue = 1; /* the value used to mark a strobe event in tomwalters@0: the .trigger file */ tomwalters@0: int cutthisframe = OFF; tomwalters@0: int infoflag = OFF; tomwalters@0: int forceframeflag = OFF; tomwalters@0: int forceframe = 0; tomwalters@0: int successforceflag = OFF; tomwalters@0: tomwalters@0: /* ................... Main ................................*/ tomwalters@0: /* .........................................................................*/ tomwalters@0: /* .........................................................................*/ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: void main (int argc, char *argv[]) tomwalters@0: { tomwalters@0: int n, sample; tomwalters@0: int frame, channel; tomwalters@0: int trigger_peak = 0; tomwalters@0: int header_bytes = 0; tomwalters@0: int cut_framestart, cut_frameend, cut_no_frames; tomwalters@0: int cut_minchannel, cut_maxchannel, cut_frameheight; tomwalters@0: char inputfn[MAX_STRING_LENGTH], outputbasefn[MAX_STRING_LENGTH]; tomwalters@0: FILE *inputfp, *outputfigurefp; tomwalters@0: FILE *strobefp; tomwalters@0: int x, counter, previousx; tomwalters@0: int nstrobes; tomwalters@0: short sampledata[2]; tomwalters@0: tomwalters@0: /*-------------------------------------*/ tomwalters@0: strcpy(progname, argv[0]); tomwalters@0: strcpy(inputfn, ""); tomwalters@0: strcpy(outputbasefn, ""); tomwalters@0: strcpy(outputfigurefn, ""); tomwalters@0: tomwalters@0: parsecommandline(argc, argv, inputfn, outputbasefn); tomwalters@0: tomwalters@0: if (strcmp(outputbasefn, "") == 0) tomwalters@0: strcpy(outputfigurefn, ""); tomwalters@0: else { tomwalters@0: strcpy(outputfigurefn, outputbasefn); tomwalters@0: /* strcat(outputfigurefn, OUTPUT_EXT);*/ tomwalters@0: } tomwalters@0: tomwalters@0: /*--------------------------------------*/ tomwalters@0: /* open files, read and check header */ tomwalters@0: inputfp = open_file(inputfn, stdin, READ); tomwalters@0: outputfigurefp = open_file(outputfigurefn, stdout, WRITE); tomwalters@0: header_bytes = readheader(inputfp); tomwalters@0: checkheader(); tomwalters@0: tomwalters@0: /*-------------------------------------*/ tomwalters@0: /* strobe code */ tomwalters@0: if (strobeflag == ON){ tomwalters@0: strobefp = open_file(strobefn, stderr, READ); tomwalters@0: /* note tomwalters@0: * add (nwidth * samplerate) to the index tomwalters@0: * the frame number is the floor of that + 1 (because it seems to give the correct answer) tomwalters@0: * some versions of gensai return a triggerpoint 3 samples across; take the first. tomwalters@0: */ tomwalters@0: for (x=0; x= strobevalue){ tomwalters@0: if (((x-previousx) <= 2) && (previousx != 0)) tomwalters@0: /* don't need this trigger */ tomwalters@0: continue; tomwalters@0: strobelocation[counter] = x; tomwalters@0: tempf = (float) strobelocation[counter] + (-1.0 * nwidth * samplerate / 1000.0); tomwalters@0: tempf = tempf * 1.0 / frameshift_samples; tomwalters@0: /* tempf = floor(tempf);*/ tomwalters@0: strobelocation[counter] = (int) tempf + 1.0; tomwalters@0: /* if (verboseflag == ON) tomwalters@0: fprintf(stderr, "strobe %i: %i samples %f (%i frames)\n", counter, x, tempf, (int)strobelocation[counter]);*/ tomwalters@0: previousx=x; tomwalters@0: counter++;} tomwalters@0: x++; tomwalters@0: if (counter >= MAX_STROBES){ tomwalters@0: fprintf(stderr, " %s : too many strobes in .trigger file.\n", progname); tomwalters@0: exit(-1);} tomwalters@0: } tomwalters@0: nstrobes=counter-1; tomwalters@0: if (infoflag == ON){ tomwalters@0: fprintf(stderr, "using %i frames ", nstrobes); tomwalters@0: for (counter=1; counter <=nstrobes; counter ++) tomwalters@0: fprintf(stderr, " %i", strobelocation[counter]); tomwalters@0: fprintf(stderr, "\n");} tomwalters@0: fclose(strobefp); tomwalters@0: } tomwalters@0: tomwalters@0: /*--------------------------------------*/ tomwalters@0: tomwalters@0: /* reset the frame/channel counters */ tomwalters@0: if (frameflag == ON) { tomwalters@0: cut_frameend = frameend; tomwalters@0: cut_framestart = framestart; } tomwalters@0: else { tomwalters@0: cut_frameend = no_frames; tomwalters@0: cut_framestart = 1; } tomwalters@0: tomwalters@0: if (channelflag == ON) { tomwalters@0: cut_maxchannel = maxchannel; tomwalters@0: cut_minchannel = minchannel; } tomwalters@0: else { tomwalters@0: cut_maxchannel = frameheight; tomwalters@0: cut_minchannel = 1; } tomwalters@0: tomwalters@0: if (timeflag == ON) { tomwalters@0: cut_timestart = samplerate * timestart/1000; tomwalters@0: cut_timeend = samplerate * timeend/1000;} tomwalters@0: else{ tomwalters@0: cut_timestart = 0; tomwalters@0: cut_timeend = framewidth_samples;} tomwalters@0: tomwalters@0: /* fprintf(stderr, "%d \n", cut_timestart);*/ tomwalters@0: /* fprintf(stderr, "%d \n", cut_timeend);*/ tomwalters@0: tomwalters@0: cut_no_frames = cut_frameend - cut_framestart + 1; /* inclusive, so +1 */ tomwalters@0: cut_frameheight = cut_maxchannel - cut_minchannel + 1; /* inclusive, so +1 */ tomwalters@0: if (strobeflag == ON) tomwalters@0: cut_no_frames = nstrobes; tomwalters@0: tomwalters@0: /*--------------------------------------*/ tomwalters@0: /* WARNING: 'time' options are NOT built into the headers yet */ tomwalters@0: tomwalters@0: changeheader(cut_no_frames, pwidth, nwidth, framewidth_samples); tomwalters@0: changeheader_B(mincf, maxcf, cut_frameheight); tomwalters@0: if (headerflag == ON) tomwalters@0: writeheader(outputfigurefp); tomwalters@0: tomwalters@0: /*--------------------------------------*/ tomwalters@0: tomwalters@0: if (verboseflag==ON) { tomwalters@0: fprintf(stderr, " frames "); tomwalters@0: fflush(stderr);} tomwalters@0: tomwalters@0: /*------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: for (frame=1; frame<=no_frames; frame++) { tomwalters@0: tomwalters@0: if (strobeflag == OFF) { tomwalters@0: if ((frame < cut_framestart) || (frame > cut_frameend )) tomwalters@0: cutthisframe = OFF; tomwalters@0: else tomwalters@0: cutthisframe = ON;} tomwalters@0: else { tomwalters@0: cutthisframe = OFF; tomwalters@0: for (counter=1; counter <= nstrobes; counter ++){ tomwalters@0: if (frame == strobelocation[counter]) tomwalters@0: cutthisframe = ON;}} tomwalters@0: tomwalters@0: if (forceframeflag == ON){ tomwalters@0: if (frame < forceframe){ tomwalters@0: cutthisframe = OFF;} tomwalters@0: else { tomwalters@0: if (successforceflag == OFF){ tomwalters@0: if (cutthisframe == ON){ tomwalters@0: successforceflag = ON; tomwalters@0: fprintf(stdout, "%d\n", frame);}} tomwalters@0: else tomwalters@0: cutthisframe = OFF;}} tomwalters@0: tomwalters@0: if (verboseflag == ON) { tomwalters@0: if (cutthisframe == ON){ tomwalters@0: fprintf(stderr, " %i ", frame); fflush(stderr);} tomwalters@0: else { tomwalters@0: fprintf(stderr, " (%i) ", frame); fflush(stderr);}} tomwalters@0: tomwalters@0: /*--------------------------------------*/ tomwalters@0: tomwalters@0: for (channel=1; channel <=frameheight; channel ++) { tomwalters@0: tomwalters@0: for(sample=0; sample cut_frameend )) tomwalters@0: continue;} tomwalters@0: else { tomwalters@0: if (cutthisframe == OFF) tomwalters@0: continue;} tomwalters@0: tomwalters@0: /* output all required channels */ tomwalters@0: for (channel = cut_minchannel; channel <= cut_maxchannel; channel++) { tomwalters@0: sum = 0.0; tomwalters@0: counter=0; tomwalters@0: for(sample=cut_timestart; sample input file default = stdin\n"); tomwalters@0: fprintf(stderr, " -o <.sai file> output file default = stdout\n"); tomwalters@0: fprintf(stderr, " -t <.trigger file> trigger location file\n"); tomwalters@0: fprintf(stderr, " -oparch assume input was generated on an opposing architecture cpu\n"); tomwalters@0: fprintf(stderr, "\n"); tomwalters@0: fprintf(stderr, " -n take first frame after \n"); tomwalters@0: fprintf(stderr, " -frames (inclusive) (default=all)\n"); tomwalters@0: fprintf(stderr, " -time (inclusive; ms from leftedge)\n"); tomwalters@0: fprintf(stderr, " -channel (inclusive) (default=all)\n"); tomwalters@0: fprintf(stderr, " -sum sum and output 1 value per frame\n"); tomwalters@0: fprintf(stderr, " -average sum, average & output 1 value per frame\n"); tomwalters@0: fprintf(stderr, " -noheader don't output a .sai header\n"); tomwalters@0: fprintf(stderr, " -header do output a .sai header (default)\n"); tomwalters@0: fprintf(stderr, "\n"); tomwalters@0: fprintf(stderr, " -v verbose output (to stderr)\n"); tomwalters@0: fprintf(stderr, " -triggerinfo report the 'trigger' frames (to stderr)"); tomwalters@0: fprintf(stderr, "\n\n"); tomwalters@0: exit(-1);} tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: