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: tomwalters@0: /*-------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: /* header.c tomwalters@0: * ---------- tomwalters@0: * tomwalters@0: * Part of the tr+fg+sai collection tomwalters@0: * tomwalters@0: * temporary version only, until I get architectures sussed: tomwalters@0: * see the comments to 'readheader' tomwalters@0: * tomwalters@0: * tomwalters@0: * M. Akeroyd. 26th May 1993. Revised Winter 1994. 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: extern char progname[MAX_STRING_LENGTH]; tomwalters@0: extern char header[MAX_LINES_HEADER][MAX_LINE_LENGTH]; tomwalters@0: tomwalters@0: extern int verboseflag; tomwalters@0: extern int oppositearchflag; /* ON if reading Sun on DEC, or DEC on Sun.*/ tomwalters@0: extern int header_lines; /* number of lines in header */ tomwalters@0: tomwalters@0: tomwalters@0: /* .sai parameters */ tomwalters@0: tomwalters@0: extern int no_frames; tomwalters@0: extern int frameheight; /* number of channels */ tomwalters@0: extern int framewidth_samples; /* pwidth + nwidth * samplerate */ tomwalters@0: extern int frameshift_samples; /* frstep_aid * samplerate */ tomwalters@0: extern int pwidth; /* in msecs */ tomwalters@0: extern int nwidth; /* in msecs: NEGATIVE */ tomwalters@0: extern int width_win; /* pixels */ tomwalters@0: extern int height_win; /* pixels */ tomwalters@0: extern long samplerate; /* samples per sec */ tomwalters@0: extern int mincf; /* Hz */ tomwalters@0: extern int maxcf; /* Hz */ tomwalters@0: tomwalters@0: tomwalters@0: /*-------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: int readheader(FILE *inputfp) tomwalters@0: { tomwalters@0: /* Version of 20v1993 tomwalters@0: * This is the latest attempt to get it to READ the required bytes. tomwalters@0: * tomwalters@0: * Because the headerlines are of the format "string"="number", tomwalters@0: * with no spaces imbetween, there is this hack ... tomwalters@0: * tomwalters@0: * MAA: Autumn 1993: but see comments below about Sparc10s and tomwalters@0: * DECstations. tomwalters@0: */ tomwalters@0: tomwalters@0: char *p_equal=" "; /* pointer to where the '=' is in the headerline */ tomwalters@0: char tempstring[MAX_STRING_LENGTH]; tomwalters@0: tomwalters@0: int bytes_required = 0; /* no. of bytes in header, as in "header_bytes=... tomwalters@0: * This is RETURNed */ tomwalters@0: int bytes_loaded = 0; /* number actually loaded */ tomwalters@0: int counter; tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* get first line */ tomwalters@0: header_lines = 0; tomwalters@0: fgets(header[0], MAX_LINE_LENGTH, inputfp); tomwalters@0: tomwalters@0: if(strspn(header[0], "header_bytes") == 0) { tomwalters@0: fprintf(stderr, "%s: is the input an AIM output file?\n", progname); tomwalters@0: exit(-1);} tomwalters@0: tomwalters@0: /* find out how many bytes there SHOULD be */ tomwalters@0: p_equal = strchr(header[0], '='); tomwalters@0: bytes_required = atoi(++p_equal); tomwalters@0: tomwalters@0: /*---------------------------------*/ tomwalters@0: tomwalters@0: /* loop on remaining lines, saving important information as required */ tomwalters@0: tomwalters@0: while (strncmp(fgets(header[++header_lines], MAX_LINE_LENGTH, inputfp), tomwalters@0: "Version=", 8) != 0) { tomwalters@0: if (strncmp(header[header_lines], "frameheight=", 12) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: frameheight = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "framewidth=", 11) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: framewidth_samples = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "frames=", 7) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: no_frames = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "frameshift=", 11) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: frameshift_samples = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "samplerate=", 11) == 0 ) { tomwalters@0: /* For some unknown reason, the samplerate has a "." at the tomwalters@0: * end of it. tomwalters@0: */ tomwalters@0: strncpy(tempstring, header[header_lines], tomwalters@0: (strlen(header[header_lines])-0)); tomwalters@0: p_equal = strchr(tempstring, '='); tomwalters@0: samplerate = atol(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "pwidth_aid=", 11) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: pwidth = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "nwidth_aid=", 11) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: nwidth = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "width_win=", 10) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: width_win = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "height_win=", 11) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: height_win = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "mincf_afb=", 10) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: mincf = atoi(++p_equal); } tomwalters@0: tomwalters@0: if (strncmp(header[header_lines], "maxcf_afb=", 10) == 0 ) { tomwalters@0: p_equal = strchr(header[header_lines], '='); tomwalters@0: maxcf = atoi(++p_equal); } tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: /*------------------------------------*/ tomwalters@0: tomwalters@0: /* how many bytes have we loaded ? */ tomwalters@0: for (counter=0; counter<=header_lines; counter++) tomwalters@0: bytes_loaded += strlen(header[counter]); tomwalters@0: tomwalters@0: tomwalters@0: /* include this warning */ tomwalters@0: if (bytes_loaded > bytes_required) { tomwalters@0: fprintf(stderr, "%s: something's gone wrong ... too many header bytes were loaded.\n"); tomwalters@0: exit(-1); tomwalters@0: } tomwalters@0: tomwalters@0: /* read some more bytes, till we are at the end of the header */ tomwalters@0: for (counter = 1; counter <= (bytes_required - bytes_loaded); counter++) tomwalters@0: fgetc(inputfp); tomwalters@0: tomwalters@0: tomwalters@0: /* printf("header.c: bytes_required %i\n", bytes_required); */ tomwalters@0: /* printf("header.c: bytes_loaded %i\n", bytes_loaded); */ tomwalters@0: tomwalters@0: tomwalters@0: /* MAA: Autumn 1993: Roy noticied that saisummary didn't always work tomwalters@0: * properly, giving a "negative data" error. The following line is the tomwalters@0: * standard working hack: load one extra byte of the header. tomwalters@0: * It might be that the reason I didn't notice before tomwalters@0: * is that a Sparc10 seems to require this extra byte, but that a DECstation tomwalters@0: * 3100 doesn't. At least when BOTH are reading a DECstation .sai file. tomwalters@0: * But when they read their 'own' .sai files, it isn't needed. tomwalters@0: * Therefore this is a byte-swapping bug. tomwalters@0: */ tomwalters@0: /* So, in summary: tomwalters@0: * KEEP this line if reading DEC .sai on a SPARC, or SPARC .sai on a DEC tomwalters@0: * REMOVE this line if reading DEc .sai on a DEC, or SPARC .sai on a SPARC tomwalters@0: */ tomwalters@0: /* fgetc(inputfp); /* THIS ONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ tomwalters@0: tomwalters@0: /* MAA: Winter 1994: Changed this bit to the "-oparch" option */ tomwalters@0: if (oppositearchflag == ON) tomwalters@0: fgetc(inputfp); /* THIS ONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/ tomwalters@0: tomwalters@0: return bytes_required; tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /*---------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: void writeheader(FILE *outputfp) tomwalters@0: { tomwalters@0: /* Version of 20v1993 tomwalters@0: * The header is written as a sequence of strings. If the total length tomwalters@0: * is less than the number required ("header_bytes=..."), then send some tomwalters@0: * NULL bytes, till its the correct length. tomwalters@0: */ tomwalters@0: tomwalters@0: int counter; tomwalters@0: int bytes_required = 0; tomwalters@0: int bytes_outputed = 0; tomwalters@0: char *p_equal; tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* find out how many bytes we are supposed to be writing */ tomwalters@0: p_equal = strchr(header[0], '='); tomwalters@0: bytes_required = atoi(++p_equal); tomwalters@0: tomwalters@0: /* write header; in the process add up the bytes */ tomwalters@0: for(counter=0; counter<=header_lines; counter++) { tomwalters@0: bytes_outputed += strlen(header[counter]); tomwalters@0: fputs(header[counter], outputfp);} tomwalters@0: tomwalters@0: fflush(outputfp); tomwalters@0: tomwalters@0: /* if we haven't yet sent enough bytes, send some more */ tomwalters@0: for (counter=1; counter<=(bytes_required - bytes_outputed); counter++) tomwalters@0: fputc(NULL, outputfp); tomwalters@0: tomwalters@0: tomwalters@0: /* include this warning */ tomwalters@0: if (bytes_required < bytes_outputed) { tomwalters@0: fprintf(stderr, "%s: something's gone wrong ... the new header is %i too big.\n", progname, (bytes_outputed - bytes_required)); tomwalters@0: exit(-1); tomwalters@0: } tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /*---------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: void checkheader() tomwalters@0: { tomwalters@0: tomwalters@0: if (framewidth_samples >= MAX_DATA) { tomwalters@0: fprintf(stderr, "%s: frames are too wide at %i: only alllowed %i samples\n", progname, framewidth_samples, MAX_DATA); tomwalters@0: exit(-1); } tomwalters@0: tomwalters@0: if (frameheight >= MAX_CHANNELS) { tomwalters@0: fprintf(stderr, "%s: too many channels (%i): only alllowed %i \n", progname, frameheight, MAX_CHANNELS); tomwalters@0: exit(-1); } tomwalters@0: tomwalters@0: } tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: /* The End */ tomwalters@0: /*---------------------------------------------------------------------------*/ tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: tomwalters@0: