Example #1
0
/*{{{  write_rec(transform_info_ptr tinfo) {*/
METHODDEF DATATYPE *
write_rec(transform_info_ptr tinfo) {
 struct write_rec_storage *local_arg=(struct write_rec_storage *)tinfo->methods->local_storage;
 transform_argument *args=tinfo->methods->arguments;
 FILE *outfptr=local_arg->outfptr;
 short *inbuf;
 array myarray;

 if (tinfo->itemsize!=1) {
  ERREXIT(tinfo->emethods, "write_rec: Only itemsize=1 is supported.\n");
 }
 if (args[ARGS_CLOSE].is_set) {
  write_rec_open_file(tinfo);
  outfptr=local_arg->outfptr;
 }
 /*{{{  Write epoch*/
 tinfo_array(tinfo, &myarray);
 /* We read the data point by point, i.e. channels fastest */
 array_transpose(&myarray);
 /* Within the record, writing is non-interlaced, ie points fastest */
 do {
  do {
   inbuf=local_arg->outbuf+local_arg->samples_per_record*myarray.current_element+local_arg->current_sample;
   *inbuf= (short int)rint(array_scan(&myarray)/local_arg->resolution);
   if (!local_arg->overflow_has_occurred && (*inbuf<local_arg->digmin || *inbuf>local_arg->digmax)) {
    TRACEMS(tinfo->emethods, 0, "write_rec: Some output values exceed digitization bits!\n");
    local_arg->overflow_has_occurred=TRUE;
   }
#ifndef LITTLE_ENDIAN
   Intel_int16(inbuf);
#endif
  } while (myarray.message==ARRAY_CONTINUE);
  if (++local_arg->current_sample>=local_arg->samples_per_record) {
   if ((int)fwrite(local_arg->outbuf, sizeof(short), tinfo->nr_of_channels*local_arg->samples_per_record, outfptr)!=tinfo->nr_of_channels*local_arg->samples_per_record) {
    ERREXIT(tinfo->emethods, "write_rec: Write error on data file.\n");
   }
   /* If nr_of_records was -1 (can only happen while appending),
    * leave it that way */
   if (local_arg->nr_of_records>=0) local_arg->nr_of_records++;
   local_arg->current_sample=0L;
  }
 } while (myarray.message!=ARRAY_ENDOFSCAN);
 /*}}}  */
 if (args[ARGS_CLOSE].is_set) write_rec_close_file(tinfo);
 return tinfo->tsdata;	/* Simply to return something `useful' */
}
Example #2
0
/*{{{  change_byteorder(char *structure, struct_member *smp) {*/
void
change_byteorder(char *structure, struct_member *smp) {
    struct_member *in_smp;

    for (in_smp=smp+1; in_smp->length!=0; in_smp++) {
        if (in_smp->control_byteorder) {
            switch(in_smp->length) {
            case 2:
                Intel_int16((uint16_t *)(structure+in_smp->offset_this_compiler));
                break;
            case 4:
                Intel_int32((uint32_t *)(structure+in_smp->offset_this_compiler));
                break;
            case 8:
                Intel_int64((uint64_t *)(structure+in_smp->offset_this_compiler));
                break;
            }
        }
    }
}
Example #3
0
/* This function not only seeks to the specified point, but also reads
 * the point into the buffer if necessary. The get_singlepoint function
 * then only transfers the data. */
LOCAL void
read_synamps_seek_point(transform_info_ptr tinfo, long point) {
 struct read_synamps_storage *local_arg=(struct read_synamps_storage *)tinfo->methods->local_storage;

 switch(local_arg->SubType) {
  case NST_CONT0:
  case NST_DCMES:
  case NST_CONTINUOUS:
  case NST_SYNAMPS: {
   /*{{{  */
   const int points_per_buf=local_arg->EEG.ChannelOffset/local_arg->bytes_per_sample; /* Note a value of 1 is fixed in read_synamps_init */
   long const buffer_boundary=(point/points_per_buf)*points_per_buf;
   long const new_last_point_in_buffer=buffer_boundary+points_per_buf-1;
   /* This format is neither points fastest nor channels fastest, but
    * points fastest in blocks. No idea why they didn't do channels fastest,
    * it would have rendered the whole file in one order, no matter what buffer
    * size is used internally in programs. This way we MUST use the given buffers. */
   if (new_last_point_in_buffer!=local_arg->last_point_in_buffer) {
    fseek(local_arg->SCAN,point2offset(tinfo,buffer_boundary),SEEK_SET);
    if (fread(local_arg->buffer,1,local_arg->BufferCount,local_arg->SCAN)!=local_arg->BufferCount) {
     ERREXIT(tinfo->emethods, "read_synamps_seek_point: Error reading data\n");
    }
    local_arg->first_point_in_buffer=buffer_boundary;
    local_arg->last_point_in_buffer=new_last_point_in_buffer;
    /*{{{  Swap byte order if necessary*/
#    ifndef LITTLE_ENDIAN
    {uint16_t *pdata=(uint16_t *)local_arg->buffer, *p_end=(uint16_t *)((char *)local_arg->buffer+local_arg->BufferCount);
     while (pdata<p_end) Intel_int16(pdata++);
    }
#    endif
    /*}}}  */
   }
   /*}}}  */
  }
  break;
 default:
  ERREXIT1(tinfo->emethods, "read_synamps_seek_point: Format `%s' is not yet supported\n", MSGPARM(neuroscan_subtype_names[local_arg->SubType]));
  break;
 }
 local_arg->current_point=point;
}
Example #4
0
/*{{{  write_synamps(transform_info_ptr tinfo) {*/
METHODDEF DATATYPE *
write_synamps(transform_info_ptr calltinfo) {
 struct write_synamps_storage *local_arg=(struct write_synamps_storage *)calltinfo->methods->local_storage;
 transform_argument *args=calltinfo->methods->arguments;
 NEUROSCAN_EPOCHED_SWEEP_HEAD sweephead;
 long tsdata_step, tsdata_steps, tsdata_stepwidth;
 array myarray;
 /* Note that 'tinfo' instead of 'tinfoptr' is used here so that we don't have to modify 
  * all of the older code which stored only one epoch */
 transform_info_ptr tinfo=calltinfo;

 if (args[ARGS_LINKED].is_set) {
  /* Go to the start: */
  for (; tinfo->previous!=NULL; tinfo=tinfo->previous);
 }
 for (; tinfo!=NULL; tinfo=tinfo->next) {
  DATATYPE * const orig_tsdata=tinfo->tsdata;
 /*{{{  Assert that epoch size didn't change & itemsize==1*/
 if (tinfo->itemsize!=1) {
  ERREXIT(tinfo->emethods, "write_synamps: Only itemsize=1 is supported.\n");
 }
 if (local_arg->EEG.nchannels!=tinfo->nr_of_channels) {
  ERREXIT2(tinfo->emethods, "write_synamps: nr_of_channels was %d, now %d\n", MSGPARM(local_arg->EEG.nchannels), MSGPARM(tinfo->nr_of_channels));
 }
 /*}}}  */

 if (tinfo->data_type==FREQ_DATA) {
  tinfo->nr_of_points=tinfo->nroffreq;
  tsdata_steps=tinfo->nrofshifts;
  tsdata_stepwidth=tinfo->nr_of_channels*tinfo->nroffreq*tinfo->itemsize;
 } else {
  tsdata_steps=1;
  tsdata_stepwidth=0;
 }
 for (tsdata_step=0; tsdata_step<tsdata_steps; tinfo->tsdata+=tsdata_stepwidth, tsdata_step++) {
 switch (local_arg->output_format) {
  case FORMAT_EEGFILE:
 if (local_arg->EEG.pnts!=tinfo->nr_of_points) {
  ERREXIT2(tinfo->emethods, "write_synamps: nr_of_points was %d, now %d\n", MSGPARM(local_arg->EEG.pnts), MSGPARM(tinfo->nr_of_points));
 }
 /*{{{  Set sweephead values*/
 sweephead.accept=1;
 sweephead.type=254;
 sweephead.correct=0;
 sweephead.rt=0;
 sweephead.response=0;
 if (tinfo->condition>0) {
  sweephead.type=tinfo->condition&0xff;
 } else if (tinfo->condition<0 && (-tinfo->condition)<=0xf) {
  sweephead.type=0;
  sweephead.response= -tinfo->condition;
 } else {
  /* KeyBoard event: Do it the same way 'Edit' does when epoching,
   * mapping F1 to type=1 and so on (overlap with stim codes, but they
   * should know how they want it...) */
  sweephead.type= (-tinfo->condition)>>4;
 }
 /*}}}  */
 /*{{{  Write sweephead struct*/
# ifndef LITTLE_ENDIAN
 change_byteorder((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD);
# endif
 write_struct((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD, local_arg->SCAN);
# ifndef LITTLE_ENDIAN
 change_byteorder((char *)&sweephead, sm_NEUROSCAN_EPOCHED_SWEEP_HEAD);
# endif
 /*}}}  */
 local_arg->EEG.nsweeps++;	/* This gets patched into the header by write_synamps_exit */
 local_arg->EEG.compsweeps++;
 local_arg->EEG.acceptcnt++;
   break;
  case FORMAT_AVGFILE:
   if (local_arg->EEG.NumSamples!=0) {
    ERREXIT(tinfo->emethods, "write_synamps: Only a single epoch may be written to an .AVG file!\n");
   }
  case FORMAT_CNTFILE:
   if (tinfo->triggers.buffer_start!=NULL) {
    struct trigger *intrig=(struct trigger *)tinfo->triggers.buffer_start+1;
    while (intrig->code!=0) {
     push_trigger(&local_arg->triggers,local_arg->EEG.NumSamples+intrig->position,intrig->code,intrig->description);
     intrig++;
    }
   }
   local_arg->EEG.NumSamples+=tinfo->nr_of_points;
   break;
 }

 tinfo_array(tinfo, &myarray);
 if (local_arg->output_format==FORMAT_AVGFILE) {
  /* points are the elements */
  float *pdata, * const buffer=(float *)malloc(myarray.nr_of_elements*sizeof(float));
  const char *fill="\0\0\0\0\0";
  if (buffer==NULL) {
   ERREXIT(tinfo->emethods, "write_synamps: Error allocating AVGFILE buffer\n");
  }
  do {
   int const channel=myarray.current_vector;
   /* Write the `5-byte channel header that is no longer used' */
   fwrite(fill, 1, 5, local_arg->SCAN);
   pdata=buffer;
   do {
    *pdata=NEUROSCAN_FLOATCONV(&local_arg->Channels[channel], array_scan(&myarray));
# ifndef LITTLE_ENDIAN
    Intel_float(pdata);
# endif
    pdata++;
   } while (myarray.message==ARRAY_CONTINUE);
   if ((int)fwrite(buffer,sizeof(float),myarray.nr_of_elements,local_arg->SCAN)!=myarray.nr_of_elements) {
    ERREXIT(tinfo->emethods, "write_synamps: Error writing data point\n");
   }
  } while (myarray.message!=ARRAY_ENDOFSCAN);
  free(buffer);
 } else {
 int16_t * const buffer=(int16_t *)malloc(myarray.nr_of_vectors*sizeof(int16_t));
 if (buffer==NULL) {
  ERREXIT(tinfo->emethods, "write_synamps: Error allocating buffer\n");
 }
 array_transpose(&myarray);	/* channels are the elements */
 do {
  int channel=0;
  do {
   DATATYPE hold=array_scan(&myarray), hold2;
   /* Code anything exceeding the representable range, including +-Inf, as min/max representable value. */
   hold2=NEUROSCAN_SHORTCONV(&local_arg->Channels[channel], hold);
   if (hold2< -32768) hold2= -32768;
   else if (hold2> 32767) hold2= 32767;
   buffer[channel]=(int16_t)hold2;
# ifndef LITTLE_ENDIAN
   Intel_int16(&buffer[channel]);
# endif
   channel++;
  } while (myarray.message==ARRAY_CONTINUE);
  if ((int)fwrite(buffer,sizeof(int16_t),myarray.nr_of_elements,local_arg->SCAN)!=myarray.nr_of_elements) {
   ERREXIT(tinfo->emethods, "write_synamps: Error writing data point\n");
  }
 } while (myarray.message!=ARRAY_ENDOFSCAN);
 free(buffer);
 }
 } /* FREQ_DATA shifts loop */
 tinfo->tsdata=orig_tsdata;
  if (!args[ARGS_LINKED].is_set) {
   break;
  }
 } /* Linked epochs loop */

 return calltinfo->tsdata;	/* Simply to return something `useful' */
}
Example #5
0
METHODDEF DATATYPE *
read_freiburg(transform_info_ptr tinfo) {
 struct read_freiburg_storage *local_arg=(struct read_freiburg_storage *)tinfo->methods->local_storage;
 transform_argument *args=tinfo->methods->arguments;
 struct freiburg_channels_struct *in_channels=local_arg->in_channels;
 array myarray;
 FILE *infile;
 int i, point, channel;
 int trial_not_accepted;
 long length_of_data;
 short header[FREIBURG_HEADER_LENGTH/sizeof(short)];
 char const *last_sep=strrchr(args[ARGS_IFILE].arg.s, PATHSEP);
 char const *last_component=(last_sep==NULL ? args[ARGS_IFILE].arg.s : last_sep+1);
 char comment[MAX_COMMENTLEN];

 tinfo->nrofaverages=1;
 if (args[ARGS_CONTINUOUS].is_set) {
  /*{{{  Read an epoch from a continuous file*/
  infile=local_arg->infile;

  if (local_arg->epochs--==0) return NULL;

  /*{{{  Configure myarray*/
  myarray.element_skip=tinfo->itemsize=1;
  myarray.nr_of_vectors=tinfo->nr_of_points=local_arg->epochlength;
  myarray.nr_of_elements=tinfo->nr_of_channels=local_arg->nr_of_channels;
  if (array_allocate(&myarray)==NULL) {
   ERREXIT(tinfo->emethods, "read_freiburg: Error allocating data\n");
  }
  tinfo->multiplexed=TRUE;
  /*}}}  */

  do {
   do {
    if (local_arg->segment_table.buffer_start!=NULL && local_arg->current_point%SEGMENT_LENGTH==0) {
     int const segment=local_arg->current_point/SEGMENT_LENGTH;
     long const nr_of_segments=local_arg->segment_table.current_length/sizeof(long);
     if (segment>=nr_of_segments) {
      array_free(&myarray);
      return NULL;
     }
     fseek(infile, ((long *)local_arg->segment_table.buffer_start)[segment], SEEK_SET);
     local_arg->no_last_values=TRUE;
    }
    if (freiburg_get_segment(tinfo, &myarray)!=0) {
     array_free(&myarray);
     return NULL;
    }
   } while (myarray.message!=ARRAY_ENDOFSCAN);
  } while (--local_arg->fromepoch>0);
  snprintf(comment, MAX_COMMENTLEN, "%s %s %02d/%02d/%04d,%02d:%02d:%02d", (local_arg->continuous_type==SLEEP_BT_TYPE ? "sleep_BT" : "sleep_KL"), last_component, local_arg->btfile.start_month, local_arg->btfile.start_day, local_arg->btfile.start_year, local_arg->btfile.start_hour, local_arg->btfile.start_minute, local_arg->btfile.start_second);
  tinfo->sfreq=local_arg->sfreq;
  /*}}}  */
 } else
 /*{{{  Read an epoch from a single (epoched or averaged) file*/
 do {	/* Return here if trial was not accepted */
 trial_not_accepted=FALSE;

 if (local_arg->epochs--==0 || (local_arg->average_mode && local_arg->current_trigger>=1)) return NULL;

 if (local_arg->average_mode) {
  /*{{{  Prepare reading an averaged file*/
  if((infile=fopen(args[ARGS_IFILE].arg.s,"rb"))==NULL) {
   ERREXIT1(tinfo->emethods, "read_freiburg: Can't open file %s\n", MSGPARM(args[ARGS_IFILE].arg.s));
  }
  fseek(infile, 0, SEEK_END);
  length_of_data=ftell(infile)-FREIBURG_HEADER_LENGTH;
  local_arg->current_trigger++;
  snprintf(comment, MAX_COMMENTLEN, "Freiburg-avg %s", last_component);
  /*}}}  */
 } else {
  /*{{{  Build pathname of the single trial to read*/
  /* A directory name was given. */
  char const * const expnumber=args[ARGS_IFILE].arg.s+strlen(args[ARGS_IFILE].arg.s)-2;
#ifdef __GNUC__
#define NEWFILENAME_SIZE (strlen(args[ARGS_IFILE].arg.s)+strlen(last_component)+20)
#else
#define NEWFILENAME_SIZE MAX_PATHLEN
#endif
  char newfilename[NEWFILENAME_SIZE];
  do {	/* Files from which only the parameter part exists are rejected */
   int div100=local_arg->current_trigger/100, mod100=local_arg->current_trigger%100;
   snprintf(newfilename, NEWFILENAME_SIZE, "%s%c%s%02d%c%c%s%02d%02d", args[ARGS_IFILE].arg.s, PATHSEP, last_component, div100, PATHSEP, tolower(expnumber[-1]), expnumber, div100, mod100);
   TRACEMS1(tinfo->emethods, 1, "read_freiburg: Constructed filename %s\n", MSGPARM(newfilename));

   if((infile=fopen(newfilename,"rb"))==NULL) {
    if (local_arg->current_trigger==0) {
     ERREXIT1(tinfo->emethods, "read_freiburg: Can't open file %s\n", MSGPARM(newfilename));
    } else {
     return NULL;
    }
   }
   fseek(infile, 0, SEEK_END);
   length_of_data=ftell(infile)-FREIBURG_HEADER_LENGTH;
   local_arg->current_trigger++;
  } while (length_of_data==0 || --local_arg->fromepoch>0);
  snprintf(comment, MAX_COMMENTLEN, "Freiburg-raw %s", last_component);
  /*}}}  */
 }

 /*{{{  Read the 64-Byte header*/
 fseek(infile, 0, SEEK_SET);
 fread(header, 1, FREIBURG_HEADER_LENGTH, infile);
 for (i=0; i<18; i++) {
# ifdef LITTLE_ENDIAN
  Intel_int16((uint16_t *)&header[i]);
# endif
  TRACEMS2(tinfo->emethods, 3, "read_freiburg: Header %02d: %d\n", MSGPARM(i), MSGPARM(header[i]));
 }
 /*}}}  */

 if (local_arg->average_mode) {
  if ((length_of_data/sizeof(short))%local_arg->nr_of_channels!=0) {
   ERREXIT2(tinfo->emethods, "read_freiburg: length_of_data=%d does not fit with nr_of_channels=%d\n", MSGPARM(length_of_data), MSGPARM(local_arg->nr_of_channels));
  }
  tinfo->nr_of_points=(length_of_data/sizeof(short))/local_arg->nr_of_channels;
  local_arg->sfreq=(args[ARGS_SFREQ].is_set ? args[ARGS_SFREQ].arg.d : 200.0); /* The most likely value */
 } else {
  local_arg->nr_of_channels=header[14];
  /* Note: In a lot of experiments, one point MORE is available in the data
   * than specified in the header, but this occurs erratically. We could only
   * check for this during decompression, but that's probably too much fuss. */
  tinfo->nr_of_points=header[16]/header[15];
  local_arg->sfreq=(args[ARGS_SFREQ].is_set ? args[ARGS_SFREQ].arg.d : 1000.0/header[15]);
 }
 tinfo->sfreq=local_arg->sfreq;
 /*{{{  Parse arguments that can be in seconds*/
 local_arg->offset=(args[ARGS_OFFSET].is_set ? gettimeslice(tinfo, args[ARGS_OFFSET].arg.s) : 0);
 /*}}}  */
 tinfo->beforetrig= -local_arg->offset;
 tinfo->aftertrig=tinfo->nr_of_points+local_arg->offset;

 /*{{{  Configure myarray*/
 myarray.element_skip=tinfo->itemsize=1;
 myarray.nr_of_vectors=tinfo->nr_of_points;
 myarray.nr_of_elements=tinfo->nr_of_channels=local_arg->nr_of_channels;
 if (array_allocate(&myarray)==NULL) {
  ERREXIT(tinfo->emethods, "read_freiburg: Error allocating data\n");
 }
 tinfo->multiplexed=TRUE;
 /*}}}  */

 fseek(infile, FREIBURG_HEADER_LENGTH, SEEK_SET);
 if (local_arg->average_mode) {
  /*{{{  Read averaged epoch*/
  for (point=0; point<tinfo->nr_of_points; point++) {
#ifdef __GNUC__
   short buffer[tinfo->nr_of_channels];
#else
   short buffer[MAX_NR_OF_CHANNELS];
#endif
   if ((int)fread(buffer, sizeof(short), tinfo->nr_of_channels, infile)!=tinfo->nr_of_channels) {
    ERREXIT1(tinfo->emethods, "read_freiburg: Error reading data point %d\n", MSGPARM(point));
   }
   for (channel=0; channel<tinfo->nr_of_channels; channel++) {
#  ifdef LITTLE_ENDIAN
    Intel_int16((uint16_t *)&buffer[channel]);
#  endif
    array_write(&myarray, (DATATYPE)buffer[channel]);
   }
  }
  /*}}}  */
 } else {
  /*{{{  Read compressed single trial*/
#  ifdef DISPLAY_ADJECTIVES
  char *adjektiv_ende=strchr(((char *)header)+36, ' ');
  if (adjektiv_ende!=NULL) *adjektiv_ende='\0';
  printf("Single trial: nr_of_points=%d, nr_of_channels=%d, Adjektiv=%s\n", tinfo->nr_of_points, tinfo->nr_of_channels, ((char *)header)+36);
#  endif
  local_arg->infile=infile;
  do {
   if (freiburg_get_segment(tinfo, &myarray)!=0) {
    TRACEMS1(tinfo->emethods, 0, "read_freiburg: Decompression out of bounds for trial %d - skipped\n", MSGPARM(local_arg->current_trigger-1));
    array_free(&myarray);
    trial_not_accepted=TRUE;
    break;
   }
  } while (myarray.message!=ARRAY_ENDOFSCAN);
  /*}}}  */
 }
 fclose(infile);
 } while (trial_not_accepted);
 /*}}}  */

 /*{{{  Look for a Freiburg channel setup for this number of channels*/
 /* Force create_channelgrid to really allocate the channel info anew.
  * Otherwise, free_tinfo will free someone else's data ! */
 tinfo->channelnames=NULL; tinfo->probepos=NULL;
 if (local_arg->channelnames!=NULL) {
  copy_channelinfo(tinfo, local_arg->channelnames, NULL);
 } else {
  while (in_channels->nr_of_channels!=0 && in_channels->nr_of_channels!=tinfo->nr_of_channels) in_channels++;
  if (in_channels->nr_of_channels==0) {
   TRACEMS1(tinfo->emethods, 1, "read_freiburg: Don't have a setup for %d channels.\n", MSGPARM(tinfo->nr_of_channels));
  } else {
   copy_channelinfo(tinfo, in_channels->channelnames, NULL);
  }
 }
 create_channelgrid(tinfo); /* Create defaults for any missing channel info */
 /*}}}  */
 
 if ((tinfo->comment=(char *)malloc(strlen(comment)+1))==NULL) {
  ERREXIT(tinfo->emethods, "read_freiburg: Error allocating comment memory\n");
 }
 strcpy(tinfo->comment, comment);

 if (local_arg->zero_idiotism_warned==FALSE && local_arg->zero_idiotism_encountered) {
  TRACEMS(tinfo->emethods, 0, "read_freiburg: All-zero data points have been encountered and omitted!\n");
  local_arg->zero_idiotism_warned=TRUE;
 }
 tinfo->z_label=NULL;
 tinfo->tsdata=myarray.start;
 tinfo->length_of_output_region=tinfo->nr_of_channels*tinfo->nr_of_points;
 tinfo->leaveright=0;
 tinfo->data_type=TIME_DATA;

 return tinfo->tsdata;
}
Example #6
0
/*{{{  read_synamps_get_singlepoint(transform_info_ptr tinfo, array *toarray) {*/
LOCAL int
read_synamps_get_singlepoint(transform_info_ptr tinfo, array *toarray) {
 struct read_synamps_storage *local_arg=(struct read_synamps_storage *)tinfo->methods->local_storage;
 transform_argument *args=tinfo->methods->arguments;

 if (local_arg->current_point>=local_arg->EEG.NumSamples) return -1;
 read_synamps_seek_point(tinfo, local_arg->current_point);
 switch(local_arg->SubType) {
  case NST_DCMES: {
   /* DC-MES data is unsigned, and the marker channel is skipped: */
   unsigned short *pdata=(unsigned short *)local_arg->buffer+local_arg->current_point-local_arg->first_point_in_buffer+1;
   int channel=0;
   do {
    *pdata^=0x8000;	/* Exclusive or to convert to signed... */
    if (args[ARGS_NOBADCHANS].is_set && local_arg->Channels[channel].bad) {
     toarray->message=ARRAY_CONTINUE;
    } else {
     array_write(toarray, NEUROSCAN_CONVSHORT(&local_arg->Channels[channel], *((signed short *)pdata)));
    }
    pdata+=local_arg->EEG.ChannelOffset/local_arg->bytes_per_sample;
    channel++;
   } while (toarray->message==ARRAY_CONTINUE);
  }
   break;
  case NST_CONT0:
  case NST_CONTINUOUS:
  case NST_SYNAMPS: {
   int channel=0;
   do {
    DATATYPE val;
    if (args[ARGS_NOBADCHANS].is_set && local_arg->Channels[channel].bad) {
     toarray->message=ARRAY_CONTINUE;
    } else {
     if (local_arg->bytes_per_sample==2) {
      int16_t * const pdata=((int16_t *)local_arg->buffer)+local_arg->current_point-local_arg->first_point_in_buffer+channel;
#   ifndef LITTLE_ENDIAN
      Intel_int16(pdata);
#   endif
      val=NEUROSCAN_CONVSHORT(&local_arg->Channels[channel],*pdata);
     } else if (local_arg->bytes_per_sample==4) {
      int32_t * const pdata=((int32_t *)local_arg->buffer)+local_arg->current_point-local_arg->first_point_in_buffer+channel;
#   ifndef LITTLE_ENDIAN
      Intel_int32(pdata);
#   endif
      val=NEUROSCAN_CONVSHORT(&local_arg->Channels[channel],*pdata);
     } else {
      ERREXIT(tinfo->emethods, "read_synamps: Unknown bytes_per_sample\n");
     }
     array_write(toarray, val);
    }
    channel++;
   } while (toarray->message==ARRAY_CONTINUE);
  }
   break;
  default:
   ERREXIT1(tinfo->emethods, "read_synamps_get_singlepoint: Format `%s' is not yet supported\n", MSGPARM(neuroscan_subtype_names[local_arg->SubType]));
   break;
 }
 local_arg->current_point++;
 return 0;
}
Example #7
0
/*{{{  write_vitaport_exit(transform_info_ptr tinfo) {*/
METHODDEF void
write_vitaport_exit(transform_info_ptr tinfo) {
    struct write_vitaport_storage *local_arg=(struct write_vitaport_storage *)tinfo->methods->local_storage;
    int channel, NoOfChannels=local_arg->fileheader.knum;
    long point;
    long const channellen=local_arg->total_points*sizeof(uint16_t);
    long const hdlen=local_arg->fileheader.hdlen;
    uint16_t checksum=0;

    local_arg->fileheaderII.dlen=hdlen+NoOfChannels*channellen;
    /*{{{  Write the file headers*/
# ifdef LITTLE_ENDIAN
    change_byteorder((char *)&local_arg->fileheader, sm_vitaport_fileheader);
    change_byteorder((char *)&local_arg->fileheaderII, sm_vitaportII_fileheader);
    change_byteorder((char *)&local_arg->fileext, sm_vitaportII_fileext);
# endif
    write_struct((char *)&local_arg->fileheader, sm_vitaport_fileheader, local_arg->outfile);
    write_struct((char *)&local_arg->fileheaderII, sm_vitaportII_fileheader, local_arg->outfile);
    write_struct((char *)&local_arg->fileext, sm_vitaportII_fileext, local_arg->outfile);
    /*}}}  */

    for (channel=0; channel<NoOfChannels; channel++) {
        /*{{{  Write a channel header*/
        /* This is the factor as we'd like to have it... */
        float factor=((float)(local_arg->channelmax[channel]> -local_arg->channelmin[channel] ? local_arg->channelmax[channel] : -local_arg->channelmin[channel]))/SHRT_MAX;

        if (strncmp(local_arg->channelheaders[channel].kname, VP_MARKERCHANNEL_NAME, 6)==0) {
            strcpy(local_arg->channelheaders[channel].kunit, "mrk");
            local_arg->channelheaders[channel].datype=VP_DATYPE_MARKER;
            /* Since the marker channel is read without the conversion factors,
             * set the conversion to 1.0 for this channel */
            local_arg->channelheaders[channel].mulfac=local_arg->channelheaders[channel].divfac=1;
            local_arg->channelheaders[channel].offset=0;
        } else {
            float const logdiff=log(factor)-TARGET_LOG_SHORTVAL;

            local_arg->channelheaders[channel].offset=0;
            if (logdiff<0) {
                /*{{{  Factor is small: Better to fix divfac and calculate mulfac after that*/
                double const divfac=exp(-logdiff);
                if (divfac>SHRT_MAX) {
                    local_arg->channelheaders[channel].divfac=SHRT_MAX;
                } else {
                    local_arg->channelheaders[channel].divfac=(unsigned short)divfac;
                }
                /* The +1 takes care that we never get below the `ideal' factor computed above. */
                local_arg->channelheaders[channel].mulfac=(unsigned short)(factor*local_arg->channelheaders[channel].divfac+1);
                if (local_arg->channelheaders[channel].mulfac==0) {
                    local_arg->channelheaders[channel].mulfac=1;
                    local_arg->channelheaders[channel].divfac=(unsigned short)(1.0/factor-1);
                }
                /*}}}  */
            } else {
                /*{{{  Factor is large: Better to fix mulfac and calculate divfac after that*/
                double const mulfac=exp(logdiff);
                if (mulfac>SHRT_MAX) {
                    local_arg->channelheaders[channel].mulfac=SHRT_MAX;
                } else {
                    local_arg->channelheaders[channel].mulfac=(unsigned short)mulfac;
                }
                /* The -1 takes care that we never get below the `ideal' factor computed above. */
                local_arg->channelheaders[channel].divfac=(unsigned short)(local_arg->channelheaders[channel].mulfac/factor-1);
                if (local_arg->channelheaders[channel].divfac==0) {
                    local_arg->channelheaders[channel].mulfac=(unsigned short)(factor+1);
                    local_arg->channelheaders[channel].divfac=1;
                }
                /*}}}  */
            }
        }
        /* Now see which factor we actually got constructed */
        factor=((float)local_arg->channelheaders[channel].mulfac)/local_arg->channelheaders[channel].divfac;

        local_arg->channelheadersII[channel].doffs=channel*channellen;
        local_arg->channelheadersII[channel].dlen=channellen;
#  ifdef LITTLE_ENDIAN
        change_byteorder((char *)&local_arg->channelheaders[channel], sm_vitaport_channelheader);
        change_byteorder((char *)&local_arg->channelheadersII[channel], sm_vitaportIIrchannelheader);
#  endif
        write_struct((char *)&local_arg->channelheaders[channel], sm_vitaport_channelheader, local_arg->outfile);
        write_struct((char *)&local_arg->channelheadersII[channel], sm_vitaportIIrchannelheader, local_arg->outfile);
#  ifdef LITTLE_ENDIAN
        change_byteorder((char *)&local_arg->channelheaders[channel], sm_vitaport_channelheader);
        change_byteorder((char *)&local_arg->channelheadersII[channel], sm_vitaportIIrchannelheader);
#  endif
        /*}}}  */
    }
    fwrite(&checksum, sizeof(checksum), 1, local_arg->outfile);

    TRACEMS(tinfo->emethods, 1, "write_vitaport_exit: Copying channels to output file...\n");

    /* We close and re-open the channel file because buffering is much more
     * efficient at least with DJGPP if the file is either only read or written */
    fclose(local_arg->channelfile);
    if ((local_arg->channelfile=fopen(local_arg->channelfilename, "rb"))==NULL) {
        ERREXIT1(tinfo->emethods, "write_vitaport_exit: Can't open temp file %s\n", MSGPARM(local_arg->channelfilename));
    }

    for (channel=0; channel<NoOfChannels; channel++) {
        /*{{{  Copy a channel to the target file */
        float const factor=((float)local_arg->channelheaders[channel].mulfac)/local_arg->channelheaders[channel].divfac;
        unsigned short const offset=local_arg->channelheaders[channel].offset;

        for (point=0; point<local_arg->total_points; point++) {
            DATATYPE dat;
            int16_t s;
            fseek(local_arg->channelfile, (point*NoOfChannels+channel)*sizeof(DATATYPE), SEEK_SET);
            if (fread(&dat, sizeof(DATATYPE), 1, local_arg->channelfile)!=1) {
                ERREXIT(tinfo->emethods, "write_vitaport_exit: Error reading temp file.\n");
            }
            s= (int16_t)rint(dat/factor)-offset;
#   ifdef LITTLE_ENDIAN
            Intel_int16((uint16_t *)&s);
#   endif
            if (fwrite(&s, sizeof(s), 1, local_arg->outfile)!=1) {
                ERREXIT(tinfo->emethods, "write_vitaport_exit: Write error.\n");
            }
        }
        /*}}}  */
    }
    fclose(local_arg->channelfile);
    unlink(local_arg->channelfilename);

    if (local_arg->triggers.current_length!=0) {
        long tagno, n_events;
        uint32_t length, trigpoint;
        int const nevents=local_arg->triggers.current_length/sizeof(struct trigger);
        struct vitaport_idiotic_multiplemarkertablenames *markertable_entry;

        /* Try to keep a security space of at least 20 free events */
        for (markertable_entry=markertable_names; markertable_entry->markertable_name!=NULL && markertable_entry->idiotically_fixed_length<nevents+20; markertable_entry++);
        if (markertable_entry->markertable_name==NULL) {
            if ((markertable_entry-1)->idiotically_fixed_length<=nevents) {
                /* Drop the requirement for at least 20 free events */
                markertable_entry--;
            } else {
                /* No use... */
                ERREXIT1(tinfo->emethods, "write_vitaport_exit: %d events wouldn't fit into the fixed-length VITAGRAPH marker tables!\nBlame the Vitaport people!\n", MSGPARM(nevents));
            }
        }
        n_events=markertable_entry->idiotically_fixed_length;

        fwrite(markertable_entry->markertable_name, 1, VP_TABLEVAR_LENGTH, local_arg->outfile);
        length=n_events*sizeof(length);
#ifdef LITTLE_ENDIAN
        Intel_int32((uint32_t *)&length);
#endif
        fwrite(&length, sizeof(length), 1, local_arg->outfile);
        for (tagno=0; tagno<n_events; tagno++) {
            if (tagno<nevents) {
                struct trigger * const intrig=((struct trigger *)local_arg->triggers.buffer_start)+tagno;
                /* Trigger positions are given in ms units */
                trigpoint=(long)rint(intrig->position*1000.0/local_arg->sfreq);
                /* Make trigpoint uneven if code%2==1 */
                trigpoint=trigpoint-trigpoint%2+(intrig->code-1)%2;
            } else {
                trigpoint= -1;
            }
#ifdef LITTLE_ENDIAN
            Intel_int32((uint32_t *)&trigpoint);
#endif
            fwrite(&trigpoint, sizeof(trigpoint), 1, local_arg->outfile);
        }
        for (; tagno<n_events; tagno++) {
            trigpoint= -1;
#ifdef LITTLE_ENDIAN
            Intel_int32((uint32_t *)&trigpoint);
#endif
            fwrite(&trigpoint, sizeof(trigpoint), 1, local_arg->outfile);
        }
    }

    fclose(local_arg->outfile);

    /*{{{  Free memory*/
    free_pointer((void **)&local_arg->channelfilename);
    free_pointer((void **)&local_arg->channelmax);
    free_pointer((void **)&local_arg->channelmin);
    free_pointer((void **)&local_arg->channelheaders);
    free_pointer((void **)&local_arg->channelheadersII);

    if (local_arg->triggers.buffer_start!=NULL) {
        clear_triggers(&local_arg->triggers);
        growing_buf_free(&local_arg->triggers);
    }
    /*}}}  */

    tinfo->methods->init_done=FALSE;
}