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(); }
void UI_BI98002EDFwindow::SelectFileButton() { int i, j, n, tmp, end_of_file, samplefreq=0, chns = 3, hdl, samplesize=1, bufsize, *buf2, datablocks, blocks_written, checked_modelnumber=0, checked_samplerate=0, checked_recordhours=0, checked_recorddate=0, checked_recordtime=0, startdate_year=0, startdate_month=0, startdate_day=0, starttime_hour=0, starttime_minute=0, starttime_second=0, progress_steps; char path[MAX_PATH_LENGTH], outputfilename[MAX_PATH_LENGTH], str[2048], str2[128], *buf1, tmp2, modelnumber_str[32]; FILE *dcmfile, *evtfile; strcpy(path, QFileDialog::getOpenFileName(0, "Select inputfile", QString::fromLocal8Bit(recent_opendir), "DCM files (*.dcm *.DCM)").toLocal8Bit().data()); if(!strcmp(path, "")) { return; } get_directory_from_path(recent_opendir, path, MAX_PATH_LENGTH); get_filename_from_path(outputfilename, path, MAX_PATH_LENGTH); dcmfile = fopeno(path, "rb"); if(dcmfile==NULL) { snprintf(str, 2048, "Can not open file %s for reading.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", QString::fromLocal8Bit(str)); messagewindow.exec(); return; } remove_extension_from_filename(path); strcat(path, ".EVT"); evtfile = fopeno(path, "rb"); if(evtfile==NULL) { remove_extension_from_filename(path); strcat(path, ".evt"); evtfile = fopeno(path, "rb"); if(evtfile==NULL) { snprintf(str, 2048, "Can not open file %s for reading.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(dcmfile); return; } } /***************** check if the file is valid ******************************/ for(end_of_file=0; end_of_file == 0; ) { for(i=0; i<256; i++) { tmp = fgetc(evtfile); if(tmp == '\n') { break; } if(tmp == EOF) { end_of_file = 1; break; } str[i] = tmp; } str[i] = 0; if(!(strncmp(str, "Sampling Rate=", 14))) { samplefreq = atoi(str + 14); switch(samplefreq) { case 128 : break; case 256 : break; case 512 : break; case 1024 : break; default : QMessageBox messagewindow(QMessageBox::Critical, "Error", "Unknown samplerate."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } checked_samplerate = 1; } if(!(strncmp(str, "Model number=", 13))) { strncpy(modelnumber_str, str + 13, 8); modelnumber_str[8] = 0; if(strcmp(modelnumber_str, "TM SD01G") && strcmp(modelnumber_str, "SD SD02G")) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Wrong modelnumber."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } checked_modelnumber = 1; } if(!(strncmp(str, "Record Date=", 12))) { strncpy(str2, str + 12, 10); str2[10] = 0; startdate_year = atoi(str2); startdate_month = atoi(str2 + 5); startdate_day = atoi(str2 + 8); if((startdate_year < 1970) || (startdate_year > 3000) || (startdate_month < 1) || (startdate_month > 12) || (startdate_day < 1) || (startdate_day > 31)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Wrong record date."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } checked_recorddate = 1; } if(!(strncmp(str, "Record Time=", 12))) { strncpy(str2, str + 12, 10); str2[8] = 0; starttime_hour = atoi(str2); starttime_minute = atoi(str2 + 3); starttime_second = atoi(str2 + 6); if((starttime_hour < 0) || (starttime_hour > 23) || (starttime_minute < 0) || (starttime_minute > 59) || (starttime_second < 0) || (starttime_second > 59)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Wrong recordtime."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } checked_recordtime = 1; } if(!(strncmp(str, "Record Hours=", 13))) { strncpy(str2, str + 13, 10); str2[2] = 0; if((atoi(str2) != 24) && (atoi(str2) != 48)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Wrong record hours."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } checked_recordhours = 1; } } if(!checked_modelnumber || !checked_samplerate || !checked_recordhours || !checked_recorddate || !checked_recordtime) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Missing line."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } /////////////////////////////////////////////////////////////////////////////////// bufsize = chns * samplesize * samplefreq; buf1 = (char *)malloc(bufsize); if(buf1 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); return; } buf2 = (int *)malloc(bufsize * sizeof(int)); if(buf2 == NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Malloc error."); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); free(buf1); return; } /////////////////////////////////////////////////////////////////////////////////// path[0] = 0; if(recent_savedir[0]!=0) { strcpy(path, recent_savedir); strcat(path, "/"); } strcat(path, outputfilename); remove_extension_from_filename(path); strcat(path, ".edf"); strcpy(path, QFileDialog::getSaveFileName(0, "Select outputfile", QString::fromLocal8Bit(path), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); if(!strcmp(path, "")) { fclose(dcmfile); fclose(evtfile); free(buf1); free(buf2); return; } get_directory_from_path(recent_savedir, path, MAX_PATH_LENGTH); hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, chns); if(hdl<0) { snprintf(str, 2048, "Can not open file %s for writing.", path); QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); fclose(dcmfile); fclose(evtfile); free(buf1); free(buf2); return; } for(i=0; i<chns; i++) { edf_set_samplefrequency(hdl, i, samplefreq); } for(i=0; i<chns; i++) { edf_set_digital_maximum(hdl, i, 127); } for(i=0; i<chns; i++) { edf_set_digital_minimum(hdl, i, -128); } for(i=0; i<chns; i++) { edf_set_physical_maximum(hdl, i, 2442.307692); } for(i=0; i<chns; i++) { edf_set_physical_minimum(hdl, i, -2461.538462); } for(i=0; i<chns; i++) { edf_set_physical_dimension(hdl, i, "uV"); } edf_set_label(hdl, 0, "channel 1"); edf_set_label(hdl, 1, "channel 2"); edf_set_label(hdl, 2, "channel 3"); edf_set_equipment(hdl, modelnumber_str); edf_set_patientname(hdl, "BI9800"); edf_set_startdatetime(hdl, startdate_year, startdate_month, startdate_day, starttime_hour, starttime_minute, starttime_second); fseeko(dcmfile, 0LL, SEEK_END); datablocks = ftello(dcmfile) / bufsize; fseeko(dcmfile, 0LL, SEEK_SET); QProgressDialog progress("Converting...", "Cancel", 0, datablocks, myobjectDialog); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datablocks / 100; if(progress_steps < 1) { progress_steps = 1; } for(blocks_written=0; ; blocks_written++) { if(!(blocks_written % progress_steps)) { progress.setValue(blocks_written); qApp->processEvents(); if(progress.wasCanceled() == true) { break; } } n = fread(buf1, bufsize, 1, dcmfile); if(n != 1) { break; } for(i=0; i<samplefreq; i++) { for(j=0; j<chns; j++) { tmp2 = buf1[(i * chns) + j] + 128; buf2[(j * samplefreq) + i] = tmp2; } } edf_blockwrite_digital_samples(hdl, buf2); } progress.reset(); edfwrite_annotation_latin1(hdl, 0LL, -1LL, "Recording starts"); fseeko(evtfile, 0LL, SEEK_SET); for(end_of_file=0; end_of_file == 0; ) { for(i=0; i<256; i++) { tmp = fgetc(evtfile); if((tmp == '\n') || (tmp == '\r')) { break; } if(tmp == EOF) { end_of_file = 1; break; } str[i] = tmp; } str[i] = 0; if((isdigit(str[0])) && (isdigit(str[1]))) { starttime_hour = atoi(str); starttime_minute = atoi(str + 3); starttime_second = atoi(str + 6); if((starttime_hour < 0) || (starttime_hour > 23) || (starttime_minute < 0) || (starttime_minute > 59) || (starttime_second < 0) || (starttime_second > 59)) { } else { if(strlen(str) > 9) { edfwrite_annotation_latin1(hdl, (starttime_second + (starttime_minute * 60) + (starttime_hour * 3600)) * 10000, -1, str + 9); } } } } edfwrite_annotation_latin1(hdl, blocks_written * 10000LL, -1LL, "Recording ends"); edfclose_file(hdl); fclose(dcmfile); fclose(evtfile); free(buf1); free(buf2); }
void UI_ExportAnnotationswindow::ExportButtonClicked() { int i, j, n, len, csv_format=0, hdl, annot_cnt, temp, include_duration; char path[MAX_PATH_LENGTH], str[1024], separator; FILE *annotationfile=NULL; struct annotationblock *annot, *annot_list; struct edfhdrblock *hdr; struct date_time_struct tm; if(CSVRadioButton->isChecked() == true) { if(asciiSecondsRadioButton->isChecked() == true) { csv_format = 1; } if(asciiISOtimeRadioButton->isChecked() == true) { csv_format = 2; } if(asciiISOtimedateRadioButton->isChecked() == true) { csv_format = 3; } if(asciiISOtimeFractionRadioButton->isChecked() == true) { csv_format = 4; } if(asciiISOtimedateFractionRadioButton->isChecked() == true) { csv_format = 5; } } if(EDFplusRadioButton->isChecked() == true) { csv_format = 0; } if(XMLRadioButton->isChecked() == true) { csv_format = 8; } mainwindow->export_annotations_var->format = csv_format; if(separatorBox->currentIndex() == 0) { separator = ','; mainwindow->export_annotations_var->separator = 0; } else { separator = '\t'; mainwindow->export_annotations_var->separator = 1; } if(durationCheckBox->checkState() == Qt::Checked) { include_duration = 1; mainwindow->export_annotations_var->duration = 1; } else { include_duration = 0; mainwindow->export_annotations_var->duration = 0; } if(!mainwindow->files_open) { ExportAnnotsDialog->close(); return; } if(filelist->count() < 1) { ExportAnnotsDialog->close(); return; } ExportButton->setEnabled(false); CloseButton->setEnabled(false); for(i=0; i<mainwindow->files_open; i++) { if(!strcmp(mainwindow->edfheaderlist[i]->filename, filelist->item(filelist->currentRow())->text().toLocal8Bit().data())) { break; } } if(i==mainwindow->files_open) { ExportAnnotsDialog->close(); return; } n = i; if(mergeRadioButton->isChecked() == true) { n = mainwindow->sel_viewtime; } hdr = mainwindow->edfheaderlist[n]; path[0] = 0; if(mainwindow->recent_savedir[0]!=0) { strcpy(path, mainwindow->recent_savedir); strcat(path, "/"); } len = strlen(path); get_filename_from_path(path + len, mainwindow->edfheaderlist[n]->filename, MAX_PATH_LENGTH - len); remove_extension_from_filename(path); if((csv_format > 0) && (csv_format < 6)) { strcat(path, "_annotations.txt"); strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "Text files (*.txt *.TXT *.csv *.CSV)").toLocal8Bit().data()); } if(csv_format == 8) { strcat(path, "_annotations.xml"); strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "XML files (*.xml *.XML)").toLocal8Bit().data()); } if(csv_format == 0) { strcat(path, "_annotations.edf"); strcpy(path, QFileDialog::getSaveFileName(0, "Output file", QString::fromLocal8Bit(path), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); } if(!strcmp(path, "")) { ExportAnnotsDialog->close(); return; } get_directory_from_path(mainwindow->recent_savedir, path, MAX_PATH_LENGTH); if(mainwindow->file_is_opened(path)) { QMessageBox messagewindow(QMessageBox::Critical, "Export annotations", "Error, selected file is in use."); messagewindow.exec(); return; } annot_list = edfplus_annotation_copy_list(&mainwindow->annotationlist[n]); if(mergeRadioButton->isChecked() == true) { for(i=0; i < mainwindow->files_open; i++) { if(i != mainwindow->sel_viewtime) { annot_cnt = edfplus_annotation_count(&mainwindow->annotationlist[i]); for(j=0; j < annot_cnt; j++) { edfplus_annotation_add_copy(&annot_list, edfplus_annotation_item(&mainwindow->annotationlist[i], j)); annot = edfplus_annotation_item(&annot_list, edfplus_annotation_count(&annot_list) - 1); annot->onset -= (mainwindow->edfheaderlist[i]->viewtime - mainwindow->edfheaderlist[mainwindow->sel_viewtime]->viewtime); } } } edfplus_annotation_sort(&annot_list); } annot_cnt = edfplus_annotation_count(&annot_list); ///////////////////////////// CSV (text) export ////////////////////////////////////// if((csv_format > 0) && (csv_format < 6)) { annotationfile = fopeno(path, "wb"); if(annotationfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open annotationfile for writing."); messagewindow.exec(); ExportAnnotsDialog->close(); edfplus_annotation_delete_list(&annot_list); return; } if(include_duration) { fprintf(annotationfile, "Onset%cDuration%cAnnotation\n", separator, separator); } else { fprintf(annotationfile, "Onset%cAnnotation\n", separator); } for(j=0; j < annot_cnt; j++) { annot = edfplus_annotation_item(&annot_list, j); if(annot == NULL) { break; } strncpy(str, annot->annotation, 1024); str[1023] = 0; utf8_to_latin1(str); len = strlen(str); for(i=0; i<len; i++) { if((((unsigned char *)str)[i] < 32) || (((unsigned char *)str)[i] == ',')) { str[i] = '.'; } } if(csv_format == 1) { if(include_duration) { fprintf(annotationfile, "%+.7f%c%s%c%s\n", (double)(annot->onset - hdr->starttime_offset) / TIME_DIMENSION, separator, annot->duration, separator, str); } else { fprintf(annotationfile, "%+.7f%c%s\n", (double)(annot->onset - hdr->starttime_offset) / TIME_DIMENSION, separator, str); } } if(csv_format == 2) { temp = annot->onset % TIME_DIMENSION; if(temp < 0) { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm); } else { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm); } if(include_duration) { fprintf(annotationfile, "%02i:%02i:%02i%c%s%c%s\n", tm.hour, tm.minute, tm.second, separator, annot->duration, separator, str); } else { fprintf(annotationfile, "%02i:%02i:%02i%c%s\n", tm.hour, tm.minute, tm.second, separator, str); } } if(csv_format == 3) { temp = annot->onset % TIME_DIMENSION; if(temp < 0) { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm); } else { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm); } if(include_duration) { fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i%c%s%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, separator, annot->duration, separator, str); } else { fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, separator, str); } } if(csv_format == 4) { temp = annot->onset % TIME_DIMENSION; if(temp < 0) { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm); temp = TIME_DIMENSION + temp; } else { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm); } if(include_duration) { fprintf(annotationfile, "%02i:%02i:%02i.%07i%c%s%c%s\n", tm.hour, tm.minute, tm.second, temp, separator, annot->duration, separator, str); } else { fprintf(annotationfile, "%02i:%02i:%02i.%07i%c%s\n", tm.hour, tm.minute, tm.second, temp, separator, str); } } if(csv_format == 5) { temp = annot->onset % TIME_DIMENSION; if(temp < 0) { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm); temp = TIME_DIMENSION + temp; } else { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm); } if(include_duration) { fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i.%07i%c%s%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, separator, annot->duration, separator, str); } else { fprintf(annotationfile, "%04i-%02i-%02iT%02i:%02i:%02i.%07i%c%s\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, separator, str); } } } fclose(annotationfile); edfplus_annotation_delete_list(&annot_list); QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); ExportAnnotsDialog->close(); return; } ///////////////////////////// XML export ////////////////////////////////////// if(csv_format == 8) { annotationfile = fopeno(path, "wb"); if(annotationfile==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not open annotationfile for writing."); messagewindow.exec(); ExportAnnotsDialog->close(); edfplus_annotation_delete_list(&annot_list); return; } fprintf(annotationfile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(annotationfile, "<!-- Generated by " PROGRAM_NAME " " PROGRAM_VERSION " -->\n"); fprintf(annotationfile, "<annotationlist>\n"); utc_to_date_time(hdr->utc_starttime, &tm); fprintf(annotationfile, " <recording_start_time>%04i-%02i-%02iT%02i:%02i:%02i.%07i</recording_start_time>\n", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, (int)hdr->starttime_offset); for(j=0; j < annot_cnt; j++) { annot = edfplus_annotation_item(&annot_list, j); if(annot == NULL) { break; } temp = annot->onset % TIME_DIMENSION; if(temp < 0) { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION) - 1, &tm); temp = TIME_DIMENSION + temp; } else { utc_to_date_time(hdr->utc_starttime + (annot->onset / TIME_DIMENSION), &tm); } fprintf(annotationfile, " <annotation>\n" " <onset>%04i-%02i-%02iT%02i:%02i:%02i.%07i</onset>\n" " <duration>%s</duration>\n" " <description>", tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second, temp, annot->duration); xml_fwrite_encode_entity(annotationfile, annot->annotation); fprintf(annotationfile, "</description>\n" " </annotation>\n"); } fprintf(annotationfile, "</annotationlist>\n"); fclose(annotationfile); edfplus_annotation_delete_list(&annot_list); QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); ExportAnnotsDialog->close(); return; } ///////////////////////////// EDFplus export ////////////////////////////////////// if(csv_format == 0) { hdl = edfopen_file_writeonly(path, EDFLIB_FILETYPE_EDFPLUS, 0); if(hdl < 0) { switch(hdl) { case EDFLIB_MALLOC_ERROR : strcpy(str, "EDFlib: malloc error"); break; case EDFLIB_NO_SUCH_FILE_OR_DIRECTORY : strcpy(str, "EDFlib: no such file or directory"); break; case EDFLIB_MAXFILES_REACHED : strcpy(str, "EDFlib: maximum files reached"); break; case EDFLIB_FILE_ALREADY_OPENED : strcpy(str, "EDFlib: file already opened"); break; case EDFLIB_NUMBER_OF_SIGNALS_INVALID : strcpy(str, "EDFlib: number of signals is invalid"); break; default : strcpy(str, "EDFlib: unknown error"); break; } QMessageBox messagewindow(QMessageBox::Critical, "Error", str); messagewindow.exec(); edfplus_annotation_delete_list(&annot_list); ExportAnnotsDialog->close(); return; } utc_to_date_time(hdr->utc_starttime, &tm); edf_set_startdatetime(hdl, tm.year, tm.month, tm.day, tm.hour, tm.minute, tm.second); if((hdr->edfplus) || (hdr->bdfplus)) { edf_set_patientname(hdl, hdr->plus_patient_name); edf_set_patientcode(hdl, hdr->plus_patientcode); if(!(strcmp(hdr->plus_gender, "Male"))) { edf_set_gender(hdl, 1); } if(!(strcmp(hdr->plus_gender, "Female"))) { edf_set_gender(hdl, 0); } if(hdr->plus_birthdate[0] != 0) { if(!(strncmp(hdr->plus_birthdate + 3, "jan", 3))) n = 1; if(!(strncmp(hdr->plus_birthdate + 3, "feb", 3))) n = 2; if(!(strncmp(hdr->plus_birthdate + 3, "mar", 3))) n = 3; if(!(strncmp(hdr->plus_birthdate + 3, "apr", 3))) n = 4; if(!(strncmp(hdr->plus_birthdate + 3, "may", 3))) n = 5; if(!(strncmp(hdr->plus_birthdate + 3, "jun", 3))) n = 6; if(!(strncmp(hdr->plus_birthdate + 3, "jul", 3))) n = 7; if(!(strncmp(hdr->plus_birthdate + 3, "aug", 3))) n = 8; if(!(strncmp(hdr->plus_birthdate + 3, "sep", 3))) n = 9; if(!(strncmp(hdr->plus_birthdate + 3, "oct", 3))) n = 10; if(!(strncmp(hdr->plus_birthdate + 3, "nov", 3))) n = 11; if(!(strncmp(hdr->plus_birthdate + 3, "dec", 3))) n = 12; edf_set_birthdate(hdl, atoi(hdr->plus_birthdate + 7), n, atoi(hdr->plus_birthdate)); } edf_set_patient_additional(hdl, hdr->plus_patient_additional); edf_set_admincode(hdl, hdr->plus_admincode); edf_set_technician(hdl, hdr->plus_technician); edf_set_equipment(hdl, hdr->plus_equipment); edf_set_recording_additional(hdl, hdr->plus_recording_additional); } else { edf_set_patientname(hdl, hdr->patient); edf_set_recording_additional(hdl, hdr->recording); } int hasdot, decimals; for(j=0; j < annot_cnt; j++) { annot = edfplus_annotation_item(&annot_list, j); if(annot == NULL) { break; } if(annot->duration[0] == 0) { edfwrite_annotation_utf8(hdl, annot->onset / 1000LL, -1LL, annot->annotation); } else { strcpy(str, annot->duration); len = strlen(str); hasdot = 0; for(i=0; i<len; i++) { if(str[i] == '.') { hasdot = 1; for(decimals=0; decimals<4; decimals++) { str[i] = str[i+1]; if(str[i] == 0) { for( ; decimals<4; decimals++) { str[i] = '0'; i++; } i--; } i++; } str[i] = 0; break; } } if(!hasdot) { strcat(str, "0000"); } edfwrite_annotation_utf8(hdl, annot->onset / 1000LL, atoi(str), annot->annotation); } } if(edfclose_file(hdl) != 0) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred: edfclose_file()"); messagewindow.exec(); } edfplus_annotation_delete_list(&annot_list); QMessageBox messagewindow(QMessageBox::Information, "Ready", "Done."); messagewindow.setIconPixmap(QPixmap(":/images/ok.png")); messagewindow.exec(); ExportAnnotsDialog->close(); } }
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); }
int main(int argc, char *argv[]) { int i, j, hdl, chns=1, smp_freq=8192, fileduration=300, linear=1; double buf[smp_freq], q, sine_1, startfreq=10.0, stopfreq=4095.0, freqspan, freq; long long samples, sampleswritten; char str[256]; #ifdef BDF_FORMAT hdl = edfopen_file_writeonly("freq_sweep.bdf", EDFLIB_FILETYPE_BDFPLUS, chns); #else hdl = edfopen_file_writeonly("freq_sweep.edf", EDFLIB_FILETYPE_EDFPLUS, chns); #endif if(hdl<0) { printf("error: edfopen_file_writeonly()\n"); return(1); } for(i=0; i<chns; i++) { if(edf_set_samplefrequency(hdl, i, smp_freq)) { printf("error: edf_set_samplefrequency()\n"); return(1); } } #ifdef BDF_FORMAT for(i=0; i<chns; i++) { if(edf_set_digital_maximum(hdl, i, 8388607)) { printf("error: edf_set_digital_maximum()\n"); return(1); } } for(i=0; i<chns; i++) { if(edf_set_digital_minimum(hdl, i, -8388608)) { printf("error: edf_set_digital_minimum()\n"); return(1); } } #else for(i=0; i<chns; i++) { if(edf_set_digital_maximum(hdl, i, 32767)) { printf("error: edf_set_digital_maximum()\n"); return(1); } } for(i=0; i<chns; i++) { if(edf_set_digital_minimum(hdl, i, -32768)) { printf("error: edf_set_digital_minimum()\n"); return(1); } } #endif for(i=0; i<chns; i++) { if(edf_set_physical_maximum(hdl, i, 400.0)) { printf("error: edf_set_physical_maximum()\n"); return(1); } } for(i=0; i<chns; i++) { if(edf_set_physical_minimum(hdl, i, -400.0)) { printf("error: edf_set_physical_minimum()\n"); return(1); } } for(i=0; i<chns; i++) { if(edf_set_physical_dimension(hdl, i, "uV")) { printf("error: edf_set_physical_dimension()\n"); return(1); } } if(edf_set_label(hdl, 0, "sweep")) { printf("error: edf_set_label()\n"); return(1); } if(edf_set_equipment(hdl, "Software generated file")) { printf("edf_set_equipment()\n"); return(1); } if(linear) { sprintf(str, "Linear frequency sweep from %fHz to %fHz", startfreq, stopfreq); } else { sprintf(str, "Logarithmic frequency sweep from %fHz to %fHz", startfreq, stopfreq); } remove_trailing_zeros(str); edf_set_patientname(hdl, str); edfwrite_annotation_latin1(hdl, 0LL, -1LL, "Recording starts"); sine_1 = 0.0; sampleswritten = 0; samples = fileduration * (long long)smp_freq; freqspan = stopfreq - startfreq; for(j=0; j<fileduration; j++) { for(i=0; i<smp_freq; i++) { q = M_PI * 2.0; q /= (smp_freq / freq); sine_1 += q; q = sin(sine_1); q *= 200.0; buf[i] = q; if(linear) { freq = startfreq + (freqspan * ((double)sampleswritten / (double)samples)); } else { // freq = exp10((((double)sampleswritten / (double)samples)) * log10(stopfreq)); freq = exp10(((((startfreq / stopfreq) * ((stopfreq / freqspan) * samples)) + sampleswritten) / ((stopfreq / freqspan) * samples)) * log10(stopfreq)); } sampleswritten++; } if(edfwrite_physical_samples(hdl, buf)) { printf("error: edfwrite_physical_samples()\n"); return(1); } if(!(j%10)) { sprintf(str, "%fHz", freq); remove_trailing_zeros(str); edfwrite_annotation_latin1(hdl, j * 10000LL, -1LL, str); } } sprintf(str, "%fHz", freq); remove_trailing_zeros(str); edfwrite_annotation_latin1(hdl, j * 10000LL, -1LL, str); edfwrite_annotation_latin1(hdl, fileduration * 10000LL, -1LL, "Recording ends"); edfclose_file(hdl); return(0); }
/* ==================================================================== */ int sci_edf_set_patientname(char *fname) { SciErr sciErr; int m1 = 0, n1 = 0; int *piAddressVarOne = NULL; int* piLenVarOne = NULL; double *pdVarOne = NULL; int iType1 = 0; int m2 = 0, n2 = 0; int *piAddressVarTwo = NULL; int* piLenVarTwo = NULL; char **stringData = NULL; int iType2 = 0; int m_out = 0, n_out = 0; double *dOut = NULL; int i; int handle; /* --> result = csum(3,8) /* check that we have only 2 parameters input */ /* check that we have only 1 parameters output */ CheckInputArgument(pvApiCtx,2,2) ; CheckOutputArgument(pvApiCtx,1,1) ; /* get Address of inputs */ sciErr = getVarAddressFromPosition(pvApiCtx, 1, &piAddressVarOne); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } sciErr = getVarAddressFromPosition(pvApiCtx, 2, &piAddressVarTwo); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } /* check input type */ sciErr = getVarType(pvApiCtx, piAddressVarOne, &iType1); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } if ( iType1 != sci_matrix ) { Scierror(999,"%s: Wrong type for input argument #%d: A integer expected.\n",fname,1); return 0; } sciErr = getVarType(pvApiCtx, piAddressVarTwo, &iType2); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } if ( iType2 != sci_strings ) { Scierror(999,"%s: Wrong type for input argument #%d: A string expected.\n",fname,2); return 0; } sciErr = getMatrixOfDouble(pvApiCtx, piAddressVarOne,&m1,&n1,&pdVarOne); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } /* get string */ sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo,&m2, &n2, NULL, NULL); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } piLenVarTwo = (int*)malloc(sizeof(int) * m2 * n2); sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &m2, &n2, piLenVarTwo, NULL); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } stringData = (char**)malloc(sizeof(char*) * m2 * n2); for(i = 0 ; i < n2 * m2 ; i++) { stringData[i] = (char*)malloc(sizeof(char) * (piLenVarTwo[i] + 1));//+ 1 for null termination } sciErr = getMatrixOfString(pvApiCtx, piAddressVarTwo, &m2, &n2, piLenVarTwo, stringData); if(sciErr.iErr) { printError(&sciErr, 0); return 0; } /* check size */ if ( (m1 != 1) || (n1 != 1) ) { Scierror(999,"%s: Wrong size for input argument #%d: A scalar expected.\n",fname,1); return 0; } if ( (m2 !=1) || (n2 !=1) ) { Scierror(999,"%s: Wrong size for input argument #%d: A single stringr expected.\n",fname,2); return 0; } /* call c function csum */ // csum(&pdVarOne[0],&pdVarTwo[0],&dOut); if ( edf_set_patientname(pdVarOne[0], stringData[0]) <0) { Scierror(999,"Could not write string\n"); return 0; } m_out = 1; n_out = 1; dOut = (double*)malloc(sizeof(double) * m_out*n_out); // CreateVar(1, MATRIX_OF_DOUBLE_DATATYPE, &m_out, &n_out, &dout); dOut[0]=0; /* create result on stack */ createMatrixOfDouble(pvApiCtx, nbInputArgument(pvApiCtx) + 1, m_out, n_out, dOut); free(dOut); AssignOutputVariable(pvApiCtx,1) = nbInputArgument(pvApiCtx) + 1; /* This function put on scilab stack, the lhs variable which are at the position lhs(i) on calling stack */ /* You need to add PutLhsVar here because WITHOUT_ADD_PUTLHSVAR was defined and equal to %t */ /* without this, you do not need to add PutLhsVar here */ ReturnArguments(pvApiCtx); return 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); }