Exemplo n.º 1
0
int EDF_annotations::get_annotations(int file_num, struct edfhdrblock *edf_hdr, struct annotationblock **annotslist, int read_nk_trigger_signal)
{
  int i, j, k, p, r=0, n,
      edfsignals,
      datarecords,
      recordsize,
      discontinuous,
      *annot_ch,
      nr_annot_chns,
      max,
      onset,
      duration,
      duration_start,
      zero,
      max_tal_ln,
      error,
      annots_in_record,
      annots_in_tal,
      samplesize=2,
      nk_triggers_smpls=0,
      nk_triggers_bufoffset=0,
      nk_triggers_enabled=0,
      nk_triggers_channel=0,
      nk_triggers_cnt=0,
      sf,
      progress_steps;

  unsigned short nk_triggerfields=0,
                 nk_old_triggerfields=0;

  char *scratchpad,
       *cnv_buf,
       *time_in_txt,
       *duration_in_txt,
       nk_triggerlabel[16][32];


  long long data_record_duration,
            elapsedtime,
            time_tmp=0LL,
            nk_trigger_sample_duration=0LL;

  FILE *inputfile;

  struct edfparamblock *edfparam;

  struct annotationblock *new_annotation=NULL,
                         *temp_annotation;



  inputfile = edf_hdr->file_hdl;
  edfsignals = edf_hdr->edfsignals;
  recordsize = edf_hdr->recordsize;
  edfparam = edf_hdr->edfparam;
  nr_annot_chns = edf_hdr->nr_annot_chns;
  datarecords = edf_hdr->datarecords;
  data_record_duration = edf_hdr->long_data_record_duration;
  discontinuous = edf_hdr->discontinuous;
  annot_ch = edf_hdr->annot_ch;

  if(edf_hdr->edfplus)
  {
    samplesize = 2;
  }
  if(edf_hdr->bdfplus)
  {
    samplesize = 3;
  }

  if((edf_hdr->edfplus) && (read_nk_trigger_signal))
  {
    if(data_record_duration == 1000000LL)
    {
      if(check_device(edf_hdr->plus_equipment) == 0)
      {
        for(i=0; i<edfsignals; i++)
        {
          if(!strcmp(edfparam[i].label, "Events/Markers  "))
          {
            sf = edf_hdr->edfparam[i].smp_per_record;

            error = 1;

            switch(sf)
            {
              case  10 : error = 0;
                         break;
              case  20 : error = 0;
                         break;
              case  50 : error = 0;
                         break;
              case 100 : error = 0;
                         break;
            }

            for(j=0; j<edfsignals; j++)
            {
              if(edf_hdr->edfparam[j].smp_per_record != sf)
              {
                if(!edf_hdr->edfparam[j].annotation)
                {
                  error = 1;
                }
              }
            }

            if(edf_hdr->nr_annot_chns != 1)  error = 1;

            if(!error)
            {
              nk_triggers_channel = i;

              nk_triggers_bufoffset = edfparam[nk_triggers_channel].buf_offset;

              nk_triggers_smpls = edfparam[nk_triggers_channel].smp_per_record;

              nk_trigger_sample_duration = data_record_duration / (long long)nk_triggers_smpls;

              strcpy(nk_triggerlabel[0], "CAL mode");
              strcpy(nk_triggerlabel[1], "RESET condition");
              strcpy(nk_triggerlabel[2], "External mark");
              strcpy(nk_triggerlabel[3], "Photo/HV mark");
              strcpy(nk_triggerlabel[4], "Remote mark");
              strcpy(nk_triggerlabel[5], "HV mark");
              strcpy(nk_triggerlabel[6], "DC trigger 9");
              strcpy(nk_triggerlabel[7], "DC trigger 10");
              strcpy(nk_triggerlabel[8], "DC trigger 11");
              strcpy(nk_triggerlabel[9], "DC trigger 12");
              strcpy(nk_triggerlabel[10], "DC trigger 13");
              strcpy(nk_triggerlabel[11], "DC trigger 14");
              strcpy(nk_triggerlabel[12], "DC trigger 15");
              strcpy(nk_triggerlabel[13], "DC trigger 16");
              strcpy(nk_triggerlabel[14], "");
              strcpy(nk_triggerlabel[15], "");

              nk_triggers_enabled = 1;

              edf_hdr->genuine_nk = 1;

              break;
            }
          }
        }
      }
    }
  }

  cnv_buf = (char *)calloc(1, recordsize);
  if(cnv_buf==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(cnv_buf)");
    messagewindow.exec();
    return(1);
  }

  max_tal_ln = 0;

  for(i=0; i<nr_annot_chns; i++)
  {
    if(max_tal_ln<edfparam[annot_ch[i]].smp_per_record * samplesize)  max_tal_ln = edfparam[annot_ch[i]].smp_per_record * samplesize;
  }

  if(max_tal_ln<128)  max_tal_ln = 128;

  scratchpad = (char *)calloc(1, max_tal_ln + 3);
  if(scratchpad==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(scratchpad)");
    messagewindow.exec();
    free(cnv_buf);
    return(1);
  }

  time_in_txt = (char *)calloc(1, max_tal_ln + 3);
  if(time_in_txt==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(time_in_txt)");
    messagewindow.exec();
    free(cnv_buf);
    free(scratchpad);
    return(1);
  }

  duration_in_txt = (char *)calloc(1, max_tal_ln + 3);
  if(duration_in_txt==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(duration_in_txt)");
    messagewindow.exec();
    free(cnv_buf);
    free(scratchpad);
    free(time_in_txt);
    return(1);
  }

  if(fseeko(inputfile, (long long)((edfsignals + 1) * 256), SEEK_SET))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading inputfile annotations. (fseek())");
    messagewindow.exec();
    free(cnv_buf);
    free(scratchpad);
    free(time_in_txt);
    free(duration_in_txt);
    return(2);
  }

  QProgressDialog progress("Scanning file for annotations...", "Abort", 0, datarecords);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

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

  elapsedtime = 0;

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

      qApp->processEvents();

      if(progress.wasCanceled() == true)
      {
        edf_hdr->annots_not_read = 1;

        free(cnv_buf);
        free(scratchpad);
        free(time_in_txt);
        free(duration_in_txt);
        return(11);
      }
    }

    if(fread(cnv_buf, recordsize, 1, inputfile)!=1)
    {
      progress.reset();
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile annotations. (fread())");
      messagewindow.exec();
      free(cnv_buf);
      free(scratchpad);
      free(time_in_txt);
      free(duration_in_txt);
      return(2);
    }


/************** process annotationsignals (if any) **************/

    error = 0;

    for(r=0; r<nr_annot_chns; r++)
    {
      n = 0;
      zero = 0;
      onset = 0;
      duration = 0;
      duration_start = 0;
      scratchpad[0] = 0;
      annots_in_tal = 0;
      annots_in_record = 0;

      p = edfparam[annot_ch[r]].buf_offset;
      max = edfparam[annot_ch[r]].smp_per_record * samplesize;

/************** process one annotation signal ****************/

      if(cnv_buf[p + max - 1]!=0)
      {
        error = 5;
        goto END;
      }

      if(!r)  /* if it's the first annotation signal, then check */
      {       /* the timekeeping annotation */
        error = 1;

        for(k=0; k<(max-2); k++)
        {
          scratchpad[k] = cnv_buf[p + k];

          if(scratchpad[k]==20)
          {
            if(cnv_buf[p + k + 1]!=20)
            {
              error = 6;
              goto END;
            }
            scratchpad[k] = 0;
            if(is_onset_number(scratchpad))
            {
              error = 36;
              goto END;
            }
            else
            {
              time_tmp = get_long_time(scratchpad);
              if(i)
              {
                if(discontinuous)
                {
                  if((time_tmp-elapsedtime)<data_record_duration)
                  {
                    error = 4;
                    goto END;
                  }
                }
                else
                {
                  if((time_tmp-elapsedtime)!=data_record_duration)
                  {
                    error = 3;
                    goto END;
                  }
                }
              }
              else
              {
                if(time_tmp>=TIME_DIMENSION)
                {
                  error = 2;
                  goto END;
                }
                else
                {
                  edf_hdr->starttime_offset = time_tmp;
                }
              }
              elapsedtime = time_tmp;
              error = 0;
              break;
            }
          }
        }
      }

      for(k=0; k<max; k++)
      {
        scratchpad[n] = cnv_buf[p + k];

        if(!scratchpad[n])
        {
          if(!zero)
          {
            if(k)
            {
              if(cnv_buf[p + k - 1]!=20)
              {
                error = 33;
                goto END;
              }
            }
            n = 0;
            onset = 0;
            duration = 0;
            duration_start = 0;
            scratchpad[0] = 0;
            annots_in_tal = 0;
          }
          zero++;
          continue;
        }
        if(zero>1)
        {
          error = 34;
          goto END;
        }
        zero = 0;

        if((scratchpad[n]==20)||(scratchpad[n]==21))
        {
          if(scratchpad[n]==21)
          {
            if(duration||duration_start||onset||annots_in_tal)
            {               /* it's not allowed to have multiple duration fields */
              error = 35;   /* in one TAL or to have a duration field which is   */
              goto END;     /* not immediately behind the onsetfield             */
            }
            duration_start = 1;
          }

          if((scratchpad[n]==20)&&onset&&(!duration_start))
          {
            if(r||annots_in_record)
            {
              if(n >= 0)
              {
                new_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
                if(new_annotation==NULL)
                {
                  progress.reset();
                  QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred while reading annotations.");
                  messagewindow.exec();
                  free(cnv_buf);
                  free(scratchpad);
                  free(time_in_txt);
                  free(duration_in_txt);
                  return(1);
                }

                new_annotation->next_annotation = NULL;
                new_annotation->file_num = file_num;

                new_annotation->annotation[0] = 0;

                if(duration)  strcpy(new_annotation->duration, duration_in_txt);
                else  new_annotation->duration[0] = 0;

                for(j=0; j<n; j++)
                {
                  if(j==MAX_ANNOTATION_LEN)  break;
                  new_annotation->annotation[j] = scratchpad[j];
                }
                new_annotation->annotation[j] = 0;

                new_annotation->file_num = edf_hdr->file_num;

                new_annotation->onset = get_long_time(time_in_txt);

                if(*annotslist!=NULL)
                {
                  temp_annotation = *annotslist;
                  while(temp_annotation->next_annotation)  temp_annotation = temp_annotation->next_annotation;

                  new_annotation->former_annotation = temp_annotation;
                  temp_annotation->next_annotation = new_annotation;
                }
                else
                {
                  new_annotation->former_annotation = NULL;
                  *annotslist = new_annotation;
                }
              }
            }

            annots_in_tal++;
            annots_in_record++;
            n = 0;
            continue;
          }

          if(!onset)
          {
            scratchpad[n] = 0;
            if(is_onset_number(scratchpad))
            {
              error = 36;
              goto END;
            }
            onset = 1;
            n = 0;
            strcpy(time_in_txt, scratchpad);
            continue;
          }

          if(duration_start)
          {
            scratchpad[n] = 0;
            if(is_duration_number(scratchpad))
            {
              error = 37;
              goto END;
            }

            for(j=0; j<n; j++)
            {
              if(j==15)  break;
              duration_in_txt[j] = scratchpad[j];
              if((duration_in_txt[j]<32)||(duration_in_txt[j]>126))
              {
                duration_in_txt[j] = '.';
              }
            }
            duration_in_txt[j] = 0;

            duration = 1;
            duration_start = 0;
            n = 0;
            continue;
          }
        }

        n++;
      }

 END:

/****************** end ************************/

      if(error)
      {
        progress.reset();
        QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not read annotations because there is an EDF or BDF incompatibility in this file.\n"
                                                                  "For more information, run the EDF/BDF compatibility checker in the Tools menu.");
        messagewindow.exec();
        free(cnv_buf);
        free(scratchpad);
        free(time_in_txt);
        free(duration_in_txt);
        return(9);
      }
    }

/************** process NK triggers ****************/

    if(nk_triggers_enabled)
    {
      if(nk_triggers_cnt < 100000)
      {
        for(k=0; k<nk_triggers_smpls; k++)
        {
          nk_triggerfields = *((unsigned char *)cnv_buf + nk_triggers_bufoffset + (k * 2) + 1);

          nk_triggerfields <<= 8;

          nk_triggerfields += *((unsigned char *)cnv_buf + nk_triggers_bufoffset + (k * 2));

          for(j=0; j<14; j++)
          {
            if((nk_triggerfields & (1 << j)) && (!(nk_old_triggerfields & (1 << j))))
            {
              nk_triggers_cnt++;

              new_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
              if(new_annotation==NULL)
              {
                progress.reset();
                QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred while reading annotations.");
                messagewindow.exec();
                free(cnv_buf);
                free(scratchpad);
                free(time_in_txt);
                free(duration_in_txt);
                return(1);
              }

              new_annotation->file_num = edf_hdr->file_num;
              new_annotation->next_annotation = NULL;
              new_annotation->file_num = file_num;
              strcpy(new_annotation->annotation, nk_triggerlabel[j]);

              new_annotation->onset = ((long long)i * data_record_duration) + ((long long)k * nk_trigger_sample_duration);

              new_annotation->onset += edf_hdr->starttime_offset;

              new_annotation->ident = (1 << ANNOT_ID_NK_TRIGGER);

              if(*annotslist!=NULL)
              {
                temp_annotation = *annotslist;
                while(temp_annotation->next_annotation)  temp_annotation = temp_annotation->next_annotation;

                new_annotation->former_annotation = temp_annotation;
                temp_annotation->next_annotation = new_annotation;
              }
              else
              {
                new_annotation->former_annotation = NULL;
                *annotslist = new_annotation;
              }
            }
          }

          nk_old_triggerfields = nk_triggerfields;
        }
      }

      edf_hdr->nk_triggers_read = 1;
    }
  }

  edfplus_annotation_sort(&annotslist[file_num]);

  progress.reset();

  free(cnv_buf);
  free(scratchpad);
  free(time_in_txt);
  free(duration_in_txt);

  return(0);
}
Exemplo n.º 2
0
void UI_ExportAnnotationswindow::ExportButtonClicked()
{
  int i, j, n,
      len,
      csv_format=0,
      hdl,
      annot_cnt,
      temp,
      include_duration;

  char path[MAX_PATH_LENGTH],
       str[1024],
       separator;

  FILE *annotationfile=NULL;

  struct annotationblock *annot, *annot_list;

  struct edfhdrblock *hdr;

  struct date_time_struct tm;


  if(CSVRadioButton->isChecked() == true)
  {
    if(asciiSecondsRadioButton->isChecked() == true)
    {
      csv_format = 1;
    }

    if(asciiISOtimeRadioButton->isChecked() == true)
    {
      csv_format = 2;
    }

    if(asciiISOtimedateRadioButton->isChecked() == true)
    {
      csv_format = 3;
    }

    if(asciiISOtimeFractionRadioButton->isChecked() == true)
    {
      csv_format = 4;
    }

    if(asciiISOtimedateFractionRadioButton->isChecked() == true)
    {
      csv_format = 5;
    }
  }

  if(EDFplusRadioButton->isChecked() == true)
  {
    csv_format = 0;
  }

  if(XMLRadioButton->isChecked() == true)
  {
    csv_format = 8;
  }

   mainwindow->export_annotations_var->format = csv_format;

  if(separatorBox->currentIndex() == 0)
  {
    separator = ',';
    mainwindow->export_annotations_var->separator = 0;
  }
  else
  {
    separator = '\t';
    mainwindow->export_annotations_var->separator = 1;
  }

  if(durationCheckBox->checkState() == Qt::Checked)
  {
    include_duration = 1;
    mainwindow->export_annotations_var->duration = 1;
  }
  else
  {
    include_duration = 0;
    mainwindow->export_annotations_var->duration = 0;
  }

  if(!mainwindow->files_open)
  {
    ExportAnnotsDialog->close();
    return;
  }

  if(filelist->count() < 1)
  {
    ExportAnnotsDialog->close();
    return;
  }

  ExportButton->setEnabled(false);
  CloseButton->setEnabled(false);

  for(i=0; i<mainwindow->files_open; i++)
  {
    if(!strcmp(mainwindow->edfheaderlist[i]->filename, filelist->item(filelist->currentRow())->text().toLocal8Bit().data()))
    {
      break;
    }
  }

  if(i==mainwindow->files_open)
  {
    ExportAnnotsDialog->close();
    return;
  }

  n = i;

  if(mergeRadioButton->isChecked() == true)
  {
    n = mainwindow->sel_viewtime;
  }

  hdr = mainwindow->edfheaderlist[n];

  path[0] = 0;
  if(mainwindow->recent_savedir[0]!=0)
  {
    strcpy(path, mainwindow->recent_savedir);
    strcat(path, "/");
  }
  len = strlen(path);
  get_filename_from_path(path + len, mainwindow->edfheaderlist[n]->filename, MAX_PATH_LENGTH - len);
  remove_extension_from_filename(path);
  if((csv_format > 0) && (csv_format < 6))
  {
    strcat(path, "_annotations.txt");

    strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT *.csv *.CSV)").toLocal8Bit().data());
  }

  if(csv_format == 8)
  {
    strcat(path, "_annotations.xml");

    strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "XML files (*.xml *.XML)").toLocal8Bit().data());
  }

  if(csv_format == 0)
  {
    strcat(path, "_annotations.edf");

    strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "EDF files (*.edf *.EDF)").toLocal8Bit().data());
  }

  if(!strcmp(path, ""))
  {
    ExportAnnotsDialog->close();
    return;
  }

  get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH);

  if(mainwindow->file_is_opened(path))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Export annotations", "Error, selected file is in use.");
    messagewindow.exec();
    return;
  }

  annot_list = edfplus_annotation_copy_list(&mainwindow->annotationlist[n]);

  if(mergeRadioButton->isChecked() == true)
  {
    for(i=0; i < mainwindow->files_open; i++)
    {
      if(i != mainwindow->sel_viewtime)
      {
        annot_cnt = edfplus_annotation_count(&mainwindow->annotationlist[i]);

        for(j=0; j < annot_cnt; j++)
        {
          edfplus_annotation_add_copy(&annot_list, edfplus_annotation_item(&mainwindow->annotationlist[i], j));

          annot = edfplus_annotation_item(&annot_list, edfplus_annotation_count(&annot_list) - 1);

          annot->onset -= (mainwindow->edfheaderlist[i]->viewtime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime);
        }
      }
    }

    edfplus_annotation_sort(&annot_list);
  }

  annot_cnt = edfplus_annotation_count(&annot_list);

///////////////////////////// CSV (text) export //////////////////////////////////////

  if((csv_format > 0) && (csv_format < 6))
  {
    annotationfile = fopeno(path, "wb");
    if(annotationfile==NULL)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open annotationfile for writing.");
      messagewindow.exec();
      ExportAnnotsDialog->close();
      edfplus_annotation_delete_list(&annot_list);
      return;
    }

    if(include_duration)
    {
      fprintf(annotationfile, "Onset%cDuration%cAnnotation\n", separator, separator);
    }
    else
    {
      fprintf(annotationfile, "Onset%cAnnotation\n", separator);
    }

    for(j=0; j < annot_cnt; j++)
    {
      annot = edfplus_annotation_item(&annot_list, j);
      if(annot == NULL)
      {
        break;
      }
      strncpy(str, annot->annotation, 1024);
      str[1023] = 0;
      utf8_to_latin1(str);

      len = strlen(str);
      for(i=0; i<len; i++)
      {
        if((((unsigned char *)str)[i] < 32) || (((unsigned char *)str)[i] == ','))
        {
          str[i] = '.';
        }
      }

      if(csv_format == 1)
      {
        if(include_duration)
        {
          fprintf(annotationfile, "%+.7f%c%s%c%s\n", (double)(annot->onset - hdr->starttime_offset) / TIME_DIMENSION, separator, annot->duration, separator, str);
        }
        else
        {
          fprintf(annotationfile, "%+.7f%c%s\n", (double)(annot->onset - hdr->starttime_offset) / TIME_DIMENSION, separator, str);
        }
      }

      if(csv_format == 2)
      {
        temp = annot->onset % TIME_DIMENSION;

        if(temp < 0)
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm);
        }
        else
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm);
        }

        if(include_duration)
        {
          fprintf(annotationfile, "%02i:%02i:%02i%c%s%c%s\n", tm.hour, tm.minute, tm.second, separator, annot->duration, separator, str);
        }
        else
        {
          fprintf(annotationfile, "%02i:%02i:%02i%c%s\n", tm.hour, tm.minute, tm.second, separator, str);
        }
      }

      if(csv_format == 3)
      {
        temp = annot->onset % TIME_DIMENSION;

        if(temp < 0)
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm);
        }
        else
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm);
        }

        if(include_duration)
        {
          fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i%c%s%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, separator, annot->duration, separator, str);
        }
        else
        {
          fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, separator, str);
        }
      }

      if(csv_format == 4)
      {
        temp = annot->onset % TIME_DIMENSION;

        if(temp < 0)
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm);

          temp = TIME_DIMENSION + temp;
        }
        else
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm);
        }

        if(include_duration)
        {
          fprintf(annotationfile, "%02i:%02i:%02i.%07i%c%s%c%s\n", tm.hour, tm.minute, tm.second, temp, separator, annot->duration, separator, str);
        }
        else
        {
          fprintf(annotationfile, "%02i:%02i:%02i.%07i%c%s\n", tm.hour, tm.minute, tm.second, temp, separator, str);
        }
      }

      if(csv_format == 5)
      {
        temp = annot->onset % TIME_DIMENSION;

        if(temp < 0)
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm);

          temp = TIME_DIMENSION + temp;
        }
        else
        {
          utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm);
        }

        if(include_duration)
        {
          fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i.%07i%c%s%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, separator, annot->duration, separator, str);
        }
        else
        {
          fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i.%07i%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, separator, str);
        }
      }
    }

    fclose(annotationfile);

    edfplus_annotation_delete_list(&annot_list);

    QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done.");
    messagewindow.setIconPixmap(QPixmap(":/images/ok.png"));
    messagewindow.exec();

    ExportAnnotsDialog->close();

    return;
  }

///////////////////////////// XML export //////////////////////////////////////

  if(csv_format == 8)
  {
    annotationfile = fopeno(path, "wb");
    if(annotationfile==NULL)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open annotationfile for writing.");
      messagewindow.exec();
      ExportAnnotsDialog->close();
      edfplus_annotation_delete_list(&annot_list);
      return;
    }

    fprintf(annotationfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");

    fprintf(annotationfile, "<!-- Generated by " PROGRAM_NAME " " PROGRAM_VERSION " -->\n");

    fprintf(annotationfile, "<annotationlist>\n");

    utc_to_date_time(hdr->utc_starttime, &tm);

    fprintf(annotationfile, " <recording_start_time>%04i-%02i-%02iT%02i:%02i:%02i.%07i</recording_start_time>\n",
                            tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, (int)hdr->starttime_offset);

    for(j=0; j < annot_cnt; j++)
    {
      annot = edfplus_annotation_item(&annot_list, j);
      if(annot == NULL)
      {
        break;
      }

      temp = annot->onset % TIME_DIMENSION;

      if(temp < 0)
      {
        utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm);

        temp = TIME_DIMENSION + temp;
      }
      else
      {
        utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm);
      }

      fprintf(annotationfile, " <annotation>\n"
                              "  <onset>%04i-%02i-%02iT%02i:%02i:%02i.%07i</onset>\n"
                              "  <duration>%s</duration>\n"
                              "  <description>",
                              tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, annot->duration);

      xml_fwrite_encode_entity(annotationfile, annot->annotation);

      fprintf(annotationfile,                     "</description>\n"
                              " </annotation>\n");
    }

    fprintf(annotationfile, "</annotationlist>\n");

    fclose(annotationfile);

    edfplus_annotation_delete_list(&annot_list);

    QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done.");
    messagewindow.setIconPixmap(QPixmap(":/images/ok.png"));
    messagewindow.exec();

    ExportAnnotsDialog->close();

    return;
  }

///////////////////////////// EDFplus export //////////////////////////////////////

  if(csv_format == 0)
  {
    hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, 0);
    if(hdl < 0)
    {
      switch(hdl)
      {
        case EDFLIB_MALLOC_ERROR : strcpy(str, "EDFlib: malloc error");
                                  break;
        case EDFLIB_NO_SUCH_FILE_OR_DIRECTORY : strcpy(str, "EDFlib: no such file or directory");
                                  break;
        case EDFLIB_MAXFILES_REACHED : strcpy(str, "EDFlib: maximum files reached");
                                  break;
        case EDFLIB_FILE_ALREADY_OPENED : strcpy(str, "EDFlib: file already opened");
                                  break;
        case EDFLIB_NUMBER_OF_SIGNALS_INVALID : strcpy(str, "EDFlib: number of signals is invalid");
                                  break;
        default : strcpy(str, "EDFlib: unknown error");
                                  break;
      }

      QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
      messagewindow.exec();
      edfplus_annotation_delete_list(&annot_list);
      ExportAnnotsDialog->close();
      return;
    }

    utc_to_date_time(hdr->utc_starttime, &tm);
    edf_set_startdatetime(hdl, tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second);

    if((hdr->edfplus) || (hdr->bdfplus))
    {
      edf_set_patientname(hdl, hdr->plus_patient_name);
      edf_set_patientcode(hdl, hdr->plus_patientcode);
      if(!(strcmp(hdr->plus_gender, "Male")))
      {
        edf_set_gender(hdl, 1);
      }
      if(!(strcmp(hdr->plus_gender, "Female")))
      {
        edf_set_gender(hdl, 0);
      }
      if(hdr->plus_birthdate[0] != 0)
      {
        if(!(strncmp(hdr->plus_birthdate + 3, "jan", 3)))  n = 1;
        if(!(strncmp(hdr->plus_birthdate + 3, "feb", 3)))  n = 2;
        if(!(strncmp(hdr->plus_birthdate + 3, "mar", 3)))  n = 3;
        if(!(strncmp(hdr->plus_birthdate + 3, "apr", 3)))  n = 4;
        if(!(strncmp(hdr->plus_birthdate + 3, "may", 3)))  n = 5;
        if(!(strncmp(hdr->plus_birthdate + 3, "jun", 3)))  n = 6;
        if(!(strncmp(hdr->plus_birthdate + 3, "jul", 3)))  n = 7;
        if(!(strncmp(hdr->plus_birthdate + 3, "aug", 3)))  n = 8;
        if(!(strncmp(hdr->plus_birthdate + 3, "sep", 3)))  n = 9;
        if(!(strncmp(hdr->plus_birthdate + 3, "oct", 3)))  n = 10;
        if(!(strncmp(hdr->plus_birthdate + 3, "nov", 3)))  n = 11;
        if(!(strncmp(hdr->plus_birthdate + 3, "dec", 3)))  n = 12;
        edf_set_birthdate(hdl, atoi(hdr->plus_birthdate + 7), n, atoi(hdr->plus_birthdate));
      }
      edf_set_patient_additional(hdl, hdr->plus_patient_additional);
      edf_set_admincode(hdl, hdr->plus_admincode);
      edf_set_technician(hdl, hdr->plus_technician);
      edf_set_equipment(hdl, hdr->plus_equipment);
      edf_set_recording_additional(hdl, hdr->plus_recording_additional);
    }
    else
    {
      edf_set_patientname(hdl, hdr->patient);
      edf_set_recording_additional(hdl, hdr->recording);
    }

    int hasdot,
        decimals;

    for(j=0; j < annot_cnt; j++)
    {
      annot = edfplus_annotation_item(&annot_list, j);
      if(annot == NULL)
      {
        break;
      }

      if(annot->duration[0] == 0)
      {
        edfwrite_annotation_utf8(hdl, annot->onset / 1000LL, -1LL, annot->annotation);
      }
      else
      {
        strcpy(str, annot->duration);

        len = strlen(str);

        hasdot = 0;

        for(i=0; i<len; i++)
        {
          if(str[i] == '.')
          {
            hasdot = 1;

            for(decimals=0; decimals<4; decimals++)
            {
              str[i] = str[i+1];

              if(str[i] == 0)
              {
                for( ; decimals<4; decimals++)
                {
                  str[i] = '0';

                  i++;
                }

                i--;
              }

              i++;
            }

            str[i] = 0;

            break;
          }
        }

        if(!hasdot)
        {
          strcat(str, "0000");
        }

        edfwrite_annotation_utf8(hdl, annot->onset / 1000LL, atoi(str), annot->annotation);
      }
    }

    if(edfclose_file(hdl) != 0)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred: edfclose_file()");
      messagewindow.exec();
    }

    edfplus_annotation_delete_list(&annot_list);

    QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done.");
    messagewindow.setIconPixmap(QPixmap(":/images/ok.png"));
    messagewindow.exec();

    ExportAnnotsDialog->close();
  }
}
Exemplo n.º 3
0
void UI_Annotationswindow::updateList(void)
{
  char str[MAX_ANNOTATION_LEN + 32],
       *str_tmp;

  int i,
      len,
      sequence_nr=0,
      jump=0,
      modified=0;

  QListWidgetItem *listitem;

  QString string;

  QByteArray ba;


  selected = -1;

#ifdef Q_OS_WIN32
  QFont specialfont("courier", 11, QFont::Normal, true);
#else
  QFont specialfont("andale mono", 12, QFont::Normal, true);
#endif

  specialfont.setPixelSize(12);

  list->clear();

  edfplus_annotation_sort(&mainwindow->annotationlist[file_num]);

  annotation = mainwindow->annotationlist[file_num];

  while(annotation != NULL)
  {
    if(annotation->hided_in_list)
    {
      annotation = annotation->next_annotation;

      sequence_nr++;

      continue;
    }

    string = QString::fromUtf8(annotation->annotation);

    ba = string.toUtf8();
    str_tmp = ba.data();

    len = 0;
    for(i=0; ; i++)
    {
      if(str_tmp[i]==0)  break;

      if(((((unsigned char *)str_tmp)[i])&224)==192)  len++;
    }

    for(i=0; i<len; i++)  string.append(' ');

    if(relative)
    {
      if((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) < 0LL)
      {
        snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, "  -%2i:%02i:%02i.%04i",
                (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600),
                (int)(((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60),
                (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60),
                (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL));
      }
      else
      {
        snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, "  %3i:%02i:%02i.%04i",
                (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600),
                (int)((((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60),
                (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60),
                (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL));
      }
    }
    else
    {
      snprintf(str, MAX_ANNOTATION_LEN + 32, "  %3i:%02i:%02i.%04i",
              (int)((((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) / TIME_DIMENSION)/ 3600) % 24),
              (int)((((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) / TIME_DIMENSION) % 3600) / 60),
              (int)(((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) / TIME_DIMENSION) % 60),
              (int)(((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) % TIME_DIMENSION) / 1000LL));
    }

    str[MAX_ANNOTATION_LEN + 31] = 0;

    remove_trailing_zeros(str);

    if(string.size() < 20)
    {
      string = string.leftJustified(20, ' ');
    }

    string.append(QString::fromLatin1(str));

    listitem = new QListWidgetItem(string, list);

    listitem->setData(Qt::UserRole, QVariant(sequence_nr));

    if(annotation->modified==1)
    {
      listitem->setFont(specialfont);

      listitem->setForeground(Qt::red);

      modified = 1;
    }

    if((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) < 0LL)
    {
      snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, "onset: -%i:%02i:%02i.%04i",
              (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600),
              (int)(((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60),
              (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60),
              (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL));
    }
    else
    {
      snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, "onset: %2i:%02i:%02i.%04i",
              (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600),
              (int)((((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60),
              (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60),
              (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL));
    }

    if(annotation->duration[0]!=0)
    {
      snprintf(str + strlen(str), (MAX_ANNOTATION_LEN + 32) / 2, "\nduration: %s",annotation->duration);
    }

    str[MAX_ANNOTATION_LEN + 31] = 0;

    remove_trailing_zeros(str);

    strcat(str, "\n\n");

    string = QString::fromLatin1(str);

    string.append(QString::fromUtf8(annotation->annotation));

    listitem->setToolTip(string);

    if(annotation->selected)
    {
      selected = sequence_nr;

      annotation->selected = 0;

      if(annotation->jump)
      {
        jump = 1;

        annotation->jump = 0;
      }
    }

    annotation = annotation->next_annotation;

    sequence_nr++;
  }

  if(mainwindow->annot_editor_active)
  {
    if(selected>=0)
    {
      list->setCurrentRow(selected, QItemSelectionModel::ClearAndSelect);

      mainwindow->annotationEditDock->set_selected_annotation(file_num, selected);

      if(jump)
      {
        jump = 0;

        annotation_selected(list->currentItem());
      }

      selected = -1;
    }

    if(modified)
    {
      mainwindow->annotations_edited = 1;

      mainwindow->save_act->setEnabled(true);
    }
  }
}
Exemplo n.º 4
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;
    }
  }