Exemplo n.º 1
0
int save_annotations(UI_Mainwindow *mainwindow, FILE *outputfile, struct edfhdrblock *hdr, struct annotationblock *annotlist)
{
  int i, j, k, n, p=0,
      new_edfsignals=0,
      signalslist[MAXSIGNALS],
      datarecords,
      annot_len,
      annot_smp_per_record,
      annot_recordsize,
      timestamp_decimals,
      timestamp_digits,
      annots_per_datrec,
      space,
      progress_steps;

  char *readbuf,
       scratchpad[256],
       *annot_buf;

  long long time;

  FILE *inputfile;

  struct annotationblock *annot;

  inputfile = hdr->file_hdl;

  for(i=0; i<hdr->edfsignals; i++)
  {
    if(!hdr->edfparam[i].annotation)
    {
      signalslist[new_edfsignals] = i;

      new_edfsignals++;
    }
  }

  datarecords = hdr->datarecords;

  time = (hdr->datarecords * hdr->long_data_record_duration) / TIME_DIMENSION;

  timestamp_decimals = get_tal_timestamp_decimal_cnt(hdr);
  if(timestamp_decimals < 0)
  {
    return(1);
  }

  timestamp_digits = get_tal_timestamp_digit_cnt(hdr);
  if(timestamp_digits < 0)
  {
    return(1);
  }

  annot = annotlist;

  annot_len = get_max_annotation_strlen(&annot);

  i = edfplus_annotation_count(&annot);

  annots_per_datrec = i / datarecords;

  if(i % datarecords)
  {
    annots_per_datrec++;
  }

  annot_recordsize = (annot_len * annots_per_datrec) + timestamp_digits + timestamp_decimals + 4;

  if(timestamp_decimals)
  {
    annot_recordsize++;
  }

  if(hdr->edf)
  {
    annot_smp_per_record = annot_recordsize / 2;

    if(annot_recordsize % annot_smp_per_record)
    {
      annot_smp_per_record++;

      annot_recordsize = annot_smp_per_record * 2;
    }
  }
  else
  {
    annot_smp_per_record = annot_recordsize / 3;

    if(annot_recordsize % annot_smp_per_record)
    {
      annot_smp_per_record++;

      annot_recordsize = annot_smp_per_record * 3;
    }
  }

  readbuf = (char *)malloc(hdr->recordsize);
  if(readbuf==NULL)
  {
    return(1);
  }

  annot_buf = (char *)malloc(annot_recordsize + 10);
  if(annot_buf==NULL)
  {
    free(readbuf);
    return(1);
  }

///////////////////////////////////////////////////////////////////

  rewind(outputfile);

  if(hdr->edf)
  {
    fprintf(outputfile, "0       ");
  }
  else
  {
    fprintf(outputfile, "XBIOSEMI");
    rewind(outputfile);
    fputc(255, outputfile);
    fseeko(outputfile, 0LL, SEEK_END);
  }
  fseeko(inputfile, 8LL, SEEK_SET);
  if((hdr->edfplus)||(hdr->bdfplus))
  {
    if(fread(scratchpad, 176, 1, inputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(2);
    }

    if((hdr->genuine_nk) && (hdr->nk_triggers_read))
    {
      space = 0;

      for(n=80; n<160; n++)
      {
        if(scratchpad[n] == ' ')
        {
          space++;

          if(space > 3)
          {
            break;
          }
        }
      }

      n += 14;

      if(n<150)
      {
        if(!strncmp(scratchpad + n, "EEG", 3))
        {
          scratchpad[n] = 'e';
          scratchpad[n+1] = 'e';
          scratchpad[n+2] = 'g';
        }
      }
    }

    if(fwrite(scratchpad, 176, 1, outputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(3);
    }
  }
  else
  {
    sprintf(scratchpad, "X X X X ");
    if(fread(scratchpad + 8, 80, 1, inputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(2);
    }
    if(fwrite(scratchpad, 80, 1, outputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(3);
    }
    sprintf(scratchpad, "Startdate X X X X ");
    if(fread(scratchpad + 18, 80, 1, inputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(2);
    }
    if(fwrite(scratchpad, 80, 1, outputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(3);
    }
    if(fread(scratchpad, 16, 1, inputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(2);
    }
    if(fwrite(scratchpad, 16, 1, outputfile)!=1)
    {
      free(readbuf);
      free(annot_buf);
      return(3);
    }
  }
  fprintf(outputfile, "%-8i", (new_edfsignals * 256) + 512);
  if(hdr->edf)
  {
    fprintf(outputfile, "EDF+C");
  }
  else
  {
    fprintf(outputfile, "BDF+C");
  }
  for(i=0; i<39; i++)
  {
    fputc(' ', outputfile);
  }
  fprintf(outputfile, "%-8i", datarecords);
  snprintf(scratchpad, 256, "%.12f", hdr->data_record_duration);
  remove_trailing_zeros(scratchpad);
  strcat(scratchpad, "         ");
  if((!strncmp(scratchpad, "0.", 2)) && (scratchpad[8] != ' '))
  {
    scratchpad[9] = 0;
    fprintf(outputfile, "%s", scratchpad + 1);
  }
  else
  {
    scratchpad[8] = 0;
    fprintf(outputfile, "%s", scratchpad);
  }
  fprintf(outputfile, "%-4i", new_edfsignals + 1);

  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", hdr->edfparam[signalslist[i]].label);
  }
  if(hdr->edf)
  {
    fprintf(outputfile, "%s", "EDF Annotations ");
  }
  else
  {
    fprintf(outputfile, "%s", "BDF Annotations ");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", hdr->edfparam[signalslist[i]].transducer);
  }
  for(i=0; i<80; i++)
  {
    fputc(' ', outputfile);
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", hdr->edfparam[signalslist[i]].physdimension);
  }
  for(i=0; i<8; i++)
  {
    fputc(' ', outputfile);
  }
  for(i=0; i<new_edfsignals; i++)
  {
    snprintf(scratchpad, 256, "%f", hdr->edfparam[signalslist[i]].phys_min);
    for(k=0; k<8; k++)
    {
      if(scratchpad[k]=='.')
      {
        for(j=7; j>=0; j--)
        {
          if((scratchpad[j]!='.')&&(scratchpad[j]!='0'))
          {
            break;
          }

          if(scratchpad[j]=='.')
          {
            scratchpad[j] = ' ';
            break;
          }

          scratchpad[j] = ' ';
        }
        break;
      }
      scratchpad[8] = 0;
    }
    fprintf(outputfile, "%s", scratchpad);
  }
  fprintf(outputfile, "-1      ");
  for(i=0; i<new_edfsignals; i++)
  {
    snprintf(scratchpad, 256, "%f", hdr->edfparam[signalslist[i]].phys_max);
    for(k=0; k<8; k++)
    {
      if(scratchpad[k]=='.')
      {
        for(j=7; j>=0; j--)
        {
          if((scratchpad[j]!='.')&&(scratchpad[j]!='0'))
          {
            break;
          }

          if(scratchpad[j]=='.')
          {
            scratchpad[j] = ' ';
            break;
          }

          scratchpad[j] = ' ';
        }
        break;
      }
    }
    scratchpad[8] = 0;
    fprintf(outputfile, "%s", scratchpad);
  }
  fprintf(outputfile, "1       ");
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%-8i", hdr->edfparam[signalslist[i]].dig_min);
  }
  if(hdr->edf)
  {
    fprintf(outputfile, "%s", "-32768  ");
  }
  else
  {
    fprintf(outputfile, "%s", "-8388608");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%-8i", hdr->edfparam[signalslist[i]].dig_max);
  }
  if(hdr->edf)
  {
    fprintf(outputfile, "%s", "32767   ");
  }
  else
  {
    fprintf(outputfile, "%s", "8388607 ");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", hdr->edfparam[signalslist[i]].prefilter);
  }
  for(i=0; i<80; i++)
  {
    fputc(' ', outputfile);
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%-8i", hdr->edfparam[signalslist[i]].smp_per_record);
  }
  fprintf(outputfile, "%-8i", annot_smp_per_record);
  for(i=0; i<((new_edfsignals * 32) + 32); i++)
  {
   fputc(' ', outputfile);
  }

///////////////////////////////////////////////////////////////////

  QProgressDialog progress("Saving file...", "Abort", 0, datarecords, mainwindow);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

  progress_steps = datarecords / 100;
  if(progress_steps < 1)
  {
    progress_steps = 1;
  }

  fseeko(inputfile, (long long)(hdr->hdrsize), SEEK_SET);

  annot = annotlist;

  time = hdr->starttime_offset;

  for(k=0; k<datarecords; k++)
  {
    if(!(k%progress_steps))
    {
      progress.setValue(k);

      qApp->processEvents();

      if(progress.wasCanceled() == true)
      {
        free(readbuf);
        free(annot_buf);
        return(4);
      }
    }

    if(fread(readbuf, hdr->recordsize, 1, inputfile) != 1)
    {
      free(readbuf);
      free(annot_buf);
      return(2);
    }

    if(hdr->edf)
    {
      for(i=0; i<new_edfsignals; i++)
      {
        for(j=0; j<hdr->edfparam[signalslist[i]].smp_per_record; j++)
        {
          fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 2))), outputfile);
          fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 2) + 1)), outputfile);
        }
      }
    }
    else
    {
      for(i=0; i<new_edfsignals; i++)
      {
        for(j=0; j<hdr->edfparam[signalslist[i]].smp_per_record; j++)
        {
          fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 3))), outputfile);
          fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 1)), outputfile);
          fputc(*((unsigned char *)(readbuf + hdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 2)), outputfile);
        }
      }
    }

#ifdef Q_OS_WIN32
    switch(timestamp_decimals)
    {
      case 0 : p = __mingw_snprintf(annot_buf, 16, "+%lli", time / TIME_DIMENSION);
                break;
      case 1 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%01lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000000LL);
                break;
      case 2 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%02lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100000LL);
                break;
      case 3 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%03lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10000LL);
                break;
      case 4 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%04lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000LL);
                break;
      case 5 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%05lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100LL);
                break;
      case 6 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%06lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10LL);
                break;
      case 7 : p = __mingw_snprintf(annot_buf, 16, "+%lli.%07lli", time / TIME_DIMENSION, time % TIME_DIMENSION);
                break;
    }
#else
    switch(timestamp_decimals)
    {
      case 0 : p = snprintf(annot_buf, 16, "+%lli", time / TIME_DIMENSION);
                break;
      case 1 : p = snprintf(annot_buf, 16, "+%lli.%01lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000000LL);
                break;
      case 2 : p = snprintf(annot_buf, 16, "+%lli.%02lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100000LL);
                break;
      case 3 : p = snprintf(annot_buf, 16, "+%lli.%03lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10000LL);
                break;
      case 4 : p = snprintf(annot_buf, 16, "+%lli.%04lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 1000LL);
                break;
      case 5 : p = snprintf(annot_buf, 16, "+%lli.%05lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 100LL);
                break;
      case 6 : p = snprintf(annot_buf, 16, "+%lli.%06lli", time / TIME_DIMENSION, (time % TIME_DIMENSION) / 10LL);
                break;
      case 7 : p = snprintf(annot_buf, 16, "+%lli.%07lli", time / TIME_DIMENSION, time % TIME_DIMENSION);
                break;
    }
#endif
    annot_buf[p++] = 20;
    annot_buf[p++] = 20;
    annot_buf[p++] = 0;

    if(annot!=NULL)
    {
      for(i=0; i<annots_per_datrec; i++)
      {
        if(annot!=NULL)
        {
          if(annot->onset<0)
          {
#ifdef Q_OS_WIN32
            p += __mingw_snprintf(annot_buf + p, 20, "-%lli.%07lli", -(annot->onset / TIME_DIMENSION), -(annot->onset % TIME_DIMENSION));
#else
            p += snprintf(annot_buf + p, 20, "-%lli.%07lli", -(annot->onset / TIME_DIMENSION), -(annot->onset % TIME_DIMENSION));
#endif
          }
          else
          {
#ifdef Q_OS_WIN32
            p += __mingw_snprintf(annot_buf + p, 20, "+%lli.%07lli", annot->onset / TIME_DIMENSION, annot->onset % TIME_DIMENSION);
#else
            p += snprintf(annot_buf + p, 20, "+%lli.%07lli", annot->onset / TIME_DIMENSION, annot->onset % TIME_DIMENSION);
#endif
          }

          for(j=0; j<7; j++)
          {
            if(annot_buf[p - j - 1] != '0')
            {
              break;
            }
          }

          if(j)
          {
            p -= j;

            if(j == 7)
            {
              p--;
            }
          }

          if(annot->duration[0])
          {
            annot_buf[p++] = 21;

            p += sprintf(annot_buf + p, "%s", annot->duration);
          }

          annot_buf[p++] = 20;

          p += sprintf(annot_buf + p, "%s", annot->annotation);

          annot_buf[p++] = 20;
          annot_buf[p++] = 0;

          annot = annot->next_annotation;
        }
      }
    }

    for(; p<annot_recordsize; p++)
    {
      annot_buf[p] = 0;
    }

    if(fwrite(annot_buf, annot_recordsize, 1, outputfile) != 1)
    {
      free(readbuf);
      free(annot_buf);
      return(3);
    }

    time += hdr->long_data_record_duration;
  }

  progress.reset();

  free(readbuf);
  free(annot_buf);

  return(0);
}
Exemplo n.º 2
0
void UI_ReduceSignalsWindow::StartConversion()
{
  int i, j, k, n,
      new_edfsignals,
      datarecords=0,
      annot_smp_per_record,
      annot_recordsize,
      timestamp_digits=0,
      timestamp_decimals=0,
      annot_len,
      tallen=0,
      len,
      annot_cnt,
      annots_per_datrec=0,
      smplrt,
      tmp,
      val,
      progress_steps,
      datrecs_processed;

  char *readbuf=NULL,
       scratchpad[256];

  long long new_starttime,
            time_diff,
            onset_diff,
            taltime,
            l_temp,
            endtime=0,
            l_tmp;

  struct date_time_struct dts;

  struct annotationblock *new_annot_list=NULL,
                         *root_new_annot_list=NULL,
                         *annot_list=NULL;

  union {
          unsigned int one;
          signed int one_signed;
          unsigned short two[2];
          signed short two_signed[2];
          unsigned char four[4];
        } var;

  QProgressDialog progress("Processing file...", "Abort", 0, 1);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);


  pushButton3->setEnabled(false);
  pushButton4->setEnabled(false);
  pushButton5->setEnabled(false);
  pushButton6->setEnabled(false);
  spinBox1->setEnabled(false);
  spinBox2->setEnabled(false);
  spinBox3->setEnabled(false);
  spinBox4->setEnabled(false);
  radioButton1->setEnabled(false);
  radioButton2->setEnabled(false);
  label2->setEnabled(false);
  label3->setEnabled(false);

  if(edfhdr==NULL)
  {
    return;
  }

  if(file_num < 0)
  {
    return;
  }

  new_edfsignals = 0;

  annot_smp_per_record = 0;

  annot_cnt = 0;

  aa_filter_order = spinBox4->value() - 1;

  time_diff = (long long)(spinBox1->value() - 1) * edfhdr->long_data_record_duration;

  taltime = (time_diff + edfhdr->starttime_offset) % TIME_DIMENSION;

  endtime = (long long)(spinBox2->value() - (spinBox1->value() - 1)) * edfhdr->long_data_record_duration + taltime;

  for(i=0; i<edfhdr->edfsignals; i++)
  {
    if(!edfhdr->edfparam[i].annotation)
    {
      if(((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->checkState()==Qt::Checked)
      {
        signalslist[new_edfsignals] = i;

        dividerlist[new_edfsignals] = ((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->itemData(((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->currentIndex()).toInt();

        new_edfsignals++;
      }
    }
  }

  datarecords = spinBox2->value() - spinBox1->value() + 1;

  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    timestamp_decimals = get_tal_timestamp_decimal_cnt(edfhdr);
    if(timestamp_decimals < 0)
    {
      showpopupmessage("Error", "Internal error, get_tal_timestamp_decimal_cnt(");
      goto END_1;
    }

    timestamp_digits = get_tal_timestamp_digit_cnt(edfhdr);
    if(timestamp_digits < 0)
    {
      showpopupmessage("Error", "Internal error, get_tal_timestamp_digit_cnt(");
      goto END_1;
    }

    annot_list = mainwindow->annotationlist[file_num];

    while(annot_list != NULL)
    {
      l_temp = annot_list->onset - time_diff;

      if((l_temp >= 0LL) && (l_temp <= endtime))
      {
        annot_cnt++;

        edfplus_annotation_add_copy(&new_annot_list, annot_list);
      }

      annot_list = annot_list->next_annotation;
    }

    annot_list = new_annot_list;

    root_new_annot_list = new_annot_list;

    new_starttime = edfhdr->utc_starttime + ((time_diff + edfhdr->starttime_offset) / TIME_DIMENSION);

    onset_diff = (new_starttime - edfhdr->utc_starttime) * TIME_DIMENSION;

    while(annot_list != NULL)
    {
      annot_list->onset -= onset_diff;

      annot_list = annot_list->next_annotation;
    }

    edfplus_annotation_sort(&new_annot_list);

    annots_per_datrec = annot_cnt / datarecords;

    if(annot_cnt % datarecords)
    {
      annots_per_datrec++;
    }

    annot_len = get_max_annotation_strlen(&new_annot_list);

    if(!annot_cnt)
    {
      annots_per_datrec = 0;
    }

    annot_recordsize = (annot_len * annots_per_datrec) + timestamp_digits + timestamp_decimals + 4;

    if(timestamp_decimals)
    {
      annot_recordsize++;
    }

    if(edfhdr->edf)
    {
      annot_smp_per_record = annot_recordsize / 2;

      if(annot_recordsize % annot_smp_per_record)
      {
        annot_smp_per_record++;

        annot_recordsize = annot_smp_per_record * 2;
      }
    }
    else
    {
      annot_smp_per_record = annot_recordsize / 3;

      if(annot_recordsize % annot_smp_per_record)
      {
        annot_smp_per_record++;

        annot_recordsize = annot_smp_per_record * 3;
      }
    }
  }
  else
  {
    annot_smp_per_record = 0;

    annot_recordsize = 0;
  }

  readbuf = (char *)malloc(edfhdr->recordsize);
  if(readbuf==NULL)
  {
    showpopupmessage("Error", "Malloc error, (readbuf).");
    goto END_2;
  }
///////////////////////////////////////////////////////////////////

  for(i=0; i<new_edfsignals; i++)
  {
    if(dividerlist[i] > 1)
    {
      for(j=0; j<aa_filter_order; j++)
      {
        filterlist[i][j] = create_ravg_filter(1, dividerlist[i]);

        if(filterlist[i][j] == NULL)
        {
          showpopupmessage("Error", "Malloc error, (create_ravg_filter()).");

          goto END_3;
        }
      }
    }
  }
///////////////////////////////////////////////////////////////////

  outputpath[0] = 0;
  if(recent_savedir[0]!=0)
  {
    strcpy(outputpath, recent_savedir);
    strcat(outputpath, "/");
  }
  len = strlen(outputpath);
  get_filename_from_path(outputpath + len, inputpath, MAX_PATH_LENGTH - len);
  remove_extension_from_filename(outputpath);
  if(edfhdr->edf)
  {
    strcat(outputpath, "_reduced.edf");

    strcpy(outputpath, QFileDialog::getSaveFileName(0, "Save file", QString::fromLocal8Bit(outputpath), "EDF files (*.edf *.EDF)").toLocal8Bit().data());
  }
  else
  {
    strcat(outputpath, "_reduced.bdf");

    strcpy(outputpath, QFileDialog::getSaveFileName(0, "Save file", QString::fromLocal8Bit(outputpath), "BDF files (*.bdf *.BDF)").toLocal8Bit().data());
  }

  if(!strcmp(outputpath, ""))
  {
    goto END_3;
  }

  get_directory_from_path(recent_savedir, outputpath, MAX_PATH_LENGTH);

  if(mainwindow->file_is_opened(outputpath))
  {
    showpopupmessage("Reduce signals", "Error, selected file is in use.");
    goto END_3;
  }

  outputfile = fopeno(outputpath, "wb");
  if(outputfile==NULL)
  {
    showpopupmessage("Error", "Can not open outputfile for writing.");
    goto END_3;
  }

  new_starttime = edfhdr->utc_starttime + ((time_diff + edfhdr->starttime_offset) / TIME_DIMENSION);

  utc_to_date_time(new_starttime, &dts);

  rewind(inputfile);
  if(fread(scratchpad, 168, 1, inputfile)!=1)
  {
    showpopupmessage("Error", "Read error (1).");
    goto END_4;
  }

  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    if(scratchpad[98] != 'X')
    {
      sprintf(scratchpad + 98, "%02i-%s-%04i", dts.day, dts.month_str, dts.year);

      scratchpad[109] = ' ';
    }
  }

  if(fwrite(scratchpad, 168, 1, outputfile)!=1)
  {
    showpopupmessage("Error", "Write error (1).");
    goto END_4;
  }

  fprintf(outputfile, "%02i.%02i.%02i%02i.%02i.%02i",
          dts.day,
          dts.month,
          dts.year % 100,
          dts.hour,
          dts.minute,
          dts.second);

  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    fprintf(outputfile, "%-8i", new_edfsignals * 256 + 512);
  }
  else
  {
    fprintf(outputfile, "%-8i", new_edfsignals * 256 + 256);
  }
  if(edfhdr->edfplus)
  {
    fprintf(outputfile, "EDF+C");
    for(i=0; i<39; i++)
    {
      fputc(' ', outputfile);
    }
  }
  if(edfhdr->bdfplus)
  {
    fprintf(outputfile, "BDF+C");
    for(i=0; i<39; i++)
    {
      fputc(' ', outputfile);
    }
  }
  if((!edfhdr->edfplus) && (!edfhdr->bdfplus))
  {
    for(i=0; i<44; i++)
    {
      fputc(' ', outputfile);
    }
  }
  fprintf(outputfile, "%-8i", datarecords);
  snprintf(scratchpad, 256, "%f", edfhdr->data_record_duration);
  convert_trailing_zeros_to_spaces(scratchpad);
  if(scratchpad[7]=='.')
  {
    scratchpad[7] = ' ';
  }
  scratchpad[8] = 0;

  fprintf(outputfile, "%s", scratchpad);
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    fprintf(outputfile, "%-4i", new_edfsignals + 1);
  }
  else
  {
    fprintf(outputfile, "%-4i", new_edfsignals);
  }

  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].label);
  }
  if(edfhdr->edfplus)
  {
    fprintf(outputfile, "EDF Annotations ");
  }
  if(edfhdr->bdfplus)
  {
    fprintf(outputfile, "BDF Annotations ");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].transducer);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    for(i=0; i<80; i++)
    {
      fputc(' ', outputfile);
    }
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].physdimension);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    for(i=0; i<8; i++)
    {
      fputc(' ', outputfile);
    }
  }
  for(i=0; i<new_edfsignals; i++)
  {
    snprintf(scratchpad, 256, "%f", edfhdr->edfparam[signalslist[i]].phys_min);
    convert_trailing_zeros_to_spaces(scratchpad);
    if(scratchpad[7]=='.')
    {
      scratchpad[7] = ' ';
    }
    scratchpad[8] = 0;
    fprintf(outputfile, "%s", scratchpad);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    fprintf(outputfile, "-1      ");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    snprintf(scratchpad, 256, "%f", edfhdr->edfparam[signalslist[i]].phys_max);
    convert_trailing_zeros_to_spaces(scratchpad);
    if(scratchpad[7]=='.')
    {
      scratchpad[7] = ' ';
    }
    scratchpad[8] = 0;
    fprintf(outputfile, "%s", scratchpad);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    fprintf(outputfile, "1       ");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].dig_min);
  }
  if(edfhdr->edfplus)
  {
    fprintf(outputfile, "-32768  ");
  }
  if(edfhdr->bdfplus)
  {
    fprintf(outputfile, "-8388608");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].dig_max);
  }
  if(edfhdr->edfplus)
  {
    fprintf(outputfile, "32767   ");
  }
  if(edfhdr->bdfplus)
  {
    fprintf(outputfile, "8388607 ");
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].prefilter);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    for(i=0; i<80; i++)
    {
      fputc(' ', outputfile);
    }
  }
  for(i=0; i<new_edfsignals; i++)
  {
    fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i]);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    fprintf(outputfile, "%-8i", annot_smp_per_record);
  }
  for(i=0; i<(new_edfsignals * 32); i++)
  {
   fputc(' ', outputfile);
  }
  if(edfhdr->edfplus || edfhdr->bdfplus)
  {
    for(i=0; i<32; i++)
    {
      fputc(' ', outputfile);
    }
  }
///////////////////////////////////////////////////////////////////

  progress.setRange(0, datarecords);
  progress.setValue(0);

  progress_steps = datarecords / 100;
  if(progress_steps < 1)
  {
    progress_steps = 1;
  }

  fseeko(inputfile, (long long)edfhdr->hdrsize + ((long long)(spinBox1->value() - 1) * (long long)edfhdr->recordsize), SEEK_SET);

  for(datrecs_processed=0; datrecs_processed<datarecords; datrecs_processed++)
  {
    if(!(datrecs_processed % progress_steps))
    {
      progress.setValue(datrecs_processed);

      qApp->processEvents();

      if(progress.wasCanceled() == true)
      {
        goto END_4;
      }
    }

    if(fread(readbuf, edfhdr->recordsize, 1, inputfile) != 1)
    {
      progress.reset();
      showpopupmessage("Error", "Read error (2).");
      goto END_4;
    }

    if(edfhdr->edf)
    {
      for(i=0; i<new_edfsignals; i++)
      {
        if(dividerlist[i] == 1)
        {
          smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record;

          for(j=0; j<smplrt; j++)
          {
            fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 2)], outputfile);
            if(fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 2) + 1], outputfile)==EOF)
            {
              progress.reset();
              showpopupmessage("Error", "Write error (4).");
              goto END_4;
            }
          }
        }
        else
        {
          smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i];

          for(j=0; j<smplrt; j++)
          {
            tmp = 0;

            for(k=0; k<dividerlist[i]; k++)
            {
              val = *(((signed short *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset)) + (dividerlist[i] * j) + k);

              for(n=0; n<aa_filter_order; n++)
              {
                val = run_ravg_filter(val, filterlist[i][n]);
              }

              tmp += val;
            }

            tmp /= dividerlist[i];

            fputc(tmp & 0xff, outputfile);
            if(fputc((tmp >> 8) & 0xff, outputfile)==EOF)
            {
              progress.reset();
              showpopupmessage("Error", "Write error (4).");
              goto END_4;
            }
          }
        }
      }
    }
    else
    {
      for(i=0; i<new_edfsignals; i++)
      {
        if(dividerlist[i] == 1)
        {
          smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record;

          for(j=0; j<smplrt; j++)
          {
            fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3)], outputfile);
            fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 1], outputfile);
            if(fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 2], outputfile)==EOF)
            {
              progress.reset();
              showpopupmessage("Error", "Write error (4).");
              goto END_4;
            }
          }
        }
        else
        {
          smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i];

          for(j=0; j<smplrt; j++)
          {
            l_tmp = 0LL;

            for(k=0; k<dividerlist[i]; k++)
            {
              var.two[0] = *((unsigned short *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset + (dividerlist[i] * j * 3) + (k * 3)));
              var.four[2] = *((unsigned char *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset + (dividerlist[i] * j * 3) + (k * 3) + 2));

              if(var.four[2]&0x80)
              {
                var.four[3] = 0xff;
              }
              else
              {
                var.four[3] = 0x00;
              }

              for(n=0; n<aa_filter_order; n++)
              {
                var.one_signed = run_ravg_filter(var.one_signed, filterlist[i][n]);
              }

              l_tmp += var.one_signed;
            }

            l_tmp /= dividerlist[i];

            fputc(l_tmp & 0xff, outputfile);
            fputc((l_tmp >> 8) & 0xff, outputfile);
            if(fputc((l_tmp >> 16) & 0xff, outputfile)==EOF)
            {
              progress.reset();
              showpopupmessage("Error", "Write error (4).");
              goto END_4;
            }
          }
        }
      }
    }

    if(edfhdr->edfplus || edfhdr->bdfplus)
    {
      switch(timestamp_decimals)
      {
        case 0 : tallen = fprintf(outputfile, "+%i", (int)(taltime / TIME_DIMENSION));
                  break;
        case 1 : tallen = fprintf(outputfile, "+%i.%01i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 1000000LL));
                  break;
        case 2 : tallen = fprintf(outputfile, "+%i.%02i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 100000LL));
                  break;
        case 3 : tallen = fprintf(outputfile, "+%i.%03i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 10000LL));
                  break;
        case 4 : tallen = fprintf(outputfile, "+%i.%04i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 1000LL));
                  break;
        case 5 : tallen = fprintf(outputfile, "+%i.%05i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 100LL));
                  break;
        case 6 : tallen = fprintf(outputfile, "+%i.%06i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 10LL));
                  break;
        case 7 : tallen = fprintf(outputfile, "+%i.%07i", (int)(taltime / TIME_DIMENSION), (int)(taltime % TIME_DIMENSION));
                  break;
      }

      fputc(20, outputfile);
      fputc(20, outputfile);
      fputc(0, outputfile);

      tallen += 3;

      if(new_annot_list != NULL)
      {
        for(i=0; i<annots_per_datrec; i++)
        {
          if(new_annot_list != NULL)
          {
            len = snprintf(scratchpad, 256, "%+i.%07i",
            (int)(new_annot_list->onset / TIME_DIMENSION),
            (int)(new_annot_list->onset % TIME_DIMENSION));

            for(j=0; j<7; j++)
            {
              if(scratchpad[len - j - 1] != '0')
              {
                break;
              }
            }

            if(j)
            {
              len -= j;

              if(j == 7)
              {
                len--;
              }
            }

            if(fwrite(scratchpad, len, 1, outputfile) != 1)
            {
              progress.reset();
              showpopupmessage("Error", "Write error (5).");
              goto END_4;
            }

            tallen += len;

            if(new_annot_list->duration[0]!=0)
            {
              fputc(21, outputfile);
              tallen++;

              tallen += fprintf(outputfile, "%s", new_annot_list->duration);
            }

            fputc(20, outputfile);
            tallen++;

            tallen += fprintf(outputfile, "%s", new_annot_list->annotation);

            fputc(20, outputfile);
            fputc(0, outputfile);
            tallen += 2;

            new_annot_list = new_annot_list->next_annotation;
          }
        }
      }

      for(k=tallen; k<annot_recordsize; k++)
      {
        fputc(0, outputfile);
      }

      taltime += edfhdr->long_data_record_duration;
    }
  }