Esempio n. 1
0
void UI_BIOSEMI2BDFPLUSwindow::SelectFileButton()
{
  int i, j, k,
      error,
      hdl_in,
      hdl_out,
      edfsignals,
      status_signal=0,
      status_samples_in_datarecord=0,
      rising_edge,
      set_duration,
      status[24],
      totalSamplesInDatarecord,
      *buf,
      buf_offset[EDFLIB_MAXSIGNALS],
      sf,
      new_sf,
      samplerate_divider;

  char str[2048],
       triggerlabel[24][64],
       outputfilename[MAX_PATH_LENGTH];

  long long datarecords,
            status_sample_duration,
            trigger_cnt,
            progress_steps;

  struct edf_hdr_struct hdr;

  struct annotationblock *annotlist=NULL;

  struct annotationblock *annotation;


  for(i=0; i<16; i++)
  {
    if(!lineEdit1[i]->text().length())
    {
      sprintf(str, "Trigger Input label %i is empty!", i + 1);
      QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
      messagewindow.exec();
      return;
    }
  }

  for(i=0; i<16; i++)
  {
    for(j=0; j<16; j++)
    {
      if(i != j)
      {
        if(!strcmp(lineEdit1[i]->text().toLocal8Bit().data(), lineEdit1[j]->text().toLocal8Bit().data()))
        {
          sprintf(str, "Trigger Input labels %i and %i are the same!", i + 1, j + 1);
          QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
          messagewindow.exec();
          return;
        }
      }
    }
  }

  str[0] = 0;

  strcpy(inputpath, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "BDF files (*.bdf *.BDF)").toLocal8Bit().data());

  if(!strcmp(inputpath, ""))
  {
    return;
  }

  get_directory_from_path(recent_opendir, inputpath, MAX_PATH_LENGTH);

  error = edfopen_file_readonly(inputpath, &hdr, EDFLIB_DO_NOT_READ_ANNOTATIONS);

  if(error < 0)
  {
    error = hdr.filetype;

    switch(error)
    {
      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_FILE_CONTAINS_FORMAT_ERRORS : strcpy(str, "EDFlib: file contains format errors.\nOpen the file in EDFbrowser to get more info.");
                                                break;
      case EDFLIB_MAXFILES_REACHED            : strcpy(str, "EDFlib: maximum amount of files reached.");
                                                break;
      case EDFLIB_FILE_READ_ERROR             : strcpy(str, "EDFlib: a file read error occurred.");
                                                break;
      case EDFLIB_FILE_ALREADY_OPENED         : strcpy(str, "EDFlib: file is already opened.");
                                                break;
      case EDFLIB_FILETYPE_ERROR              : strcpy(str, "EDFlib: filetype error.");
                                                break;
      case EDFLIB_FILE_WRITE_ERROR            : strcpy(str, "EDFlib: file write error.");
                                                break;
      case EDFLIB_NUMBER_OF_SIGNALS_INVALID   : strcpy(str, "EDFlib: invalid number of signals.");
                                                break;
      case EDFLIB_FILE_IS_DISCONTINUOUS       : strcpy(str, "EDFlib: file is discontinuous.");
                                                break;
      case EDFLIB_INVALID_READ_ANNOTS_VALUE   : strcpy(str, "EDFlib: invalid read annotations argument.");
                                                break;
      default                                 : strcpy(str, "EDFlib: unknown error.");
    }

    QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
    messagewindow.exec();

    return;
  }

  hdl_in = hdr.handle;

/////////////////// check file /////////////////////////////////////////////

  if(hdr.filetype == EDFLIB_FILETYPE_BDFPLUS)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Selected file is already a BDF-plus file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  if(hdr.filetype != EDFLIB_FILETYPE_BDF)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Selected file is not a BDF file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  if(hdr.datarecord_duration != EDFLIB_TIME_DIMENSION)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Datarecord duration of inputfile must be 1 second.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  edfsignals = hdr.edfsignals;

  if(edfsignals < 1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "There are no signals in the selected file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  sf = hdr.signalparam[0].smp_in_datarecord;

  for(i=1; i<edfsignals; i++)
  {
    if(hdr.signalparam[i].smp_in_datarecord != sf)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "All signals must have the same samplefrequency.");
      messagewindow.exec();
      edfclose_file(hdl_in);
      return;
    }
  }

  error = 1;

  switch(sf)
  {
    case 16384 : error = 0;
                 break;
    case  8192 : error = 0;
                 break;
    case  4096 : error = 0;
                 break;
    case  2048 : error = 0;
                 break;
    case  1024 : error = 0;
                 break;
    case   512 : error = 0;
                 break;
    case   256 : error = 0;
                 break;
    case   128 : error = 0;
                 break;
    case    64 : error = 0;
                 break;
    case    32 : error = 0;
                 break;
  }

  if(error)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Samplefrequency must be 16384, 8192, 4096, 2048, 1024, 512, 256, 128, 64 or 32 Hz.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  for(i=0; i<edfsignals; i++)
  {
    if(!(strcmp(hdr.signalparam[i].label, "Status          ")))
    {
      status_signal = i;

      break;
    }
  }

  if(i == edfsignals)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "There is no Status signal in the selected file.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  totalSamplesInDatarecord = 0;

  for(i=0; i<edfsignals; i++)
  {
    buf_offset[i] = totalSamplesInDatarecord;

    if(i == status_signal)
    {
      status_samples_in_datarecord = hdr.signalparam[i].smp_in_datarecord;
    }

    totalSamplesInDatarecord += hdr.signalparam[i].smp_in_datarecord;
  }

  status_sample_duration = EDFLIB_TIME_DIMENSION / (long long)status_samples_in_datarecord;

  for(i=0; i<16; i++)
  {
    strcpy(&triggerlabel[i][0], lineEdit1[i]->text().toUtf8().data());
    triggerlabel[i][16] = 0;
  }

  strcpy(&triggerlabel[16][0], "new epoch");

  if(radioButton1->isChecked() == true)
  {
    rising_edge = 1;

    for(i=0; i<16; i++)
    {
      status[i] = 1;
    }
  }
  else
  {
    rising_edge = 0;

    for(i=0; i<16; i++)
    {
      status[i] = 0;
    }
  }

  if(checkBox1->isChecked() == true)
  {
    set_duration = 1;
  }
  else
  {
    set_duration = 0;
  }

  for(i=16; i<24; i++)
  {
    status[i] = 1;
  }

  strcpy(outputfilename, inputpath);
  remove_extension_from_filename(outputfilename);
  strcat(outputfilename, "_+.bdf");

  outputpath[0] = 0;
  if(recent_savedir[0]!=0)
  {
    strcpy(outputpath, recent_savedir);
    strcat(outputpath, "/");
  }
  strcat(outputpath, outputfilename);

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

  if(!strcmp(outputpath, ""))
  {
    edfclose_file(hdl_in);
    return;
  }

  get_directory_from_path(recent_savedir, outputpath, MAX_PATH_LENGTH);

  if(mainwindow->file_is_opened(outputpath))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Outputfile is already opened in EDFbrowser.\nClose the file and try again.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  if(!(strcmp(inputpath, outputpath)))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Inputfile and outputfile are the same.");
    messagewindow.exec();
    edfclose_file(hdl_in);
    return;
  }

  hdl_out = edfopen_file_writeonly(outputpath, EDFLIB_FILETYPE_BDFPLUS, edfsignals);

  if(hdl_out < 0)
  {
    switch(hdl_out)
    {
      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 amount of files reached.");
                                                break;
      case EDFLIB_FILE_READ_ERROR             : strcpy(str, "EDFlib: a file read error occurred.");
                                                break;
      case EDFLIB_FILE_ALREADY_OPENED         : strcpy(str, "EDFlib: file is already opened.");
                                                break;
      case EDFLIB_FILETYPE_ERROR              : strcpy(str, "EDFlib: filetype error.");
                                                break;
      case EDFLIB_FILE_WRITE_ERROR            : strcpy(str, "EDFlib: file write error.");
                                                break;
      case EDFLIB_NUMBER_OF_SIGNALS_INVALID   : strcpy(str, "EDFlib: invalid number of signals.");
                                                break;
      default                                 : strcpy(str, "EDFlib: unknown error.");
    }

    QMessageBox messagewindow(QMessageBox::Critical, "Error", str);
    messagewindow.exec();

    edfclose_file(hdl_in);
    return;
  }

/////////////////// copy header /////////////////////////////////////////////

  for(i=0; i<edfsignals; i++)
  {
    edf_set_samplefrequency(hdl_out, i, hdr.signalparam[i].smp_in_datarecord);
    edf_set_physical_maximum(hdl_out, i, hdr.signalparam[i].phys_max);
    edf_set_physical_minimum(hdl_out, i, hdr.signalparam[i].phys_min);
    edf_set_digital_maximum(hdl_out, i, hdr.signalparam[i].dig_max);
    edf_set_digital_minimum(hdl_out, i, hdr.signalparam[i].dig_min);
    edf_set_label(hdl_out, i, hdr.signalparam[i].label);
    edf_set_prefilter(hdl_out, i, hdr.signalparam[i].prefilter);
    edf_set_transducer(hdl_out, i, hdr.signalparam[i].transducer);
    edf_set_physical_dimension(hdl_out, i, hdr.signalparam[i].physdimension);
  }

  edf_set_startdatetime(hdl_out, hdr.startdate_year, hdr.startdate_month, hdr.startdate_day, hdr.starttime_hour, hdr.starttime_minute, hdr.starttime_second);
  edf_set_patientname(hdl_out, hdr.patient);
  edf_set_recording_additional(hdl_out, hdr.recording);

/////////////////// collect triggers /////////////////////////////////////////////

  buf = (int *)malloc(sizeof(int) * status_samples_in_datarecord);
  if(buf == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (buf).");
    messagewindow.exec();
    edfclose_file(hdl_in);
    edfclose_file(hdl_out);
    return;
  }

  QProgressDialog progress("Collecting triggers...", "Abort", 0, (int)hdr.datarecords_in_file);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

  progress_steps = hdr.datarecords_in_file / 100LL;
  if(progress_steps < 1LL)
  {
    progress_steps = 1LL;
  }

  trigger_cnt = 0;

  for(datarecords = 0LL; datarecords < hdr.datarecords_in_file; datarecords++)
  {
    if(trigger_cnt >= ((hdr.datarecords_in_file * 32) - 2))
    {
      break;
    }

    if(trigger_cnt >= 100000)
    {
      break;
    }

    if(!(datarecords % progress_steps))
    {
      progress.setValue((int)datarecords);

      qApp->processEvents();

      if(progress.wasCanceled())
      {
        edfclose_file(hdl_in);
        edfclose_file(hdl_out);
        free(buf);
        edfplus_annotation_delete_list(&annotlist);
        return;
      }
    }

    if(edfread_digital_samples(hdl_in, status_signal, status_samples_in_datarecord, buf) < 0)
    {
      progress.reset();
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred during the collection of triggers.");
      messagewindow.exec();
      edfclose_file(hdl_in);
      edfclose_file(hdl_out);
      free(buf);
      edfplus_annotation_delete_list(&annotlist);
      return;
    }

    for(i=0; i<status_samples_in_datarecord; i++)
    {
      for(j=0; j<17; j++)
      {
        if(((buf[i] & (1 << j)) && !status[j]) || (!(buf[i] & (1 << j)) && status[j]))  // rising or falling edge detected
        {
          if(status[j])  // falling edge detected
          {
            if((!rising_edge) && (j < 16))
            {
              annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
              if(annotation == NULL)
              {
                progress.reset();
                QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (annotation).");
                messagewindow.exec();
                edfclose_file(hdl_in);
                edfclose_file(hdl_out);
                free(buf);
                edfplus_annotation_delete_list(&annotlist);
                return;
              }
              annotation->onset = (datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration);
              annotation->onset += hdr.starttime_subsecond;
              strcpy(annotation->annotation, triggerlabel[j]);
              edfplus_annotation_add_item(&annotlist, annotation);

              trigger_cnt++;
            }
            else
            {
              if(set_duration)
              {
                k = edfplus_annotation_count(&annotlist);
                for(; k>0; k--)
                {
                  annotation = edfplus_annotation_item(&annotlist, k - 1);
                  if(annotation == NULL)
                  {
                    break;
                  }
                  if(!strcmp(annotation->annotation, triggerlabel[j]))
                  {
                    sprintf(str, "%.4f", (double)((datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration) - annotation->onset) / (double)EDFLIB_TIME_DIMENSION);
                    str[15] = 0;
                    strcpy(annotation->duration, str);
                    break;
                  }
                }
              }
            }

            status[j] = 0;
          }
          else  // rising edge detected
          {
            if(rising_edge || (j == 16))
            {
              annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock));
              if(annotation == NULL)
              {
                progress.reset();
                QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (annotation).");
                messagewindow.exec();
                edfclose_file(hdl_in);
                edfclose_file(hdl_out);
                free(buf);
                edfplus_annotation_delete_list(&annotlist);
                return;
              }
              annotation->onset = (datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration);
              annotation->onset += hdr.starttime_subsecond;
              strcpy(annotation->annotation, triggerlabel[j]);
              edfplus_annotation_add_item(&annotlist, annotation);

              trigger_cnt++;
            }
            else
            {
              if(set_duration)
              {
                k = edfplus_annotation_count(&annotlist);
                for(; k>0; k--)
                {
                  annotation = edfplus_annotation_item(&annotlist, k - 1);
                  if(annotation == NULL)
                  {
                    break;
                  }
                  if(!strcmp(annotation->annotation, triggerlabel[j]))
                  {
                    sprintf(str, "%.4f", (double)((datarecords * EDFLIB_TIME_DIMENSION) + ((long long)i * status_sample_duration) - annotation->onset) / (double)EDFLIB_TIME_DIMENSION);
                    str[15] = 0;
                    strcpy(annotation->duration, str);
                    break;
                  }
                }
              }
            }

            status[j] = 1;
          }
        }
      }
    }
  }

  edfwrite_annotation_latin1(hdl_out, 0LL, -1LL, "Recording starts");

  j = edfplus_annotation_count(&annotlist);

  for(i=0; i<j; i++)
  {
    annotation = edfplus_annotation_item(&annotlist, i);

    if(annotation->duration[0] == 0)
    {
      edfwrite_annotation_utf8(hdl_out, annotation->onset / 1000LL, -1LL, annotation->annotation);
    }
    else
    {
      edfwrite_annotation_utf8(hdl_out, annotation->onset / 1000LL, (long long)(atof(annotation->duration) * 10000.0), annotation->annotation);
    }
  }

  free(buf);

  edfwrite_annotation_latin1(hdl_out, hdr.datarecords_in_file * 10000LL, -1LL, "Recording ends");

/////////////////// choose datarecord duration /////////////////////////////////////////////

  samplerate_divider = 1;

  i = edfplus_annotation_count(&annotlist);

  edfplus_annotation_delete_list(&annotlist);

  annotlist = NULL;

  if(i % 2)
  {
    i++;
  }

  i += 2;

  while(i > hdr.datarecords_in_file)
  {
    samplerate_divider *= 2;

    i /= 2;

    if(samplerate_divider == 32)
    {
      break;
    }
  }

  if(samplerate_divider > 1)
  {
    for(i=0; i<edfsignals; i++)
    {
      edf_set_samplefrequency(hdl_out, i, hdr.signalparam[i].smp_in_datarecord / samplerate_divider);
    }

    if(edf_set_datarecord_duration(hdl_out, 100000 / samplerate_divider) == -1)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "edf_set_datarecord_duration() returned an error.");
      messagewindow.exec();
      edfclose_file(hdl_in);
      edfclose_file(hdl_out);
      return;
    }
  }

  new_sf = sf / samplerate_divider;

/////////////////// start conversion /////////////////////////////////////////////

  buf = (int *)malloc(sizeof(int) * totalSamplesInDatarecord);
  if(buf == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (buf).");
    messagewindow.exec();
    edfclose_file(hdl_in);
    edfclose_file(hdl_out);
    return;
  }

  edfrewind(hdl_in, status_signal);

  progress.setLabelText("Converting...");
  progress.setValue(0);

  for(datarecords = 0LL; datarecords < hdr.datarecords_in_file; datarecords++)
  {
    if(!(datarecords % progress_steps))
    {
      progress.setValue((int)datarecords);

      qApp->processEvents();

      if(progress.wasCanceled())
      {
        edfclose_file(hdl_in);
        edfclose_file(hdl_out);
        free(buf);
        return;
      }
    }

    for(i=0; i<edfsignals; i++)
    {
      if(edfread_digital_samples(hdl_in, i, hdr.signalparam[i].smp_in_datarecord, buf + buf_offset[i]) < 0)
      {
        progress.reset();
        QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred during the conversion.");
        messagewindow.exec();
        edfclose_file(hdl_in);
        edfclose_file(hdl_out);
        free(buf);
        return;
      }
    }

    for(j=0; j<samplerate_divider; j++)
    {
      for(i=0; i<edfsignals; i++)
      {
        if(edfwrite_digital_samples(hdl_out, buf + buf_offset[i] + (j * new_sf)) < 0)
        {
          progress.reset();
          QMessageBox messagewindow(QMessageBox::Critical, "Error", "A write error occurred during the conversion.");
          messagewindow.exec();
          edfclose_file(hdl_in);
          edfclose_file(hdl_out);
          free(buf);
          return;
        }
      }
    }
  }

  QApplication::setOverrideCursor(Qt::WaitCursor);

  edfclose_file(hdl_in);
  edfclose_file(hdl_out);
  free(buf);

  QApplication::restoreOverrideCursor();

  progress.reset();

#ifdef Q_WS_WIN
  snprintf(str, 2048, "Done. Converted %I64d input trigger events to BDF+ annotations.\n"
                      "\nBDF+ file is located at %s", trigger_cnt, outputpath);
#else
  snprintf(str, 2048, "Done. Converted %lli input trigger events to BDF+ annotations.\n"
                      "\nBDF+ file is located at %s", trigger_cnt, outputpath);
#endif

  QMessageBox messagewindow(QMessageBox::Information, "Ready", str);
  messagewindow.setIconPixmap(QPixmap(":/images/ok.png"));
  messagewindow.exec();
}
Esempio n. 2
0
void UI_AverageCurveWindow::export_edf(void)
{
  int i, j, k, p,
      type,
      edf_hdl,
      smp_per_record,
      datarecords,
      smpls_left;

  char path[MAX_PATH_LENGTH],
       str[512];

  double *buf,
         frequency,
         frequency2;


  smp_per_record = signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].smp_per_record;

  datarecords = avg_samples_on_screen / smp_per_record;

  smpls_left = avg_samples_on_screen % smp_per_record;

  path[0] = 0;
  if(mainwindow->recent_savedir[0]!=0)
  {
    strcpy(path, mainwindow->recent_savedir);
    strcat(path, "/");
  }
  get_filename_from_path(path + strlen(path), signalcomp->edfhdr->filename, 512);
  remove_extension_from_filename(path);
  sprintf(path + strlen(path), " averaging %s %i triggers [%s]",
          signalcomp->signallabel,
          avg_cnt,
          avg_annotation);

  if(signalcomp->edfhdr->edf)
  {
    strcat(path, ".edf");

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

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

  if(!strcmp(path, ""))
  {
    return;
  }

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

  if(signalcomp->edfhdr->edf)
  {
    edf_hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, 1);
  }
  else
  {
    edf_hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_BDFPLUS, 1);
  }

  if(edf_hdl < 0)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open output file for writing.");
    messagewindow.exec();
    return;
  }

  edf_set_samplefrequency(edf_hdl, 0, smp_per_record);

  if(edf_set_datarecord_duration(edf_hdl, signalcomp->edfhdr->long_data_record_duration / 100LL))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Datarecordduration out of range.");
    messagewindow.exec();
    return;
  }

  if(signalcomp->edfhdr->edf)
  {
    edf_set_digital_maximum(edf_hdl, 0, 32767);
    edf_set_digital_minimum(edf_hdl, 0, -32768);
  }
  else
  {
    edf_set_digital_maximum(edf_hdl, 0, 8388607);
    edf_set_digital_minimum(edf_hdl, 0, -8388608);
  }

  edf_set_physical_maximum(edf_hdl, 0, avg_max_value);
  edf_set_physical_minimum(edf_hdl, 0, avg_min_value);
  edf_set_label(edf_hdl, 0, signalcomp->signallabel);
  edf_set_physical_dimension(edf_hdl, 0, signalcomp->physdimension);

  p = 0;

  for(j=0; j<signalcomp->fidfilter_cnt; j++)
  {
    type = signalcomp->fidfilter_type[j];

    frequency = signalcomp->fidfilter_freq[j];

    frequency2 = signalcomp->fidfilter_freq2[j];

    if(type == 0)
    {
      p += sprintf(str + p, "HP:%f", frequency);
    }

    if(type == 1)
    {
      p += sprintf(str + p, "LP:%f", frequency);
    }

    if(type == 2)
    {
      p += sprintf(str + p, "N:%f", frequency);
    }

    if(type == 3)
    {
      p += sprintf(str + p, "BP:%f", frequency);
    }

    if(type == 4)
    {
      p += sprintf(str + p, "BS:%f", frequency);
    }

    for(k=(p-1); k>0; k--)
    {
      if(str[k]!='0')  break;
    }

    if(str[k]=='.')  str[k] = 0;
    else  str[k+1] = 0;

    p = strlen(str);

    if((type == 3) || (type == 4))
    {
      p += sprintf(str + p, "-%f", frequency2);

      for(k=(p-1); k>0; k--)
      {
        if(str[k]!='0')  break;
      }

      if(str[k]=='.')  str[k] = 0;
      else  str[k+1] = 0;
    }

    strcat(str, "Hz ");

    p = strlen(str);

    if(p>80)  break;
  }

  for(j=0; j<signalcomp->ravg_filter_cnt; j++)
  {
    if(signalcomp->ravg_filter_type[j] == 0)
    {
      p += sprintf(str + p, "HP:%iSmpls ", signalcomp->ravg_filter[j]->size);
    }

    if(signalcomp->ravg_filter_type[j] == 1)
    {
      p += sprintf(str + p, "LP:%iSmpls ", signalcomp->ravg_filter[j]->size);
    }

    p = strlen(str);

    if(p>80)  break;
  }

  strcat(str, signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].prefilter);
  edf_set_prefilter(edf_hdl, 0, str);
  edf_set_transducer(edf_hdl, 0, signalcomp->edfhdr->edfparam[signalcomp->edfsignal[0]].transducer);

  if((signalcomp->edfhdr->edfplus) || (signalcomp->edfhdr->bdfplus))
  {
    edf_set_patientname(edf_hdl, signalcomp->edfhdr->plus_patient_name);
    sprintf(str, "%i triggers \"%s\" averaged. %s", avg_cnt, avg_annotation, signalcomp->edfhdr->plus_recording_additional);
    edf_set_recording_additional(edf_hdl, str);
    edf_set_patientcode(edf_hdl, signalcomp->edfhdr->plus_patientcode);
    if(signalcomp->edfhdr->plus_gender[0] == 'M')
    {
      edf_set_gender(edf_hdl, 1);
    }
    if(signalcomp->edfhdr->plus_gender[0] == 'F')
    {
      edf_set_gender(edf_hdl, 0);
    }
    edf_set_patient_additional(edf_hdl, signalcomp->edfhdr->plus_patient_additional);
    edf_set_admincode(edf_hdl, signalcomp->edfhdr->plus_admincode);
    edf_set_technician(edf_hdl, signalcomp->edfhdr->plus_technician);
    edf_set_equipment(edf_hdl, signalcomp->edfhdr->plus_equipment);
  }
  else
  {
    edf_set_patientname(edf_hdl, signalcomp->edfhdr->patient);
    sprintf(str, "%i triggers \"%s\" averaged. %s", avg_cnt, avg_annotation, signalcomp->edfhdr->recording);
    edf_set_recording_additional(edf_hdl, str);
  }

  for(i=0; i<datarecords; i++)
  {
    edfwrite_physical_samples(edf_hdl, avgbuf + (i * smp_per_record));
  }

  if(smpls_left)
  {
    buf = (double *)calloc(1, smp_per_record * sizeof(double));
    if(buf == NULL)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error (buf).");
      messagewindow.exec();
    }
    else
    {
      for(i=0; i<smpls_left; i++)
      {
        buf[i] = avgbuf[(datarecords * smp_per_record) + i];
      }

      edfwrite_physical_samples(edf_hdl, buf);

      free(buf);
    }
  }

  edfwrite_annotation_latin1(edf_hdl,
                             (avg_period * 10000.0) / (double)avg_trigger_position_ratio,
                             -1,
                             avg_annotation);

  edfclose_file(edf_hdl);
}
Esempio n. 3
0
void UI_MIT2EDFwindow::SelectFileButton()
{
  FILE *header_inputfile=NULL,
       *data_inputfile=NULL,
       *annot_inputfile=NULL;

  int i, j, p, len, hdl, *buf;

  char header_filename[MAX_PATH_LENGTH],
       txt_string[2048],
       edf_filename[MAX_PATH_LENGTH],
       data_filename[MAX_PATH_LENGTH],
       annot_filename[MAX_PATH_LENGTH],
       filename_x[MAX_PATH_LENGTH],
       scratchpad[4096],
       *charpntr;

  unsigned char a_buf[128];

  long long filesize;

  pushButton1->setEnabled(false);

  strcpy(header_filename, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "MIT header files (*.hea *.HEA)").toLocal8Bit().data());

  if(!strcmp(header_filename, ""))
  {
    pushButton1->setEnabled(true);
    return;
  }

  get_directory_from_path(recent_opendir, header_filename, MAX_PATH_LENGTH);

  header_inputfile = fopeno(header_filename, "rb");
  if(header_inputfile==NULL)
  {
    snprintf(txt_string, 2048, "Can not open file %s for reading.\n", header_filename);
    textEdit1->append(QString::fromLocal8Bit(txt_string));
    pushButton1->setEnabled(true);
    return;
  }

  get_filename_from_path(filename_x, header_filename, MAX_PATH_LENGTH);

  snprintf(txt_string, 2048, "Read file: %s", filename_x);
  textEdit1->append(QString::fromLocal8Bit(txt_string));

  remove_extension_from_filename(filename_x);

  charpntr = fgets(scratchpad, 4095, header_inputfile);
  if(charpntr == NULL)
  {
    textEdit1->append("Can not read header file. (error 1)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  len = strlen(charpntr);
  if(len < 6)
  {
    textEdit1->append("Can not read header file. (error 2)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  for(i=0; i<len; i++)
  {
    if(charpntr[i] == ' ')
    {
      charpntr[i] = 0;

      break;
    }
  }

  if(i == len)
  {
    textEdit1->append("Can not read header file. (error 3)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  if(strcmp(charpntr, filename_x))
  {
    textEdit1->append("Can not read header file. (error 4)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  p = ++i;

  for(; i<len; i++)
  {
    if(charpntr[i] == ' ')
    {
      charpntr[i] = 0;

      break;
    }
  }

  if(i == p)
  {
    textEdit1->append("Can not read header file. (error 5)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  mit_hdr.chns = atoi(charpntr + p);

  if(mit_hdr.chns < 1)
  {
    textEdit1->append("Error, number of signals is less than one. (error 6)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  if(mit_hdr.chns > MAXSIGNALS)
  {
    textEdit1->append("Error, Too many signals in header. (error 7)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  p = ++i;

  for(; i<len; i++)
  {
    if(charpntr[i] == ' ')
    {
      charpntr[i] = 0;

      break;
    }
  }

  if(i == p)
  {
    textEdit1->append("Can not read header file. (error 8)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  mit_hdr.sf = atoi(charpntr + p);

  if(mit_hdr.sf < 1)
  {
    textEdit1->append("Error, samplefrequency is less than 1 Hz. (error 9)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  if(mit_hdr.sf > 100000)
  {
    textEdit1->append("Error, samplefrequency is more than 100000 Hz. (error 10)\n");
    fclose(header_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  mit_hdr.smp_period = 1000000000LL / mit_hdr.sf;

  strcat(filename_x, ".dat");

  for(j=0; j<mit_hdr.chns; j++)
  {
    mit_hdr.adc_gain[j] = 200.0;

    mit_hdr.adc_resolution[j] = 12;

    mit_hdr.adc_zero[j] = 0;

    mit_hdr.init_val[j] = 0;

    sprintf(mit_hdr.label[j], "chan. %i", j + 1);

    charpntr = fgets(scratchpad, 4095, header_inputfile);
    if(charpntr == NULL)
    {
      textEdit1->append("Can not read header file. (error 11)\n");
      fclose(header_inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    len = strlen(charpntr);
    if(len < 6)
    {
      textEdit1->append("Can not read header file. (error 12)\n");
      fclose(header_inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    for(i=0; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == len)
    {
      textEdit1->append("Can not read header file. (error 13)\n");
      fclose(header_inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    if(strcmp(charpntr, filename_x))
    {
      textEdit1->append("Error, filenames are different. (error 14)\n");
      fclose(header_inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == len)
    {
      textEdit1->append("Can not read header file. (error 15)\n");
      fclose(header_inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    mit_hdr.format[j] = atoi(charpntr + p);

    if((mit_hdr.format[j] != 212) && (mit_hdr.format[j] != 16))
    {
      snprintf(txt_string, 2048, "Error, unsupported format: %i  (error 16)\n", mit_hdr.format[j]);
      textEdit1->append(txt_string);
      fclose(header_inputfile);
      pushButton1->setEnabled(true);
      return;
    }

    if(j>0)
    {
      if(mit_hdr.format[j] != mit_hdr.format[0])
      {
        textEdit1->append("Error, different formats in the same file. (error 17)\n");
        fclose(header_inputfile);
        pushButton1->setEnabled(true);
        return;
      }
    }

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    mit_hdr.adc_gain[j] = atoi(charpntr + p);

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    mit_hdr.adc_resolution[j] = atoi(charpntr + p);

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    mit_hdr.adc_zero[j] = atoi(charpntr + p);

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    mit_hdr.init_val[j] = atoi(charpntr + p);

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    // skip

    p = ++i;

    for(; i<len; i++)
    {
      if(charpntr[i] == ' ')
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    // skip

    p = ++i;

    for(; i<len; i++)
    {
      if((charpntr[i] == '\n') || (charpntr[i] == '\r'))
      {
        charpntr[i] = 0;

        break;
      }
    }

    if(i == p)
    {
      continue;
    }

    strncpy(mit_hdr.label[j], charpntr + p, 16);

    mit_hdr.label[j][16] = 0;
  }

  fclose(header_inputfile);

  strcpy(data_filename, header_filename);

  remove_extension_from_filename(data_filename);

  strcpy(edf_filename, data_filename);

  strcpy(annot_filename, data_filename);

  strcat(data_filename, ".dat");

  strcat(edf_filename, ".edf");

  strcat(annot_filename, ".atr");

  data_inputfile = fopeno(data_filename, "rb");
  if(data_inputfile==NULL)
  {
    snprintf(txt_string, 2048, "Can not open file %s for reading.\n", data_filename);
    textEdit1->append(QString::fromLocal8Bit(txt_string));
    pushButton1->setEnabled(true);
    return;
  }

  fseeko(data_inputfile, 0LL, SEEK_END);
  filesize = ftello(data_inputfile);
  if(filesize < (mit_hdr.chns * mit_hdr.sf * 45 / 10))
  {
    textEdit1->append("Error, .dat filesize is too small.\n");
    fclose(data_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  mit_hdr.sf_div = 1;

  mit_hdr.sf_block = mit_hdr.sf;

  if(!(mit_hdr.sf % 10))
  {
    mit_hdr.sf_div = 10;

    mit_hdr.sf_block /= mit_hdr.sf_div;
  }
  else if(!(mit_hdr.sf % 8))
    {
      mit_hdr.sf_div = 8;

      mit_hdr.sf_block /= mit_hdr.sf_div;
    }
    else if(!(mit_hdr.sf % 4))
      {
        mit_hdr.sf_div = 4;

        mit_hdr.sf_block /= mit_hdr.sf_div;
      }
      else if(!(mit_hdr.sf % 2))
        {
          mit_hdr.sf_div = 2;

          mit_hdr.sf_block /= mit_hdr.sf_div;
        }

  hdl = edfopen_file_writeonly(edf_filename, EDFLIB_FILETYPE_EDFPLUS, mit_hdr.chns);

  if(hdl<0)
  {
    snprintf(txt_string, 2048, "Can not open file %s for writing.\n", edf_filename);
    textEdit1->append(QString::fromLocal8Bit(txt_string));
    fclose(data_inputfile);
    pushButton1->setEnabled(true);
    return;
  }

  for(i=0; i<mit_hdr.chns; i++)
  {
    if(edf_set_samplefrequency(hdl, i, mit_hdr.sf_block))
    {
      textEdit1->append("Error: edf_set_samplefrequency()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }
  }

  for(i=0; i<mit_hdr.chns; i++)
  {
    if(edf_set_digital_minimum(hdl, i, -32768))
    {
      textEdit1->append("Error: edf_set_digital_minimum()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }
  }

  for(i=0; i<mit_hdr.chns; i++)
  {
    if(edf_set_digital_maximum(hdl, i, 32767))
    {
      textEdit1->append("Error: edf_set_digital_maximum()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }
  }

  for(i=0; i<mit_hdr.chns; i++)
  {
    if(edf_set_label(hdl, i, mit_hdr.label[i]))
    {
      textEdit1->append("Error: edf_set_label()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }
  }

  for(i=0; i<mit_hdr.chns; i++)
  {
    if(edf_set_physical_dimension(hdl, i, "uV"))
    {
      textEdit1->append("Error: edf_set_physical_dimension()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }

    if(edf_set_physical_maximum(hdl, i, (double)((32767 - mit_hdr.adc_zero[i]) * 1000) / mit_hdr.adc_gain[i]))
    {
      textEdit1->append("Error: edf_set_physical_maximum()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }

    if(edf_set_physical_minimum(hdl, i, (double)((-32768 - mit_hdr.adc_zero[i]) * 1000) / mit_hdr.adc_gain[i]))
    {
      textEdit1->append("Error: edf_set_physical_minimum()\n");
      fclose(data_inputfile);
      edfclose_file(hdl);
      pushButton1->setEnabled(true);
      return;
    }
  }

  if(edf_set_datarecord_duration(hdl, 100000 / mit_hdr.sf_div))
  {
    textEdit1->append("Error: edf_set_datarecord_duration()\n");
    fclose(data_inputfile);
    edfclose_file(hdl);
    pushButton1->setEnabled(true);
    return;
  }

  buf = (int *)malloc(mit_hdr.sf_block * mit_hdr.chns * sizeof(int));
  if(buf == NULL)
  {
    textEdit1->append("Malloc() error (buf)\n");
    fclose(data_inputfile);
    edfclose_file(hdl);
    pushButton1->setEnabled(true);
    return;
  }

/////////////////// Start conversion //////////////////////////////////////////

  int k, blocks, tmp1, tmp2;

  fseeko(data_inputfile, 0LL, SEEK_SET);

  blocks = filesize / (mit_hdr.sf_block * mit_hdr.chns);

  QProgressDialog progress("Converting digitized signals ...", "Abort", 0, blocks);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

  if(mit_hdr.format[0] == 212)
  {
    blocks *= 10;
    blocks /= 15;

    progress.setMaximum(blocks);

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

        qApp->processEvents();

        if(progress.wasCanceled() == true)
        {
          textEdit1->append("Conversion aborted by user.\n");
          fclose(data_inputfile);
          edfclose_file(hdl);
          free(buf);
          pushButton1->setEnabled(true);
          return;
        }
      }

      for(i=0; i<mit_hdr.sf_block; i++)
      {
        for(j=0; j<mit_hdr.chns; j++)
        {
          if(j % 2)
          {
            tmp1 = fgetc(data_inputfile);
            tmp2 = fgetc(data_inputfile);

            if(tmp2 == EOF)
            {
              goto OUT;
            }

            buf[j * mit_hdr.sf_block + i] = (tmp1 & 0xf0) << 4;
            buf[j * mit_hdr.sf_block + i] += tmp2;
            if(buf[j * mit_hdr.sf_block + i] & 0x800)
            {
              buf[j * mit_hdr.sf_block + i] |= 0xfffff000;
            }
          }
          else
          {
            tmp1 = fgetc(data_inputfile);
            tmp2 = fgetc(data_inputfile);

            buf[j * mit_hdr.sf_block + i] = (tmp2 & 0x0f) << 8;
            buf[j * mit_hdr.sf_block + i] += tmp1;
            if(buf[j * mit_hdr.sf_block + i] & 0x800)
            {
              buf[j * mit_hdr.sf_block + i] |= 0xfffff000;
            }

            fseeko(data_inputfile, -1LL, SEEK_CUR);
          }
        }
      }

      if(edf_blockwrite_digital_samples(hdl, buf))
      {
        progress.reset();
        textEdit1->append("A write error occurred during conversion.\n");
        fclose(data_inputfile);
        edfclose_file(hdl);
        free(buf);
        pushButton1->setEnabled(true);
        return;
      }
    }
  }

  if(mit_hdr.format[0] == 16)
  {
    blocks /= 2;

    progress.setMaximum(blocks);

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

        qApp->processEvents();

        if(progress.wasCanceled() == true)
        {
          textEdit1->append("Conversion aborted by user.\n");
          fclose(data_inputfile);
          edfclose_file(hdl);
          free(buf);
          pushButton1->setEnabled(true);
          return;
        }
      }

      for(i=0; i<mit_hdr.sf_block; i++)
      {
        for(j=0; j<mit_hdr.chns; j++)
        {
          tmp1 = fgetc(data_inputfile);
          if(tmp1 == EOF)
          {
            goto OUT;
          }

          tmp1 += (fgetc(data_inputfile) << 8);

          if(tmp1 & 0x8000)
          {
            tmp1 |= 0xffff0000;
          }

         buf[j * mit_hdr.sf_block + i] = tmp1;
        }
      }

      if(edf_blockwrite_digital_samples(hdl, buf))
      {
        progress.reset();
        textEdit1->append("A write error occurred during conversion.\n");
        fclose(data_inputfile);
        edfclose_file(hdl);
        free(buf);
        pushButton1->setEnabled(true);
        return;
      }
    }
  }

OUT:

  progress.reset();

  qApp->processEvents();

/////////////////// End conversion //////////////////////////////////////////

  fclose(data_inputfile);

  free(buf);

  int annot_code, tc=0, skip;

  long long bytes_read;

  get_filename_from_path(filename_x, annot_filename, MAX_PATH_LENGTH);

  annot_inputfile = fopeno(annot_filename, "rb");
  if(annot_inputfile==NULL)
  {
    remove_extension_from_filename(annot_filename);

    strcat(annot_filename, ".ari");

    annot_inputfile = fopeno(annot_filename, "rb");
  }

  if(annot_inputfile==NULL)
  {
    remove_extension_from_filename(annot_filename);

    strcat(annot_filename, ".ecg");

    annot_inputfile = fopeno(annot_filename, "rb");
  }

  if(annot_inputfile==NULL)
  {
    snprintf(txt_string, 2048, "Can not open file %s for reading.\n"
                               "Annotations can not be included.", filename_x);
    textEdit1->append(QString::fromLocal8Bit(txt_string));
  }
  else
  {
    snprintf(txt_string, 2048, "Read file: %s", filename_x);
    textEdit1->append(QString::fromLocal8Bit(txt_string));

    fseeko(annot_inputfile, 0LL, SEEK_END);
    filesize = ftello(annot_inputfile);

    progress.setLabelText("Converting annotations ...");
    progress.setMinimum(0);
    progress.setMaximum(filesize);

    fseeko(annot_inputfile, 0LL, SEEK_SET);

    for(bytes_read=0LL; bytes_read < filesize; bytes_read += 2LL)
    {
      if(!(bytes_read % 100))
      {
        progress.setValue(bytes_read);

        qApp->processEvents();

        if(progress.wasCanceled() == true)
        {
          textEdit1->append("Conversion aborted by user.\n");

          break;
        }
      }

      skip = 0;

      if(fread(a_buf, 2, 1, annot_inputfile) != 1)
      {
        break;
      }

#pragma GCC diagnostic ignored "-Wstrict-aliasing"

      if(*((unsigned short *)a_buf) == 0)  // end of file
      {
        break;
      }

      annot_code = a_buf[1] >> 2;

      if(annot_code == 59)
      {
        if(fread(a_buf, 4, 1, annot_inputfile) != 1)
        {
          break;
        }

        tc += (*((unsigned short *)a_buf) << 16);

        tc += *((unsigned short *)(a_buf + 2));
      }
      else if(annot_code == 63)
        {
          skip = *((unsigned short *)a_buf) & 0x3ff;

          if(skip % 2) skip++;
        }
        else if((annot_code >= 0) && (annot_code <= ACMAX))
          {
            tc += *((unsigned short *)a_buf) & 0x3ff;

#pragma GCC diagnostic warning "-Wstrict-aliasing"

            if(annot_code < 42)
            {
              edfwrite_annotation_latin1(hdl, ((long long)tc * mit_hdr.smp_period) / 100000LL, -1, annotdescrlist[annot_code]);
            }
            else
            {
              edfwrite_annotation_latin1(hdl, ((long long)tc * mit_hdr.smp_period) / 100000LL, -1, "user-defined");
            }
          }

      if(skip)
      {
        if(fseek(annot_inputfile, skip, SEEK_CUR) < 0)
        {
          break;
        }

        bytes_read += skip;
      }
    }

    fclose(annot_inputfile);
  }

  progress.reset();

  edfclose_file(hdl);

  textEdit1->append("Ready.\n");

  pushButton1->setEnabled(true);
}
Esempio n. 4
0
void UI_Mainwindow::save_screen_waveform()
{
  int i, j,
      n=0,
      chn,
      chns=0,
      hdl=-1,
      yref[MAX_CHNS],
      yor[MAX_CHNS];

  char str[128],
       opath[MAX_PATHLEN];

  short *wavbuf[4];

  long long rec_len=0LL;

  double yinc[MAX_CHNS];

  if(device == NULL)
  {
    return;
  }

  wavbuf[0] = NULL;
  wavbuf[1] = NULL;
  wavbuf[2] = NULL;
  wavbuf[3] = NULL;

  scrn_timer->stop();

  scrn_thread->wait();

  if(devparms.timebasedelayenable)
  {
    rec_len = EDFLIB_TIME_DIMENSION * devparms.timebasedelayscale * devparms.hordivisions;
  }
  else
  {
    rec_len = EDFLIB_TIME_DIMENSION * devparms.timebasescale * devparms.hordivisions;
  }

  if(rec_len < 10LL)
  {
    strcpy(str, "Can not save waveforms when timebase < 1uSec.");
    goto OUT_ERROR;
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])  // Download data only when channel is switched on
    {
      continue;
    }

    wavbuf[chn] = (short *)malloc(WAVFRM_MAX_BUFSZ * sizeof(short));
    if(wavbuf[chn] == NULL)
    {
      strcpy(str, "Malloc error.");
      goto OUT_ERROR;
    }

    chns++;
  }

  if(!chns)
  {
    strcpy(str, "No active channels.");
    goto OUT_ERROR;
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])  // Download data only when channel is switched on
    {
      continue;
    }

    usleep(20000);

    sprintf(str, ":WAV:SOUR CHAN%i", chn + 1);

    tmc_write(str);

    usleep(20000);

    tmc_write(":WAV:FORM BYTE");

    usleep(20000);

    tmc_write(":WAV:MODE NORM");

    usleep(20000);

    tmc_write(":WAV:YINC?");

    usleep(20000);

    tmc_read();

    yinc[chn] = atof(device->buf);

    if(yinc[chn] < 1e-6)
    {
      sprintf(str, "Error, parameter \"YINC\" out of range.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }

    usleep(20000);

    tmc_write(":WAV:YREF?");

    usleep(20000);

    tmc_read();

    yref[chn] = atoi(device->buf);

    if((yref[chn] < 1) || (yref[chn] > 255))
    {
      sprintf(str, "Error, parameter \"YREF\" out of range.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }

    usleep(20000);

    tmc_write(":WAV:YOR?");

    usleep(20000);

    tmc_read();

    yor[chn] = atoi(device->buf);

    if((yor[chn] < -255) || (yor[chn] > 255))
    {
      sprintf(str, "Error, parameter \"YOR\" out of range.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }

    usleep(20000);

    tmc_write(":WAV:DATA?");

    QApplication::setOverrideCursor(Qt::WaitCursor);

    qApp->processEvents();

    n = tmc_read();

    QApplication::restoreOverrideCursor();

    if(n < 0)
    {
      strcpy(str, "Can not read from device.");
      goto OUT_ERROR;
    }

    if(n > WAVFRM_MAX_BUFSZ)
    {
      strcpy(str, "Datablock too big for buffer.");
      goto OUT_ERROR;
    }

    if(n < 16)
    {
      strcpy(str, "Not enough data in buffer.");
      goto OUT_ERROR;
    }

    for(i=0; i<n; i++)
    {
      wavbuf[chn][i] = ((int)(((unsigned char *)device->buf)[i]) - yref[chn] - yor[chn]) << 5;
    }
  }

  opath[0] = 0;
  if(recent_savedir[0]!=0)
  {
    strcpy(opath, recent_savedir);
    strcat(opath, "/");
  }
  strcat(opath, "waveform.edf");

  strcpy(opath, QFileDialog::getSaveFileName(this, "Save file", opath, "EDF files (*.edf *.EDF)").toLocal8Bit().data());

  if(!strcmp(opath, ""))
  {
    goto OUT_NORMAL;
  }

  get_directory_from_path(recent_savedir, opath, MAX_PATHLEN);

  hdl = edfopen_file_writeonly(opath, EDFLIB_FILETYPE_EDFPLUS, chns);
  if(hdl < 0)
  {
    strcpy(str, "Can not create EDF file.");
    goto OUT_ERROR;
  }

  if(edf_set_datarecord_duration(hdl, rec_len / 100LL))
  {
    strcpy(str, "Can not set datarecord duration of EDF file.");
    goto OUT_ERROR;
  }

  j = 0;

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])
    {
      continue;
    }

    edf_set_samplefrequency(hdl, j, n);
    edf_set_digital_maximum(hdl, j, 32767);
    edf_set_digital_minimum(hdl, j, -32768);
    if(devparms.chanscale[chn] > 2)
    {
      edf_set_physical_maximum(hdl, j, yinc[chn] * 32767.0 / 32.0);
      edf_set_physical_minimum(hdl, j, yinc[chn] * -32768.0 / 32.0);
      edf_set_physical_dimension(hdl, j, "V");
    }
    else
    {
      edf_set_physical_maximum(hdl, j, 1000.0 * yinc[chn] * 32767.0 / 32.0);
      edf_set_physical_minimum(hdl, j, 1000.0 * yinc[chn] * -32768.0 / 32.0);
      edf_set_physical_dimension(hdl, j, "mV");
    }
    sprintf(str, "CHAN%i", chn + 1);
    edf_set_label(hdl, j, str);

    j++;
  }

  edf_set_equipment(hdl, devparms.modelname);

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])
    {
      continue;
    }

    if(edfwrite_digital_short_samples(hdl, wavbuf[chn]))
    {
      strcpy(str, "A write error occurred.");
      goto OUT_ERROR;
    }
  }

OUT_NORMAL:

  if(hdl >= 0)
  {
    edfclose_file(hdl);
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    free(wavbuf[chn]);
  }

  scrn_timer->start(devparms.screentimerival);

  return;

OUT_ERROR:

  QMessageBox msgBox;
  msgBox.setIcon(QMessageBox::Critical);
  msgBox.setText(str);
  msgBox.exec();

  if(hdl >= 0)
  {
    edfclose_file(hdl);
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    free(wavbuf[chn]);
  }

  scrn_timer->start(devparms.screentimerival);
}
Esempio n. 5
0
void UI_Mainwindow::save_memory_waveform()
{
  int i, j, k,
      n=0,
      chn,
      chns=0,
      hdl=-1,
      bytes_rcvd=0,
      mempnts,
      yref[MAX_CHNS],
      yor[MAX_CHNS],
      smps_per_record,
      datrecs=1,
      empty_buf;

  char str[128],
       opath[MAX_PATHLEN];

  short *wavbuf[4];

  long long rec_len=0LL;

  double yinc[MAX_CHNS];

  if(device == NULL)
  {
    return;
  }

  scrn_timer->stop();

  scrn_thread->wait();

  wavbuf[0] = NULL;
  wavbuf[1] = NULL;
  wavbuf[2] = NULL;
  wavbuf[3] = NULL;

  mempnts = devparms.acquirememdepth;

  smps_per_record = mempnts;

  QProgressDialog progress("Downloading data...", "Abort", 0, mempnts, this);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(100);

  statusLabel->setText("Downloading data...");

  for(i=0; i<MAX_CHNS; i++)
  {
    if(!devparms.chandisplay[i])
    {
      continue;
    }

    chns++;
  }

  if(!chns)
  {
    strcpy(str, "No active channels.");
    goto OUT_ERROR;
  }

  while(smps_per_record >= (5000000 / chns))
  {
    smps_per_record /= 2;

    datrecs *= 2;
  }

  if(mempnts < 1)
  {
    strcpy(str, "Can not save waveform when memory depth is set to \"Auto\".");
    goto OUT_ERROR;
  }

  rec_len = (EDFLIB_TIME_DIMENSION * (long long)mempnts) / devparms.samplerate;

  if(rec_len < 100)
  {
    strcpy(str, "Can not save waveforms shorter than 10 uSec.\n"
                "Set the horizontal timebase to 1 uSec or higher.");
    goto OUT_ERROR;
  }

  for(i=0; i<MAX_CHNS; i++)
  {
    if(!devparms.chandisplay[i])  // Download data only when channel is switched on
    {
      continue;
    }

    wavbuf[i] = (short *)malloc(mempnts * sizeof(short));
    if(wavbuf[i] == NULL)
    {
      sprintf(str, "Malloc error.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }
  }

  tmc_write(":STOP");

  usleep(20000);

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])  // Download data only when channel is switched on
    {
      continue;
    }

    sprintf(str, ":WAV:SOUR CHAN%i", chn + 1);

    tmc_write(str);

    tmc_write(":WAV:FORM BYTE");

    usleep(20000);

    tmc_write(":WAV:MODE RAW");

    usleep(20000);

    tmc_write(":WAV:YINC?");

    usleep(20000);

    tmc_read();

    yinc[chn] = atof(device->buf);

    if(yinc[chn] < 1e-6)
    {
      sprintf(str, "Error, parameter \"YINC\" out of range.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }

    usleep(20000);

    tmc_write(":WAV:YREF?");

    usleep(20000);

    tmc_read();

    yref[chn] = atoi(device->buf);

    if((yref[chn] < 1) || (yref[chn] > 255))
    {
      sprintf(str, "Error, parameter \"YREF\" out of range.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }

    usleep(20000);

    tmc_write(":WAV:YOR?");

    usleep(20000);

    tmc_read();

    yor[chn] = atoi(device->buf);

    if((yor[chn] < -255) || (yor[chn] > 255))
    {
      sprintf(str, "Error, parameter \"YOR\" out of range.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }

    empty_buf = 0;

    for(bytes_rcvd=0; bytes_rcvd<mempnts ;)
    {
      progress.setValue(bytes_rcvd);

      qApp->processEvents();

      if(progress.wasCanceled())
      {
        strcpy(str, "Canceled");
        goto OUT_ERROR;
      }

      sprintf(str, ":WAV:STAR %i",  bytes_rcvd + 1);

      usleep(20000);

      tmc_write(str);

      if((bytes_rcvd + SAV_MEM_BSZ) > mempnts)
      {
        sprintf(str, ":WAV:STOP %i", mempnts);
      }
      else
      {
        sprintf(str, ":WAV:STOP %i", bytes_rcvd + SAV_MEM_BSZ);
      }

      usleep(20000);

      tmc_write(str);

      usleep(20000);

      tmc_write(":WAV:DATA?");

      n = tmc_read();

      if(n < 0)
      {
        sprintf(str, "Can not read from device.  line %i file %s", __LINE__, __FILE__);
        goto OUT_ERROR;
      }

      printf("received %i bytes, total %i bytes\n", n, n + bytes_rcvd);

      if(n > SAV_MEM_BSZ)
      {
        sprintf(str, "Datablock too big for buffer.  line %i file %s", __LINE__, __FILE__);
        goto OUT_ERROR;
      }

      if(n < 1)
      {
        if(empty_buf++ > 100)
        {
          break;
        }
      }
      else
      {
        empty_buf = 0;
      }

      for(k=0; k<n; k++)
      {
        if((bytes_rcvd + k) >= mempnts)
        {
          break;
        }

        wavbuf[chn][bytes_rcvd + k] = ((int)(((unsigned char *)device->buf)[k]) - yref[chn] - yor[chn]) << 5;
      }

      bytes_rcvd += n;

      if(bytes_rcvd >= mempnts)
      {
        break;
      }
    }

    if(bytes_rcvd < mempnts)
    {
      sprintf(str, "Download error.  line %i file %s", __LINE__, __FILE__);
      goto OUT_ERROR;
    }
  }

  progress.reset();

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])
    {
      continue;
    }

    sprintf(str, ":WAV:SOUR CHAN%i", chn + 1);

    usleep(20000);

    tmc_write(str);

    usleep(20000);

    tmc_write(":WAV:MODE NORM");

    usleep(20000);

    tmc_write(":WAV:STAR 1");

    if(devparms.modelserie == 1)
    {
      usleep(20000);

      tmc_write(":WAV:STOP 1200");
    }
    else
    {
      usleep(20000);

      tmc_write(":WAV:STOP 1400");

      usleep(20000);

      tmc_write(":WAV:POIN 1400");
    }
  }

  if(bytes_rcvd < mempnts)
  {
    sprintf(str, "Download error.  line %i file %s", __LINE__, __FILE__);
    goto OUT_ERROR;
  }
  else
  {
    statusLabel->setText("Downloading finished");
  }

  opath[0] = 0;
  if(recent_savedir[0]!=0)
  {
    strcpy(opath, recent_savedir);
    strcat(opath, "/");
  }
  strcat(opath, "waveform.edf");

  strcpy(opath, QFileDialog::getSaveFileName(this, "Save file", opath, "EDF files (*.edf *.EDF)").toLocal8Bit().data());

  if(!strcmp(opath, ""))
  {
    goto OUT_NORMAL;
  }

  get_directory_from_path(recent_savedir, opath, MAX_PATHLEN);

  hdl = edfopen_file_writeonly(opath, EDFLIB_FILETYPE_EDFPLUS, chns);
  if(hdl < 0)
  {
    strcpy(str, "Can not create EDF file.");
    goto OUT_ERROR;
  }

  if(edf_set_datarecord_duration(hdl, (rec_len / 100LL) / datrecs))
  {
    strcpy(str, "Can not set datarecord duration of EDF file.");
    goto OUT_ERROR;
  }

  j = 0;

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])
    {
      continue;
    }

    edf_set_samplefrequency(hdl, j, smps_per_record);
    edf_set_digital_maximum(hdl, j, 32767);
    edf_set_digital_minimum(hdl, j, -32768);
    if(devparms.chanscale[chn] > 2)
    {
      edf_set_physical_maximum(hdl, j, yinc[chn] * 32767.0 / 32.0);
      edf_set_physical_minimum(hdl, j, yinc[chn] * -32768.0 / 32.0);
      edf_set_physical_dimension(hdl, j, "V");
    }
    else
    {
      edf_set_physical_maximum(hdl, j, 1000.0 * yinc[chn] * 32767.0 / 32.0);
      edf_set_physical_minimum(hdl, j, 1000.0 * yinc[chn] * -32768.0 / 32.0);
      edf_set_physical_dimension(hdl, j, "mV");
    }
    sprintf(str, "CHAN%i", chn + 1);
    edf_set_label(hdl, j, str);

    j++;
  }

  edf_set_equipment(hdl, devparms.modelname);

  for(i=0; i<datrecs; i++)
  {
    for(chn=0; chn<MAX_CHNS; chn++)
    {
      if(!devparms.chandisplay[chn])
      {
        continue;
      }

      if(edfwrite_digital_short_samples(hdl, wavbuf[chn] + (i * smps_per_record)))
      {
        strcpy(str, "A write error occurred.");
        goto OUT_ERROR;
      }
    }
  }

OUT_NORMAL:

  if(hdl >= 0)
  {
    edfclose_file(hdl);
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    free(wavbuf[chn]);
  }

  scrn_timer->start(devparms.screentimerival);

  return;

OUT_ERROR:

  progress.reset();

  statusLabel->setText("Downloading aborted");

  if(hdl >= 0)
  {
    edfclose_file(hdl);
  }

  if(progress.wasCanceled() == false)
  {
    QMessageBox msgBox;
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText(str);
    msgBox.exec();
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    if(!devparms.chandisplay[chn])
    {
      continue;
    }

    sprintf(str, ":WAV:SOUR CHAN%i", chn + 1);

    tmc_write(str);

    tmc_write(":WAV:MODE NORM");

    tmc_write(":WAV:STAR 1");

    if(devparms.modelserie == 1)
    {
      tmc_write(":WAV:STOP 1200");
    }
    else
    {
      tmc_write(":WAV:STOP 1400");

      tmc_write(":WAV:POIN 1400");
    }
  }

  for(chn=0; chn<MAX_CHNS; chn++)
  {
    free(wavbuf[chn]);
  }

  scrn_timer->start(devparms.screentimerival);
}
Esempio n. 6
0
void UI_WAV2EDFwindow::SelectFileButton()
{
  FILE *inputfile=NULL;

  int i, j,
      edfsignals,
      sf,
      resolution,
      edf_hdl,
      readbufsize,
      *writebuf,
      bytes_per_sample,
      sf_divider;

unsigned int fmt_chunk_offset,
             data_chunk_offset,
             tmp;

  char path[MAX_PATH_LENGTH],
       outputfilename[MAX_PATH_LENGTH],
       scratchpad[512],
       *readbuf;

  long long blocks,
            leftover,
            progress_steps,
            k;

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


  enable_widgets(false);

  if(!(strlen(PatientnameLineEdit->text().toLatin1().data())))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a subject name.");
    messagewindow.exec();
    enable_widgets(true);
    return;
  }

  if(!(strlen(RecordingLineEdit->text().toLatin1().data())))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Invalid input", "Please enter a recording description.");
    messagewindow.exec();
    enable_widgets(true);
    return;
  }

  strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "Text files (*.wav *.WAV)").toLocal8Bit().data());

  if(!strcmp(path, ""))
  {
    enable_widgets(true);
    return;
  }

  get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH);

  inputfile = fopeno(path, "rb");
  if(inputfile==NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open file for reading.");
    messagewindow.exec();
    enable_widgets(true);
    return;
  }

/***************** check if the wavefile is valid ******************************/

  rewind(inputfile);

  if(fread(scratchpad, 256, 1, inputfile)!=1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading from inputfile.");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  if((strncmp(scratchpad, "RIFF", 4)) || (strncmp(scratchpad + 8, "WAVE", 4)))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "File is not a Wave file.");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  fmt_chunk_offset = 12;

  while(1)
  {
    fseeko(inputfile, (long long)fmt_chunk_offset, SEEK_SET);

    if(fread(scratchpad, 256, 1, inputfile)!=1)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not find fmt chunk.");
      messagewindow.exec();
      fclose(inputfile);
      enable_widgets(true);
      return;
    }

    if(strncmp(scratchpad, "fmt ", 4) == 0)
    {
      break;
    }

    tmp = *((unsigned int *)(scratchpad + 4));
    if(tmp < 2)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not find fmt chunk.");
      messagewindow.exec();
      fclose(inputfile);
      enable_widgets(true);
      return;
    }

    if(tmp & 1)
    {
      tmp++;
    }

    fmt_chunk_offset += (tmp + 8);
  }

  if(*((signed short *)(scratchpad + 8)) != 1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "File contains compressed data.\nCan not convert compressed data.");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  edfsignals = *((unsigned short *)(scratchpad + 10));

  if(edfsignals < 1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Channels < 1");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  if(edfsignals > MAXSIGNALS)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Channels > MAXSIGNALS");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  sf = *((unsigned int *)(scratchpad + 12));

  if(sf < 1)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Samplefrequency < 1");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  if(sf > 500000)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Samplefrequency > 500000");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  resolution = *((unsigned short *)(scratchpad + 22));

  if(resolution < 8)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Resolution < 8 bit");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  if(resolution > 24)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Resolution > 24");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  if((resolution != 8) && (resolution != 16)  && (resolution != 24))
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Resolution (bitdepth) must be 8, 16 or 24 bit.");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  bytes_per_sample = 2;

  if(resolution > 16)
  {
    bytes_per_sample = 3;
  }

  if(resolution < 9)
  {
    bytes_per_sample = 1;
  }

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

  data_chunk_offset = 12;

  while(1)
  {
    fseeko(inputfile, (long long)data_chunk_offset, SEEK_SET);

    if(fread(scratchpad, 256, 1, inputfile)!=1)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not find data chunk.");
      messagewindow.exec();
      fclose(inputfile);
      enable_widgets(true);
      return;
    }

    if(strncmp(scratchpad, "data", 4) == 0)
    {
      break;
    }

    tmp = *((unsigned int *)(scratchpad + 4));
    if(tmp < 2)
    {
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not find data chunk.");
      messagewindow.exec();
      fclose(inputfile);
      enable_widgets(true);
      return;
    }

    if(tmp & 1)
    {
      tmp++;
    }

    data_chunk_offset += (tmp + 8);
  }

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

  sf_divider = 1;

  if((sf % 10) == 0)
  {
    sf_divider = 10;

    sf /= 10;
  }

  blocks = (long long)(*((int *)(scratchpad + 4)));

  blocks /= (sf * edfsignals * bytes_per_sample);

  fseeko(inputfile, 0LL, SEEK_END);

  leftover = ftello(inputfile) - (long long)data_chunk_offset - 8LL;

  leftover /= (sf * edfsignals * bytes_per_sample);

  if(blocks > leftover)
  {
    blocks = leftover;
  }

  if(blocks < 1LL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Not enough data in file.");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  readbufsize = bytes_per_sample * sf * edfsignals;

  readbuf = (char *)malloc(readbufsize);
  if(readbuf == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred. (readbuf).");
    messagewindow.exec();
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

  writebuf = (int *)malloc(sf * edfsignals * sizeof(int));
  if(writebuf == NULL)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred. (writebuf).");
    messagewindow.exec();
    free(readbuf);
    fclose(inputfile);
    enable_widgets(true);
    return;
  }

//  printf("resolution is %i    edfsignals is %i    sf is %i    blocks is %lli\n", resolution, edfsignals, sf, blocks);

/***************** create a new EDF file *****************************************/

  get_filename_from_path(outputfilename, path, MAX_PATH_LENGTH);
  remove_extension_from_filename(outputfilename);
  if(resolution > 16)
  {
    strcat(outputfilename, ".bdf");
  }
  else
  {
    strcat(outputfilename, ".edf");
  }

  path[0] = 0;
  if(recent_savedir[0]!=0)
  {
    strcpy(path, recent_savedir);
    strcat(path, "/");
  }
  strcat(path, outputfilename);

  if(resolution > 16)
  {
    strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "BDF files (*.bdf *.BDF)").toLocal8Bit().data());
  }
  else
  {
    strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "EDF files (*.edf *.EDF)").toLocal8Bit().data());
  }

  if(!strcmp(path, ""))
  {
    enable_widgets(true);
    fclose(inputfile);
    return;
  }

  get_directory_from_path(recent_savedir, path, MAX_PATH_LENGTH);

  if(resolution > 16)
  {
    edf_hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_BDFPLUS, edfsignals);
  }
  else
  {
    edf_hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, edfsignals);
  }

  if(edf_hdl < 0)
  {
    QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open output file for writing.");
    messagewindow.exec();
    fclose(inputfile);
    free(readbuf);
    free(writebuf);
    enable_widgets(true);
    return;
  }

  for(i=0; i<edfsignals; i++)
  {
    edf_set_samplefrequency(edf_hdl, i, sf);
  }

  if(sf_divider != 1)
  {
    edf_set_datarecord_duration(edf_hdl, 100000 / sf_divider);
  }

  for(i=0; i<edfsignals; i++)
  {
    if(resolution > 16)
    {
      edf_set_digital_maximum(edf_hdl, i, 8388607);
    }
    else
    {
      if(resolution < 9)
      {
        edf_set_digital_maximum(edf_hdl, i, 127);
      }
      else
      {
        edf_set_digital_maximum(edf_hdl, i, 32767);
      }
    }
  }

  for(i=0; i<edfsignals; i++)
  {
    if(resolution > 16)
    {
      edf_set_digital_minimum(edf_hdl, i, -8388608);
    }
    else
    {
      if(resolution < 9)
      {
        edf_set_digital_minimum(edf_hdl, i, -128);
      }
      else
      {
        edf_set_digital_minimum(edf_hdl, i, -32768);
      }
    }
  }

  for(i=0; i<edfsignals; i++)
  {
    edf_set_physical_maximum(edf_hdl, i, PhysMaxSpinBox->value());
  }

  for(i=0; i<edfsignals; i++)
  {
    edf_set_physical_minimum(edf_hdl, i, PhysMaxSpinBox->value() * -1.0);
  }

  for(i=0; i<edfsignals; i++)
  {
    edf_set_physical_dimension(edf_hdl, i, PhysDimLineEdit->text().toLatin1().data());
  }

  for(i=0; i<edfsignals; i++)
  {
    sprintf(scratchpad, "channel %i", i + 1);

    edf_set_label(edf_hdl, i, scratchpad);
  }

  edf_set_patientname(edf_hdl, PatientnameLineEdit->text().toLatin1().data());

  edf_set_recording_additional(edf_hdl, RecordingLineEdit->text().toLatin1().data());

  edf_set_startdatetime(edf_hdl, StartDatetimeedit->date().year(), StartDatetimeedit->date().month(), StartDatetimeedit->date().day(),
                        StartDatetimeedit->time().hour(), StartDatetimeedit->time().minute(), StartDatetimeedit->time().second());

  edfwrite_annotation_latin1(edf_hdl, 0LL, -1, "Recording starts");

/***************** start conversion **************************************/

  fseeko(inputfile, (long long)data_chunk_offset + 8LL, SEEK_SET);

  QProgressDialog progress("Converting a Wave file ...", "Abort", 0, (int)blocks, myobjectDialog);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(200);

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

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

      qApp->processEvents();

      if(progress.wasCanceled() == true)
      {
        edfclose_file(edf_hdl);
        fclose(inputfile);
        free(readbuf);
        free(writebuf);
        enable_widgets(true);
        return;
      }
    }

    if(fread(readbuf, readbufsize, 1, inputfile)!=1)
    {
      progress.reset();
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "A read error occurred during conversion.");
      messagewindow.exec();
      edfclose_file(edf_hdl);
      fclose(inputfile);
      free(readbuf);
      free(writebuf);
      enable_widgets(true);
      return;
    }

    if(bytes_per_sample == 1)
    {
      for(i=0; i<sf; i++)
      {
        for(j=0; j<edfsignals; j++)
        {
          writebuf[i + (j * sf)] = (signed char)(*(readbuf + (i * edfsignals) + j) + 128);
        }
      }
    }

    if(bytes_per_sample == 2)
    {
      for(i=0; i<sf; i++)
      {
        for(j=0; j<edfsignals; j++)
        {
          writebuf[i + (j * sf)] = *(((signed short *)readbuf) + (i * edfsignals) + j);
        }
      }
    }

    if(bytes_per_sample == 3)
    {
      for(i=0; i<sf; i++)
      {
        for(j=0; j<edfsignals; j++)
        {
          var.two[0] = *((unsigned short *)(readbuf + (i * edfsignals) + (j * 3)));

          var.four[2] = *((unsigned char *)(readbuf + (i * edfsignals * 3) + (j * 3) + 2));

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

          writebuf[i + (j * sf)] = var.one_signed;
        }
      }
    }

    if(edf_blockwrite_digital_samples(edf_hdl, writebuf))
    {
      progress.reset();
      QMessageBox messagewindow(QMessageBox::Critical, "Error", "A write error occurred during conversion.");
      messagewindow.exec();
      edfclose_file(edf_hdl);
      fclose(inputfile);
      free(readbuf);
      free(writebuf);
      enable_widgets(true);
      return;
    }
  }

  progress.reset();

  edfwrite_annotation_latin1(edf_hdl, (blocks * 10000LL) / sf_divider, -1, "Recording ends");

  edfclose_file(edf_hdl);

  fclose(inputfile);

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

  free(readbuf);
  free(writebuf);

  enable_widgets(true);
}