view saitools/header.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line source
/*
    Copyright (c) Applied Psychology Unit, Medical Research Council. 1993
    ===========================================================================

    Permission to use, copy, modify, and distribute this software without fee 
    is hereby granted for research purposes, provided that this copyright 
    notice appears in all copies and in all supporting documentation, and that 
    the software is not redistributed for any fee (except for a nominal 
    shipping charge). Anyone wanting to incorporate all or part of this 
    software in a commercial product must obtain a license from the Medical 
    Research Council.

    The MRC makes no representations about the suitability of this 
    software for any purpose.  It is provided "as is" without express or 
    implied warranty.
 
    THE MRC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 
    ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 
    THE A.P.U. BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES 
    OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 
    WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 
    ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 
    SOFTWARE.
*/

/*-------------------------------------------------------------------------*/

/* header.c 
* ----------
*
* Part of the tr+fg+sai collection
*
* temporary version only, until I get architectures sussed:
* see the comments to 'readheader'
*
*
* M. Akeroyd. 26th May 1993. Revised Winter 1994.
*
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "tip.h"



extern char progname[MAX_STRING_LENGTH];
extern char header[MAX_LINES_HEADER][MAX_LINE_LENGTH];

extern int verboseflag;
extern int oppositearchflag;    /* ON if reading Sun on DEC, or DEC on Sun.*/
extern int header_lines;        /* number of lines in header */


/* .sai parameters */

extern int no_frames;
extern int frameheight;             /* number of channels */
extern int framewidth_samples;      /* pwidth + nwidth * samplerate */
extern int frameshift_samples;      /* frstep_aid * samplerate */
extern int pwidth;                  /* in msecs */
extern int nwidth;                  /* in msecs: NEGATIVE */
extern int width_win;               /* pixels */
extern int height_win;              /* pixels */
extern long samplerate;              /* samples per sec */
extern int mincf;                   /* Hz */
extern int maxcf;                   /* Hz */


/*-------------------------------------------------------------------------*/

int readheader(FILE *inputfp) 
{ 
  /* Version of 20v1993 
   * This is the latest attempt to get it to READ the required bytes.
   *
   * Because the headerlines are of the format "string"="number", 
   * with no spaces imbetween, there is this hack ... 
   * 
   * MAA: Autumn 1993: but see comments below about Sparc10s and 
   * DECstations.
   */
 
  char *p_equal=" ";       /* pointer to where the '=' is in the headerline */
  char tempstring[MAX_STRING_LENGTH];        

  int bytes_required = 0;  /* no. of bytes in header, as in "header_bytes=...
			    * This is RETURNed */
  int bytes_loaded = 0;    /* number actually loaded */
  int counter;



  /* get first line */
  header_lines = 0;
  fgets(header[0], MAX_LINE_LENGTH, inputfp);

  if(strspn(header[0], "header_bytes") == 0) {
    fprintf(stderr, "%s: is the input an AIM output file?\n", progname);
    exit(-1);}

  /* find out how many bytes there SHOULD be */
  p_equal = strchr(header[0], '=');
  bytes_required = atoi(++p_equal); 

/*---------------------------------*/

  /* loop on remaining lines, saving important information as required */

  while (strncmp(fgets(header[++header_lines], MAX_LINE_LENGTH, inputfp),
		 "Version=", 8)  != 0) {
    if (strncmp(header[header_lines], "frameheight=", 12) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      frameheight = atoi(++p_equal); }

    if (strncmp(header[header_lines], "framewidth=", 11) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      framewidth_samples = atoi(++p_equal); }

    if (strncmp(header[header_lines], "frames=", 7) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      no_frames = atoi(++p_equal); }

    if (strncmp(header[header_lines], "frameshift=", 11) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      frameshift_samples = atoi(++p_equal); }

    if (strncmp(header[header_lines], "samplerate=", 11) == 0 ) {
      /* For some unknown reason, the samplerate has a "." at the
       * end of it. 
       */
      strncpy(tempstring, header[header_lines], 
	      (strlen(header[header_lines])-0));
      p_equal = strchr(tempstring, '=');
      samplerate = atol(++p_equal); } 

    if (strncmp(header[header_lines], "pwidth_aid=", 11) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      pwidth = atoi(++p_equal); }

    if (strncmp(header[header_lines], "nwidth_aid=", 11) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      nwidth = atoi(++p_equal); }

    if (strncmp(header[header_lines], "width_win=", 10) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      width_win = atoi(++p_equal); }

    if (strncmp(header[header_lines], "height_win=", 11) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      height_win = atoi(++p_equal); }

    if (strncmp(header[header_lines], "mincf_afb=", 10) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      mincf = atoi(++p_equal); }

    if (strncmp(header[header_lines], "maxcf_afb=", 10) == 0 ) {
      p_equal = strchr(header[header_lines], '=');
      maxcf = atoi(++p_equal); }

  }

/*------------------------------------*/

  /* how many bytes have we loaded ? */
  for (counter=0; counter<=header_lines; counter++) 
    bytes_loaded += strlen(header[counter]);


  /* include this warning */
  if (bytes_loaded > bytes_required) {
    fprintf(stderr, "%s: something's gone wrong ... too many header bytes were loaded.\n");
    exit(-1);
  }
  
  /* read some more bytes, till we are at the end of the header */
  for (counter = 1; counter <= (bytes_required - bytes_loaded); counter++) 
    fgetc(inputfp);


/* printf("header.c: bytes_required %i\n", bytes_required); */
/* printf("header.c: bytes_loaded %i\n", bytes_loaded); */


/* MAA: Autumn 1993: Roy noticied that saisummary didn't always work
*  properly, giving a "negative data" error. The following line is the
*  standard working hack: load one extra byte of the header.
*  It might be that the reason I didn't notice before
*  is that a Sparc10 seems to require this extra byte, but that a DECstation
*  3100 doesn't. At least when BOTH are reading a DECstation .sai file.
*  But when they read their 'own' .sai files, it isn't needed.
*  Therefore this is a byte-swapping bug.
*/
/* So, in summary:
* KEEP this line if reading DEC .sai on a SPARC, or SPARC .sai on a DEC
* REMOVE this line if reading DEc .sai on a DEC, or SPARC .sai on a SPARC
*/
/*     fgetc(inputfp);           /* THIS ONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

/* MAA: Winter 1994: Changed this bit to the "-oparch" option */
  if (oppositearchflag == ON) 
    fgetc(inputfp);           /* THIS ONE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
  
  return bytes_required; 
}




/*---------------------------------------------------------------------------*/



void writeheader(FILE *outputfp)
{
  /* Version of 20v1993
   * The header is written as a sequence of strings. If the total length
   * is less than the number required ("header_bytes=..."), then send some
   * NULL bytes, till its the correct length.
   */

  int counter;
  int bytes_required = 0;
  int bytes_outputed = 0;
  char *p_equal;



  /* find out how many bytes we are supposed to be writing */
  p_equal = strchr(header[0], '=');
  bytes_required = atoi(++p_equal); 

  /* write header; in the process add up the bytes */
  for(counter=0; counter<=header_lines; counter++) {
    bytes_outputed += strlen(header[counter]);
    fputs(header[counter], outputfp);}

  fflush(outputfp);

  /* if we haven't yet sent enough bytes, send some more */
  for (counter=1; counter<=(bytes_required - bytes_outputed); counter++) 
    fputc(NULL, outputfp);


  /* include this warning */
  if (bytes_required < bytes_outputed) {
    fprintf(stderr, "%s: something's gone wrong ... the new header is %i too big.\n", progname, (bytes_outputed - bytes_required));
    exit(-1);
  }

}




/*---------------------------------------------------------------------------*/



void checkheader()
{

  if (framewidth_samples >= MAX_DATA) {
    fprintf(stderr, "%s: frames are too wide at %i: only alllowed %i samples\n", progname, framewidth_samples, MAX_DATA);
    exit(-1); }

  if (frameheight >= MAX_CHANNELS) {
    fprintf(stderr, "%s: too many channels (%i): only alllowed %i \n", progname, frameheight, MAX_CHANNELS);
    exit(-1); }

}




/* The End */
/*---------------------------------------------------------------------------*/