Logo Search packages:      
Sourcecode: edfbrowser version File versions  Download package

nk2edf.cpp

/*
***************************************************************************
*
* Author: Teunis van Beelen
*
* Copyright (C) 2007, 2008, 2009 Teunis van Beelen
*
* teuniz@gmail.com
*
***************************************************************************
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
***************************************************************************
*
* This version of GPL is at http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
*
***************************************************************************
*/



#include "nk2edf.h"






UI_NK2EDFwindow::UI_NK2EDFwindow()
{
  char txt_string[2048];

  myobjectDialog = new QDialog;

  myobjectDialog->setMinimumSize(QSize(600, 480));
  myobjectDialog->setMaximumSize(QSize(600, 480));
  myobjectDialog->setWindowTitle("Nihon Kohden to EDF(+) converter");
  myobjectDialog->setModal(TRUE);
  myobjectDialog->setAttribute(Qt::WA_DeleteOnClose, TRUE);

  pushButton1 = new QPushButton(myobjectDialog);
  pushButton1->setGeometry(QRect(20, 430, 100, 26));
  pushButton1->setText("Select File");

  pushButton2 = new QPushButton(myobjectDialog);
  pushButton2->setGeometry(QRect(480, 430, 100, 26));
  pushButton2->setText("Close");

  checkBox1 = new QCheckBox(myobjectDialog);
  checkBox1->setGeometry(QRect(200, 430, 120, 26));
  checkBox1->setText("Create EDF+");
  checkBox1->setCheckState(Qt::Checked);

  textEdit1 = new QTextEdit(myobjectDialog);
  textEdit1->setGeometry(QRect(20, 20, 560, 380));
  textEdit1->setFrameStyle(QFrame::Panel | QFrame::Sunken);
  textEdit1->setReadOnly(TRUE);
  textEdit1->setLineWrapMode(QTextEdit::NoWrap);
  sprintf(txt_string, "Nihon Kohden to EDF(+) converter.\n");
  textEdit1->append(txt_string);

  fchooser = new QFileDialog(myobjectDialog);
  fchooser->setConfirmOverwrite(1);
  fchooser->setFileMode(QFileDialog::ExistingFile);
  fchooser->setAcceptMode(QFileDialog::AcceptOpen);
  fchooser->setWindowTitle("Select inputfile");
  fchooser->setLabelText(QFileDialog::FileName, "input file");
#ifdef Q_WS_X11
  fchooser->setDirectory(getenv("HOME"));
#endif
#ifdef Q_WS_MAC
  fchooser->setDirectory(getenv("HOME"));
#endif
  fchooser->setDefaultSuffix("eeg");
  fchooser->setFilter("EEG files (*.eeg *.EEG)");

  QObject::connect(pushButton1, SIGNAL(clicked()), this, SLOT(SelectFileButton()));
  QObject::connect(pushButton2, SIGNAL(clicked()), myobjectDialog, SLOT(close()));

  myobjectDialog->exec();
}



void UI_NK2EDFwindow::SelectFileButton()
{
  FILE *inputfile=NULL,
       *outputfile=NULL,
       *logfile=NULL,
       *pntfile=NULL;

  const char *fileName;

  int i, j, k,
      pathlen,
      fname_len,
      error,
      ctl_block_cnt,
      datablock_cnt,
      total_blocks,
      edfplus,
      n_logs=0,
      total_logs=0,
      n_logblocks=0,
      ctlblock_address,
      wfmblock_address,
      logblock_address;

  char txt_string[2048],
       path[512],
       logfilepath[512],
       pntfilepath[512],
       *log_buf=NULL,
       scratchpad[256];

  QStringList  input_fileNames;

  QString input_fileName;


  pushButton1->setEnabled(FALSE);

  edfplus = checkBox1->checkState();

  total_elapsed_time = 0;

  if(!(fchooser->exec() == QDialog::Accepted))
  {
    pushButton1->setEnabled(TRUE);
    return;
  }
  input_fileNames = fchooser->selectedFiles();
  input_fileName = input_fileNames.at(0);
  strcpy(path, input_fileName.toLatin1().data());

  pathlen = strlen(path);

  if(pathlen<5)
  {
    textEdit1->append("error, filename must contain at least five characters.");
    pushButton1->setEnabled(TRUE);
    return;
  }

  fname_len = 0;
  for(i=pathlen; i>0; i--)
  {
       if((path[i-1]=='/')||(path[i-1]=='\\'))  break;
       fname_len++;
  }
  fileName = path + pathlen - fname_len;

  for(i=0; fileName[i]!=0; i++) ;
  if(i==0)
  {
    textEdit1->append("error, filename must contain at least five characters.");
    pushButton1->setEnabled(TRUE);
    return;
  }

  i -= 4;
  if((strcmp((const char *)fileName + i, ".eeg"))&&(strcmp((const char *)fileName + i, ".EEG")))
  {
    textEdit1->append("error, filename extension must have the form \".eeg\" or \".EEG\"");
    pushButton1->setEnabled(TRUE);
    return;
  }

  inputfile = fopen64(path, "rb");
  if(inputfile==NULL)
  {
    snprintf(txt_string, 2048, "can not open file %s for reading.\n", path);
    textEdit1->append(txt_string);
    pushButton1->setEnabled(TRUE);
    return;
  }

/***************** check if the EEG file is valid ******************************/

  rewind(inputfile);
  if(fread(scratchpad, 16, 1, inputfile)!=1)
  {
    textEdit1->append("error reading .eeg file.\n");
    fclose(inputfile);
    pushButton1->setEnabled(TRUE);
    return;
  }
  scratchpad[16] = 0;
  if(check_device(scratchpad))
  {
    snprintf(txt_string, 2048, "error, deviceblock has unknown signature: \"%s\"\n", scratchpad);
    textEdit1->append(txt_string);
    fclose(inputfile);
    pushButton1->setEnabled(TRUE);
    return;
  }
  fseeko64(inputfile, 0x0081, SEEK_SET);
  if(fread(scratchpad, 16, 1, inputfile)!=1)
  {
    textEdit1->append("error reading .eeg file.\n");
    fclose(inputfile);
    pushButton1->setEnabled(TRUE);
    return;
  }
  scratchpad[16] = 0;
  if(check_device(scratchpad))
  {
    snprintf(txt_string, 2048, "error, controlblock has unknown signature: \"%s\"\n", scratchpad);
    textEdit1->append(txt_string);
    fclose(inputfile);
    pushButton1->setEnabled(TRUE);
    return;
  }
  fseeko64(inputfile, 0x17fe, SEEK_SET);
  if(fgetc(inputfile)!=0x01)
  {
    snprintf(txt_string, 2048, "error, waveformdatablock has wrong signature.\n");
    textEdit1->append(txt_string);
    fclose(inputfile);
    pushButton1->setEnabled(TRUE);
    return;
  }

/************************* read logs **********************************************/

  if(edfplus)
  {
    strncpy(logfilepath, path, 512);
    pathlen = strlen(logfilepath);
    strcpy(logfilepath + pathlen - 3, "log");
    logfile = fopen64(logfilepath, "rb");
    if(logfile==NULL)
    {
      snprintf(txt_string, 2048, "Can not open file %s for reading,\n"
                          "if there is no .log file you can try to create an EDF file instead of EDF+.\n",
                          logfilepath);
      textEdit1->append(txt_string);
      fclose(inputfile);
      pushButton1->setEnabled(TRUE);
      return;
    }

    rewind(logfile);
    if(fread(scratchpad, 16, 1, logfile)!=1)
    {
      textEdit1->append("error reading .log file.\n");
      fclose(logfile);
      fclose(inputfile);
      pushButton1->setEnabled(TRUE);
      return;
    }
    scratchpad[16] = 0;
    if(check_device(scratchpad))
    {
      snprintf(txt_string, 2048, "error, .log file has unknown signature: \"%s\"\n", scratchpad);
      textEdit1->append(txt_string);
      fclose(logfile);
      fclose(inputfile);
      pushButton1->setEnabled(TRUE);
      return;
    }

    fseeko64(logfile, 0x0091, SEEK_SET);
    n_logblocks = fgetc(logfile);
    log_buf = (char *)calloc(1, n_logblocks * 11520);
    if(log_buf==NULL)
    {
      textEdit1->append("malloc error\n");
      fclose(logfile);
      fclose(inputfile);
      pushButton1->setEnabled(TRUE);
      return;
    }

    total_logs = 0;

    for(i=0; i<n_logblocks; i++)
    {
      fseeko64(logfile, 0x0092 + (i * 20) , SEEK_SET);
      if(fread((char *)(&logblock_address), 4, 1, logfile)!=1)
      {
        textEdit1->append("error reading .log file.\n");
        fclose(inputfile);
        fclose(logfile);
        free(log_buf);
        pushButton1->setEnabled(TRUE);
        return;
      }
      fseeko64(logfile, logblock_address + 0x0012, SEEK_SET);
      n_logs = fgetc(logfile);
      fseeko64(logfile, logblock_address + 0x0014, SEEK_SET);
      if(fread(log_buf + (total_logs * 45), n_logs * 45, 1, logfile)!=1)
      {
        textEdit1->append("error reading .log file.\n");
        fclose(inputfile);
        fclose(logfile);
        free(log_buf);
        pushButton1->setEnabled(TRUE);
        return;
      }
      total_logs += n_logs;
    }

    for(i=0; i<total_logs; i++)
    {
      for(j=0; j<20; j++)
      {
        if(((unsigned char *)log_buf)[(i * 45) + j]<32)  log_buf[(i * 45) + j] = ' ';
      }

      latin12utf8(log_buf + (i * 45), 20);
    }

/************************* check pntfile **********************************************/

    strncpy(pntfilepath, path, 512);
    pathlen = strlen(pntfilepath);
    strcpy(pntfilepath + pathlen - 3, "pnt");
    pntfile = fopen64(pntfilepath, "rb");
    if(pntfile==NULL)
    {
      snprintf(txt_string, 2048, "Can not open file %s for reading,\n"
                          "if there is no .pnt file you can try to create an EDF file instead of EDF+.\n",
                          pntfilepath);
      textEdit1->append(txt_string);
      fclose(logfile);
      fclose(inputfile);
      free(log_buf);
      pushButton1->setEnabled(TRUE);
      return;
    }

    rewind(pntfile);
    if(fread(scratchpad, 16, 1, pntfile)!=1)
    {
      textEdit1->append("error reading .pnt file.\n");
      fclose(pntfile);
      fclose(logfile);
      fclose(inputfile);
      free(log_buf);
      pushButton1->setEnabled(TRUE);
      return;
    }
    scratchpad[16] = 0;
    if(check_device(scratchpad))
    {
      snprintf(txt_string, 2048, "error, .pnt file has unknown signature: \"%s\"\n", scratchpad);
      textEdit1->append(txt_string);
      fclose(pntfile);
      fclose(logfile);
      fclose(inputfile);
      free(log_buf);
      pushButton1->setEnabled(TRUE);
      return;
    }
  }

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

  total_blocks = 0;

  fseeko64(inputfile, 0x0091, SEEK_SET);
  ctl_block_cnt = fgetc(inputfile);
  if(ctl_block_cnt==EOF)
  {
    textEdit1->append("error reading inputfile.\n");
    pushButton1->setEnabled(TRUE);
    fclose(inputfile);
    if(edfplus)
    {
      fclose(logfile);
      free(log_buf);
      fclose(pntfile);
    }
    return;
  }

  QApplication::setOverrideCursor(Qt::WaitCursor);

  for(i=0; i<ctl_block_cnt; i++)
  {
    fseeko64(inputfile, 0x0092 + (i * 20), SEEK_SET);
    if(fread((char *)(&ctlblock_address), 4, 1, inputfile)!=1)
    {
      textEdit1->append("error reading inputfile.\n");
      pushButton1->setEnabled(TRUE);
      fclose(inputfile);
      if(edfplus)
      {
        fclose(logfile);
        free(log_buf);
        fclose(pntfile);
      }
      return;
    }
    fseeko64(inputfile, ctlblock_address + 17, SEEK_SET);
    datablock_cnt = fgetc(inputfile);
    if(datablock_cnt==EOF)
    {
      textEdit1->append("error reading inputfile.\n");
      pushButton1->setEnabled(TRUE);
      fclose(inputfile);
      if(edfplus)
      {
        fclose(logfile);
        free(log_buf);
        fclose(pntfile);
      }
      QApplication::restoreOverrideCursor();
      return;
    }

    for(j=0; j<datablock_cnt; j++)
    {
      fseeko64(inputfile, ctlblock_address + (j * 20) + 18, SEEK_SET);
      if(fread((char *)(&wfmblock_address), 4, 1, inputfile)!=1)
      {
        textEdit1->append("error reading inputfile.\n");
        pushButton1->setEnabled(TRUE);
        fclose(inputfile);
        if(edfplus)
        {
          fclose(logfile);
          free(log_buf);
          fclose(pntfile);
        }
        QApplication::restoreOverrideCursor();
        return;
      }

   /********************************************************************/

      if(edfplus)  sprintf(path + pathlen - 4, "_%u-%u+.edf", i + 1, j + 1);
      else  sprintf(path + pathlen - 4, "_%u-%u.edf", i + 1, j + 1);

      outputfile = fopen64(path, "wb");
      if(outputfile==NULL)
      {
        snprintf(txt_string, 2048, "can not open file %s for writing.\n", path);
        textEdit1->append(txt_string);
        pushButton1->setEnabled(TRUE);
        fclose(inputfile);
        if(edfplus)
        {
          fclose(logfile);
          free(log_buf);
          fclose(pntfile);
        }
        QApplication::restoreOverrideCursor();
        return;
      }

      textEdit1->append("converting a waveform datablock...");

      for(k=0; k<10; k++)  qApp->processEvents();

      error = convert_nk2edf(inputfile, outputfile, pntfile, wfmblock_address, edfplus, total_logs, log_buf);
      if(error==0)
      {
        snprintf(txt_string, 2048, "to %s", path);
        textEdit1->append(txt_string);
      }
      if(error==1)  textEdit1->append("malloc error.\n");
      if(error==2)  textEdit1->append("read error during conversion.\n");
      if(error==3)  textEdit1->append("write error during conversion.\n");

      if(fclose(outputfile))
      {
        textEdit1->append("error closing outputfile.\n");
        pushButton1->setEnabled(TRUE);
        fclose(inputfile);
        if(edfplus)
        {
          fclose(logfile);
          fclose(pntfile);
          free(log_buf);
        }
        QApplication::restoreOverrideCursor();
        return;
      }

      if(error)
      {
        if(edfplus)
        {
          fclose(logfile);
          fclose(pntfile);
          free(log_buf);
        }
        QApplication::restoreOverrideCursor();
        pushButton1->setEnabled(TRUE);
        return;
      }

      total_blocks++;

      /**************************************************************/
    }
  }

  QApplication::restoreOverrideCursor();

  if(fclose(inputfile))  textEdit1->append("error closing inputfile.\n");
  if(edfplus)
  {
    if(fclose(logfile))  textEdit1->append("error closing .log file.\n");
    if(fclose(pntfile))  textEdit1->append("error closing .pnt file.\n");
    free(log_buf);
  }

  if(edfplus)  snprintf(txt_string, 2048, "Converted %u waveformblock(s) succesfully to EDF+.\n", total_blocks);
  else  snprintf(txt_string, 2048, "Converted %u waveformblock(s) succesfully to EDF.\n", total_blocks);
  textEdit1->append(txt_string);

  pushButton1->setEnabled(TRUE);
}




int UI_NK2EDFwindow::convert_nk2edf(FILE *inputfile, FILE *outputfile, FILE *pntfile,  int offset, int edfplus, int n_logs, char *log_buf)
{
  int i, j, k, p,
      temp,
      channels,
      samplefrequency,
      record_duration,
      raster,
      record_size,
      max_buf_records,
      bufsize,
      records_in_buf,
      seconds,
      deci_seconds,
      left_records,
      elapsed_time,
      error;

  char *buf,
       *annotations,
       scratchpad[48];

  QProgressDialog progress("Converting a waveform datablock...", "Cancel", 0, 100, myobjectDialog);
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(0);
  progress.setValue(1);

  for(k=0; k<10; k++)  qApp->processEvents();

/************************* filter events ******************************************/

  for(i=0; i<n_logs; i++)
  {
    elapsed_time = 36000 * (log_buf[(i * 45) + 20] - 48);
    elapsed_time += 3600 * (log_buf[(i * 45) + 21] - 48);
    elapsed_time += 600 * (log_buf[(i * 45) + 22] - 48);
    elapsed_time += 60 * (log_buf[(i * 45) + 23] - 48);
    elapsed_time += 10 * (log_buf[(i * 45) + 24] - 48);
    elapsed_time += log_buf[(i * 45) + 25] - 48;
    if(elapsed_time>=total_elapsed_time) break;
  }
  log_buf += i * 45;
  n_logs -= i;

/************************* write EDF-header ***************************************/

  rewind(outputfile);

  fprintf(outputfile, "0       ");

  if(edfplus)
  {
    error = 0;
    fseeko64(pntfile, 0x0604, SEEK_SET);
    if(fread(scratchpad, 10, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[10] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<10; i++)
    {
      if(scratchpad[i]==0)  break;
      if(scratchpad[i]==' ')  scratchpad[i] = '_';
    }
    if(i)
    {
      p = i;
      if(fwrite(scratchpad, i, 1, outputfile)!=1)
      {
        return(3);
      }
    }
    else
    {
      fputc('X', outputfile);
      p = 1;
    }
    fputc(' ', outputfile);
    p++;

    fseeko64(pntfile, 0x064a, SEEK_SET);
    if(fread(scratchpad, 6, 1, pntfile)!=1)
    {
      return(2);
    }
    if(!strncmp(scratchpad, "Male", 4))  fputc('M', outputfile);
    else
    {
      if(!strncmp(scratchpad, "Female", 6))  fputc('F', outputfile);
      else  fputc('X', outputfile);
    }
    p++;
    fputc(' ', outputfile);
    p++;

    fseeko64(pntfile, 0x0668, SEEK_SET);
    if(fread(scratchpad, 2, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[2] = 0;
    temp = atoi(scratchpad);
    if((temp<1)||(temp>31))  error = 1;
    for(i=0; i<2; i++)
    {
      if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
      {
        error = 1;
        break;
      }
    }
    fseeko64(pntfile, 0x0665, SEEK_SET);
    if(fread(scratchpad, 2, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[2] = 0;
    temp = atoi(scratchpad);
    if((temp<1)||(temp>12))  error = 1;
    fseeko64(pntfile, 0x0660, SEEK_SET);
    if(fread(scratchpad, 4, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[4] = 0;
    temp = atoi(scratchpad);
    if((temp<1)||(temp>9999))  error = 1;
    for(i=0; i<4; i++)
    {
      if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
      {
        error = 1;
        break;
      }
    }

    if(error)
    {
      fputc('X', outputfile);
      p++;
    }
    else
    {
      fseeko64(pntfile, 0x0668, SEEK_SET);
      if(fread(scratchpad, 2, 1, pntfile)!=1)
      {
        return(2);
      }
      scratchpad[2] = 0;
      temp = atoi(scratchpad);
      if((temp<1)||(temp>31))
      {
        snprintf(scratchpad, 48, "01");
        error = 1;
      }
      for(i=0; i<2; i++)
      {
        if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
        {
          snprintf(scratchpad, 48, "01");
          error = 1;
          break;
        }
      }
      if(fwrite(scratchpad, 2, 1, outputfile)!=1)
      {
        return(3);
      }
      p += 2;
      fputc('-', outputfile);
      p++;
      fseeko64(pntfile, 0x0665, SEEK_SET);
      if(fread(scratchpad, 2, 1, pntfile)!=1)
      {
        return(2);
      }
      scratchpad[2] = 0;
      temp = atoi(scratchpad);
      switch(temp)
      {
        case  1 : strcpy(scratchpad, "JAN");
                  break;
        case  2 : strcpy(scratchpad, "FEB");
                  break;
        case  3 : strcpy(scratchpad, "MAR");
                  break;
        case  4 : strcpy(scratchpad, "APR");
                  break;
        case  5 : strcpy(scratchpad, "MAY");
                  break;
        case  6 : strcpy(scratchpad, "JUN");
                  break;
        case  7 : strcpy(scratchpad, "JUL");
                  break;
        case  8 : strcpy(scratchpad, "AUG");
                  break;
        case  9 : strcpy(scratchpad, "SEP");
                  break;
        case 10 : strcpy(scratchpad, "OCT");
                  break;
        case 11 : strcpy(scratchpad, "NOV");
                  break;
        case 12 : strcpy(scratchpad, "DEC");
                  break;
        default : strcpy(scratchpad, "JAN");
                  error = 1;
                  break;
      }
      if(fwrite(scratchpad, 3, 1, outputfile)!=1)
      {
        return(3);
      }
      p += 3;
      fputc('-', outputfile);
      p++;
      fseeko64(pntfile, 0x0660, SEEK_SET);
      if(fread(scratchpad, 4, 1, pntfile)!=1)
      {
        return(2);
      }
      scratchpad[4] = 0;
      temp = atoi(scratchpad);
      if((temp<1)||(temp>9999))
      {
        snprintf(scratchpad, 48, "1800");
        error = 1;
      }
      for(i=0; i<4; i++)
      {
        if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
        {
          snprintf(scratchpad, 48, "1800");
          error = 1;
          break;
        }
      }
      if(fwrite(scratchpad, 4, 1, outputfile)!=1)
      {
        return(3);
      }
      p += 4;
    }

    fputc(' ', outputfile);
    p++;

    fseeko64(pntfile, 0x062e, SEEK_SET);
    if(fread(scratchpad, 20, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[20] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<20; i++)
    {
      if(scratchpad[i]==0)  break;
      if(scratchpad[i]==' ')  scratchpad[i] = '_';
    }
    if(i)
    {
      p += i;
      if(fwrite(scratchpad, i, 1, outputfile)!=1)
      {
        return(3);
      }
    }
    else
    {
      fputc('X', outputfile);
      p++;
    }

    for(i=0; i<80-p; i++)  fputc(' ', outputfile);

    if(fwrite("Startdate ", 10, 1, outputfile)!=1)
    {
      return(3);
    }
    p = 10;
    error = 0;
    fseeko64(pntfile, 0x0046, SEEK_SET);
    if(fread(scratchpad, 2, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[2] = 0;
    temp = atoi(scratchpad);
    if((temp<1)||(temp>31))  error = 1;
    for(i=0; i<2; i++)
    {
      if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
      {
        error = 1;
        break;
      }
    }
    fseeko64(pntfile, 0x0044, SEEK_SET);
    if(fread(scratchpad, 2, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[2] = 0;
    temp = atoi(scratchpad);
    if((temp<1)||(temp>12))  error = 1;
    fseeko64(pntfile, 0x0040, SEEK_SET);
    if(fread(scratchpad, 4, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[4] = 0;
    temp = atoi(scratchpad);
    if((temp<1970)||(temp>9999))  error = 1;
    for(i=0; i<4; i++)
    {
      if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
      {
        error = 1;
        break;
      }
    }

    if(error)
    {
      fputc('X', outputfile);
      p++;
    }
    else
    {
      fseeko64(pntfile, 0x0046, SEEK_SET);
      if(fread(scratchpad, 2, 1, pntfile)!=1)
      {
        return(2);
      }
      scratchpad[2] = 0;
      temp = atoi(scratchpad);
      if((temp<1)||(temp>31))  snprintf(scratchpad, 48, "01");
      for(i=0; i<2; i++)
      {
        if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
        {
          snprintf(scratchpad, 48, "01");
          break;
        }
      }
      if(fwrite(scratchpad, 2, 1, outputfile)!=1)
      {
        return(3);
      }
      fputc('-', outputfile);
      fseeko64(pntfile, 0x0044, SEEK_SET);
      if(fread(scratchpad, 2, 1, pntfile)!=1)
      {
        return(2);
      }
      scratchpad[2] = 0;
      temp = atoi(scratchpad);
      switch(temp)
      {
        case  1 : strcpy(scratchpad, "JAN");
                  break;
        case  2 : strcpy(scratchpad, "FEB");
                  break;
        case  3 : strcpy(scratchpad, "MAR");
                  break;
        case  4 : strcpy(scratchpad, "APR");
                  break;
        case  5 : strcpy(scratchpad, "MAY");
                  break;
        case  6 : strcpy(scratchpad, "JUN");
                  break;
        case  7 : strcpy(scratchpad, "JUL");
                  break;
        case  8 : strcpy(scratchpad, "AUG");
                  break;
        case  9 : strcpy(scratchpad, "SEP");
                  break;
        case 10 : strcpy(scratchpad, "OCT");
                  break;
        case 11 : strcpy(scratchpad, "NOV");
                  break;
        case 12 : strcpy(scratchpad, "DEC");
                  break;
        default : strcpy(scratchpad, "JAN");
                  break;
      }
      if(fwrite(scratchpad, 3, 1, outputfile)!=1)
      {
        return(3);
      }
      fputc('-', outputfile);
      fseeko64(pntfile, 0x0040, SEEK_SET);
      if(fread(scratchpad, 4, 1, pntfile)!=1)
      {
        return(2);
      }
      scratchpad[4] = 0;
      temp = atoi(scratchpad);
      if((temp<1)||(temp>9999))  snprintf(scratchpad, 48, "1800");
      for(i=0; i<4; i++)
      {
        if((scratchpad[i]<'0')||(scratchpad[i]>'9'))
        {
          snprintf(scratchpad, 48, "1800");
          break;
        }
      }
      if(fwrite(scratchpad, 4, 1, outputfile)!=1)
      {
        return(3);
      }
      p += 11;
    }

    fputc(' ', outputfile);
    p++;

    fseeko64(pntfile, 0x061c, SEEK_SET);
    if(fread(scratchpad, 10, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[10] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<10; i++)
    {
      if(scratchpad[i]==0)  break;
      if(scratchpad[i]==' ')  scratchpad[i] = '_';
    }
    if(i)
    {
      p += i;
      if(fwrite(scratchpad, i, 1, outputfile)!=1)
      {
        return(3);
      }
    }
    else
    {
      fputc('X', outputfile);
      p++;
    }

    fputc(' ', outputfile);
    p++;

    fseeko64(pntfile, 0x06aa, SEEK_SET);
    if(fread(scratchpad, 20, 1, pntfile)!=1)
    {
      return(2);
    }
    scratchpad[20] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<20; i++)
    {
      if(scratchpad[i]==0)  break;
      if(scratchpad[i]==' ')  scratchpad[i] = '_';
    }
    if(i)
    {
      p += i;
      if(fwrite(scratchpad, i, 1, outputfile)!=1)
      {
        return(3);
      }
    }
    else
    {
      fputc('X', outputfile);
      p++;
    }

    fputc(' ', outputfile);
    p++;

    if(fwrite("Nihon_Kohden_", 13, 1, outputfile)!=1)
    {
      return(3);
    }
    p += 13;
    rewind(inputfile);
    if(fread(scratchpad, 16, 1, inputfile)!=1)
    {
      return(2);
    }
    scratchpad[16] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<16; i++)
    {
      if(scratchpad[i]==0)  break;
      if(scratchpad[i]==' ')  scratchpad[i] = '_';
    }
    if(fwrite(scratchpad, i, 1, outputfile)!=1)
    {
      return(3);
    }
    p += i;

    for(i=0; i<80-p; i++)  fputc(' ', outputfile);
  }
  else
  {
    fseeko64(inputfile, 0x004f, SEEK_SET);
    if(fread(scratchpad, 32, 1, inputfile)!=1)
    {
      return(2);
    }
    scratchpad[32] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<32; i++)
    {
      if(scratchpad[i]==0)  break;
    }
    p = 80 - i;
    if(fwrite(scratchpad, i, 1, outputfile)!=1)
    {
      return(3);
    }
    for(i=0; i<p; i++)  fputc(' ', outputfile);

    if(fwrite("Nihon Kohden ", 13, 1, outputfile)!=1)
    {
      return(3);
    }
    rewind(inputfile);
    if(fread(scratchpad, 16, 1, inputfile)!=1)
    {
      return(2);
    }
    scratchpad[16] = 0;
    latin1_to_ascii(scratchpad, strlen(scratchpad));
    for(i=0; i<16; i++)
    {
      if(scratchpad[i]==0)  break;
    }
    p = 67 - i;
    if(fwrite(scratchpad, i, 1, outputfile)!=1)
    {
      return(3);
    }
    for(i=0; i<p; i++)  fputc(' ', outputfile);
  }

  fseeko64(inputfile, 0x0016 + offset, SEEK_SET);
  temp = fgetc(inputfile);
  fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15));
  fseeko64(inputfile, 0x0015 + offset, SEEK_SET);
  temp = fgetc(inputfile);
  fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15));
  fseeko64(inputfile, 0x0014 + offset, SEEK_SET);
  temp = fgetc(inputfile);
  fprintf(outputfile, "%02u", ((temp >> 4) * 10) + (temp & 15));

  fseeko64(inputfile, 0x0017 + offset, SEEK_SET);
  temp = fgetc(inputfile);
  fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15));
  temp = fgetc(inputfile);
  fprintf(outputfile, "%02u.", ((temp >> 4) * 10) + (temp & 15));
  temp = fgetc(inputfile);
  fprintf(outputfile, "%02u", ((temp >> 4) * 10) + (temp & 15));

  fseeko64(inputfile, 0x0026 + offset, SEEK_SET);
  channels = fgetc(inputfile);
  if(edfplus)
  {
    fprintf(outputfile, "%-8u", (channels + 1) * 256 + 256);
    fprintf(outputfile, "EDF+C");
    for(i=0; i<39; i++)  fputc(' ', outputfile);
  }
  else
  {
    fprintf(outputfile, "%-8u", channels * 256 + 256);
    for(i=0; i<44; i++)  fputc(' ', outputfile);
  }
  fseeko64(inputfile, 0x001c + offset, SEEK_SET);
  if(fread((char *)(&record_duration), 4, 1, inputfile)!=1)
  {
    return(2);
  }
  fprintf(outputfile, "%-8u", record_duration);
  fprintf(outputfile, "0.1     ");
  if(edfplus)  fprintf(outputfile, "%-4u", channels + 1);
  else  fprintf(outputfile, "%-4u", channels);

  for(i=0; i<channels; i++)
  {
    fseeko64(inputfile, 0x0027 + (i * 10) + offset, SEEK_SET);
    temp = fgetc(inputfile);
    switch(temp)
    {
      case  0 : fprintf(outputfile, "EEG FP1         ");
                break;
      case  1 : fprintf(outputfile, "EEG FP2         ");
                break;
      case  2 : fprintf(outputfile, "EEG F3          ");
                break;
      case  3 : fprintf(outputfile, "EEG F4          ");
                break;
      case  4 : fprintf(outputfile, "EEG C3          ");
                break;
      case  5 : fprintf(outputfile, "EEG C4          ");
                break;
      case  6 : fprintf(outputfile, "EEG P3          ");
                break;
      case  7 : fprintf(outputfile, "EEG P4          ");
                break;
      case  8 : fprintf(outputfile, "EEG O1          ");
                break;
      case  9 : fprintf(outputfile, "EEG O2          ");
                break;
      case 10 : fprintf(outputfile, "EEG F7          ");
                break;
      case 11 : fprintf(outputfile, "EEG F8          ");
                break;
      case 12 : fprintf(outputfile, "EEG T3          ");
                break;
      case 13 : fprintf(outputfile, "EEG T4          ");
                break;
      case 14 : fprintf(outputfile, "EEG T5          ");
                break;
      case 15 : fprintf(outputfile, "EEG T6          ");
                break;
      case 16 : fprintf(outputfile, "EEG FZ          ");
                break;
      case 17 : fprintf(outputfile, "EEG CZ          ");
                break;
      case 18 : fprintf(outputfile, "EEG PZ          ");
                break;
      case 19 : fprintf(outputfile, "EEG E           ");
                break;
      case 20 : fprintf(outputfile, "EEG PG1         ");
                break;
      case 21 : fprintf(outputfile, "EEG PG2         ");
                break;
      case 22 : fprintf(outputfile, "EEG A1          ");
                break;
      case 23 : fprintf(outputfile, "EEG A2          ");
                break;
      case 24 : fprintf(outputfile, "EEG T1          ");
                break;
      case 25 : fprintf(outputfile, "EEG T2          ");
                break;
      case 35 : fprintf(outputfile, "EEG X10         ");
                break;
      case 36 : fprintf(outputfile, "EEG X11         ");
                break;
      case 74 : fprintf(outputfile, "BN1             ");
                break;
      case 75 : fprintf(outputfile, "BN2             ");
                break;
      case 76 : fprintf(outputfile, "Mark1           ");
                break;
      case 77 : fprintf(outputfile, "Mark2           ");
                break;
      case 100 : fprintf(outputfile, "EEG X12/BP1     ");
                 break;
      case 101 : fprintf(outputfile, "EEG X13/BP2     ");
                 break;
      case 102 : fprintf(outputfile, "EEG X14/BP3     ");
                 break;
      case 103 : fprintf(outputfile, "EEG X15/BP4     ");
                 break;
      case 254 : fprintf(outputfile, "-               ");
                 break;
      case 255 : fprintf(outputfile, "Z               ");
                 break;
    }

    if((25<temp)&&(temp<35))    fprintf(outputfile, "EEG X%u          ", temp - 25);
    if((36<temp)&&(temp<42))    fprintf(outputfile, "-               ");
    if((41<temp)&&(temp<74))    fprintf(outputfile, "DC%02u            ", temp - 41);
    if((77<temp)&&(temp<100))   fprintf(outputfile, "-               ");
    if((103<temp)&&(temp<188))  fprintf(outputfile, "EEG X%u         ", temp - 88);
    if((187<temp)&&(temp<254))  fprintf(outputfile, "EEG X%u        ", temp - 88);
  }

  if(edfplus)  fprintf(outputfile, "EDF Annotations ");

  for(i=0; i<(channels * 80); i++)  fputc(' ', outputfile);
  if(edfplus)  for(i=0; i<80; i++)  fputc(' ', outputfile);

  for(i=0; i<channels; i++)
  {
    fseeko64(inputfile, 0x0027 + (i * 10) + offset, SEEK_SET);
    temp = fgetc(inputfile);
    if((temp<42)||(temp>73))  fprintf(outputfile, "uV      ");
    else  fprintf(outputfile, "mV      ");
  }
  if(edfplus)  fprintf(outputfile, "        ");

  for(i=0; i<channels; i++)
  {
    fseeko64(inputfile, 0x0027 + (i * 10) + offset, SEEK_SET);
    temp = fgetc(inputfile);
    if((temp<42)||(temp>73))  fprintf(outputfile, "-3200   ");
    else  fprintf(outputfile, "-12002.9");
  }
  if(edfplus)  fprintf(outputfile, "-1      ");

  for(i=0; i<channels; i++)
  {
    fseeko64(inputfile, 0x0027 + (i * 10) + offset, SEEK_SET);
    temp = fgetc(inputfile);
    if((temp<42)||(temp>73))  fprintf(outputfile, "3199.902");
    else  fprintf(outputfile, "12002.56");
  }
  if(edfplus)  fprintf(outputfile, "1       ");

  for(i=0; i<channels; i++)  fprintf(outputfile, "-32768  ");
  if(edfplus)  fprintf(outputfile, "-32768  ");

  for(i=0; i<channels; i++)  fprintf(outputfile, "32767   ");
  if(edfplus)  fprintf(outputfile, "32767   ");

  for(i=0; i<(channels * 80); i++)  fputc(' ', outputfile);
  if(edfplus)  for(i=0; i<80; i++)  fputc(' ', outputfile);

  fseeko64(inputfile, 0x001b + offset, SEEK_SET);
  samplefrequency = fgetc(inputfile) * 256;
  fseeko64(inputfile, 0x001a + offset, SEEK_SET);
  samplefrequency += fgetc(inputfile);
  samplefrequency &= 0x3fff;
  for(i=0; i<channels; i++)  fprintf(outputfile, "%-8u", samplefrequency / 10);
  if(edfplus)  fprintf(outputfile, "25      ");

  for(i=0; i<(channels * 32); i++)  fputc(' ', outputfile);
  if(edfplus)  for(i=0; i<32; i++)  fputc(' ', outputfile);

/************************* write data ****************************************************/

  progress.setValue(1);
  for(k=0; k<10; k++)  qApp->processEvents();

  bufsize = 4194304;
  buf = (char *)calloc(1, bufsize);
  if(buf==NULL)  return(1);

  record_size = (samplefrequency / 10) * channels * 2;
  if(edfplus)  record_size += 50;

  max_buf_records = bufsize / record_size;

  raster = (samplefrequency / 10) * 2;

  seconds = 0;
  deci_seconds = 0;

  fseeko64(inputfile, 0x0027 + offset + (channels * 10), SEEK_SET);

  left_records = record_duration;

  while(left_records)
  {
    if(left_records>max_buf_records)  records_in_buf = max_buf_records;
    else  records_in_buf = left_records;

    for(i=0; i<records_in_buf; i++)
    {
      for(j=0; j<raster; j+=2)
      {
        for(k=0; k<channels; k++)
        {
          buf[j+(k*raster)+(i*record_size)] = fgetc(inputfile);
          buf[j+(k*raster)+(i*record_size)+1] = fgetc(inputfile) + 128;
        }
        fgetc(inputfile);
        if(fgetc(inputfile)==EOF)
        {
          free(buf);
          return(2);
        }
      }
      if(edfplus)
      {
        annotations = buf + (i * record_size) + (raster * channels);
        memset(annotations, 0, 50);
        p = sprintf(annotations, "%+i.%i", seconds, deci_seconds);
        annotations[p++] = 20;
        annotations[p++] = 20;
        if(n_logs>seconds)
        {
          if(!deci_seconds)
          {
            elapsed_time = 36000 * (log_buf[(seconds * 45) + 20] - 48);
            elapsed_time += 3600 * (log_buf[(seconds * 45) + 21] - 48);
            elapsed_time += 600 * (log_buf[(seconds * 45) + 22] - 48);
            elapsed_time += 60 * (log_buf[(seconds * 45) + 23] - 48);
            elapsed_time += 10 * (log_buf[(seconds * 45) + 24] - 48);
            elapsed_time += log_buf[(seconds * 45) + 25] - 48;
            if(elapsed_time>=total_elapsed_time)
            {
              elapsed_time -= total_elapsed_time;
              if(elapsed_time<(record_duration / 10))
              {
                p++;
                p += sprintf(annotations + p, "%+i", elapsed_time);
                annotations[p++] = 20;
                strncpy(annotations + p, log_buf + (seconds * 45), 20);
                p += 20;
                annotations[p] = 20;
              }
            }
          }
        }
      }
      if(++deci_seconds>9)
      {
        deci_seconds = 0;
        seconds++;
      }
    }

    if(fwrite(buf, records_in_buf * record_size, 1, outputfile)!=1)
    {
      free(buf);
      return(3);
    }
    left_records -= records_in_buf;

    progress.setValue((seconds * 100) / (record_duration / 10));
    for(k=0; k<10; k++)  qApp->processEvents();
  }

  total_elapsed_time += record_duration / 10;

  free(buf);

  return(0);
}


int UI_NK2EDFwindow::check_device(char *str)
{
  int error = 1;

  if(!strncmp(str, "EEG-1100A V01.00", 16))  error = 0;
  if(!strncmp(str, "EEG-1100B V01.00", 16))  error = 0;
  if(!strncmp(str, "EEG-1100C V01.00", 16))  error = 0;
  if(!strncmp(str, "QI-403A   V01.00", 16))  error = 0;
  if(!strncmp(str, "QI-403A   V02.00", 16))  error = 0;
  if(!strncmp(str, "EEG-2100  V01.00", 16))  error = 0;
  if(!strncmp(str, "EEG-2100  V02.00", 16))  error = 0;
  if(!strncmp(str, "DAE-2100D V01.30", 16))  error = 0;
  if(!strncmp(str, "DAE-2100D V02.00", 16))  error = 0;

  return(error);
}



void UI_NK2EDFwindow::latin12utf8(char *latin1_str, int len)
{
  int i, j;

  unsigned char *str, tmp_str[512];


  str = (unsigned char *)latin1_str;

  j = 0;

  for(i=0; i<len; i++)
  {
    if(str[i]==0)  return;

    tmp_str[j] = str[i];

    if(str[i]<32) tmp_str[j] = '.';

    if((str[i]>126)&&(str[i]<160))  tmp_str[j] = '.';

    if(str[i]>159)
    {
      if((len-j)<2)
      {
        tmp_str[j] = ' ';
      }
      else
      {
        tmp_str[j] = 192 + (str[i]>>6);
        j++;
        tmp_str[j] = 128 + (str[i]&63);
      }
    }

    j++;

    if(j>=len)  break;
  }

  for(i=0; i<len; i++)
  {
    str[i] = tmp_str[i];
  }
}



Generated by  Doxygen 1.6.0   Back to index