int EDF_annotations::get_annotations(int file_num, struct edfhdrblock *edf_hdr, struct annotationblock **annotslist, int read_nk_trigger_signal) { int i, j, k, p, r=0, n, edfsignals, datarecords, recordsize, discontinuous, *annot_ch, nr_annot_chns, max, onset, duration, duration_start, zero, max_tal_ln, error, annots_in_record, annots_in_tal, samplesize=2, nk_triggers_smpls=0, nk_triggers_bufoffset=0, nk_triggers_enabled=0, nk_triggers_channel=0, nk_triggers_cnt=0, sf, progress_steps; unsigned short nk_triggerfields=0, nk_old_triggerfields=0; char *scratchpad, *cnv_buf, *time_in_txt, *duration_in_txt, nk_triggerlabel[16][32]; long long data_record_duration, elapsedtime, time_tmp=0LL, nk_trigger_sample_duration=0LL; FILE *inputfile; struct edfparamblock *edfparam; struct annotationblock *new_annotation=NULL, *temp_annotation; inputfile = edf_hdr->file_hdl; edfsignals = edf_hdr->edfsignals; recordsize = edf_hdr->recordsize; edfparam = edf_hdr->edfparam; nr_annot_chns = edf_hdr->nr_annot_chns; datarecords = edf_hdr->datarecords; data_record_duration = edf_hdr->long_data_record_duration; discontinuous = edf_hdr->discontinuous; annot_ch = edf_hdr->annot_ch; if(edf_hdr->edfplus) { samplesize = 2; } if(edf_hdr->bdfplus) { samplesize = 3; } if((edf_hdr->edfplus) && (read_nk_trigger_signal)) { if(data_record_duration == 1000000LL) { if(check_device(edf_hdr->plus_equipment) == 0) { for(i=0; i<edfsignals; i++) { if(!strcmp(edfparam[i].label, "Events/Markers ")) { sf = edf_hdr->edfparam[i].smp_per_record; error = 1; switch(sf) { case 10 : error = 0; break; case 20 : error = 0; break; case 50 : error = 0; break; case 100 : error = 0; break; } for(j=0; j<edfsignals; j++) { if(edf_hdr->edfparam[j].smp_per_record != sf) { if(!edf_hdr->edfparam[j].annotation) { error = 1; } } } if(edf_hdr->nr_annot_chns != 1) error = 1; if(!error) { nk_triggers_channel = i; nk_triggers_bufoffset = edfparam[nk_triggers_channel].buf_offset; nk_triggers_smpls = edfparam[nk_triggers_channel].smp_per_record; nk_trigger_sample_duration = data_record_duration / (long long)nk_triggers_smpls; strcpy(nk_triggerlabel[0], "CAL mode"); strcpy(nk_triggerlabel[1], "RESET condition"); strcpy(nk_triggerlabel[2], "External mark"); strcpy(nk_triggerlabel[3], "Photo/HV mark"); strcpy(nk_triggerlabel[4], "Remote mark"); strcpy(nk_triggerlabel[5], "HV mark"); strcpy(nk_triggerlabel[6], "DC trigger 9"); strcpy(nk_triggerlabel[7], "DC trigger 10"); strcpy(nk_triggerlabel[8], "DC trigger 11"); strcpy(nk_triggerlabel[9], "DC trigger 12"); strcpy(nk_triggerlabel[10], "DC trigger 13"); strcpy(nk_triggerlabel[11], "DC trigger 14"); strcpy(nk_triggerlabel[12], "DC trigger 15"); strcpy(nk_triggerlabel[13], "DC trigger 16"); strcpy(nk_triggerlabel[14], ""); strcpy(nk_triggerlabel[15], ""); nk_triggers_enabled = 1; edf_hdr->genuine_nk = 1; break; } } } } } } cnv_buf = (char *)calloc(1, recordsize); if(cnv_buf==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(cnv_buf)"); messagewindow.exec(); return(1); } max_tal_ln = 0; for(i=0; i<nr_annot_chns; i++) { if(max_tal_ln<edfparam[annot_ch[i]].smp_per_record * samplesize) max_tal_ln = edfparam[annot_ch[i]].smp_per_record * samplesize; } if(max_tal_ln<128) max_tal_ln = 128; scratchpad = (char *)calloc(1, max_tal_ln + 3); if(scratchpad==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(scratchpad)"); messagewindow.exec(); free(cnv_buf); return(1); } time_in_txt = (char *)calloc(1, max_tal_ln + 3); if(time_in_txt==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(time_in_txt)"); messagewindow.exec(); free(cnv_buf); free(scratchpad); return(1); } duration_in_txt = (char *)calloc(1, max_tal_ln + 3); if(duration_in_txt==NULL) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "Memory allocation error occurred when trying to read annotations.\n(duration_in_txt)"); messagewindow.exec(); free(cnv_buf); free(scratchpad); free(time_in_txt); return(1); } if(fseeko(inputfile, (long long)((edfsignals + 1) * 256), SEEK_SET)) { QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred when reading inputfile annotations. (fseek())"); messagewindow.exec(); free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(2); } QProgressDialog progress("Scanning file for annotations...", "Abort", 0, datarecords); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } elapsedtime = 0; for(i=0; i<datarecords; i++) { if(!(i%progress_steps)) { progress.setValue(i); qApp->processEvents(); if(progress.wasCanceled() == true) { edf_hdr->annots_not_read = 1; free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(11); } } if(fread(cnv_buf, recordsize, 1, inputfile)!=1) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "An error occurred while reading inputfile annotations. (fread())"); messagewindow.exec(); free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(2); } /************** process annotationsignals (if any) **************/ error = 0; for(r=0; r<nr_annot_chns; r++) { n = 0; zero = 0; onset = 0; duration = 0; duration_start = 0; scratchpad[0] = 0; annots_in_tal = 0; annots_in_record = 0; p = edfparam[annot_ch[r]].buf_offset; max = edfparam[annot_ch[r]].smp_per_record * samplesize; /************** process one annotation signal ****************/ if(cnv_buf[p + max - 1]!=0) { error = 5; goto END; } if(!r) /* if it's the first annotation signal, then check */ { /* the timekeeping annotation */ error = 1; for(k=0; k<(max-2); k++) { scratchpad[k] = cnv_buf[p + k]; if(scratchpad[k]==20) { if(cnv_buf[p + k + 1]!=20) { error = 6; goto END; } scratchpad[k] = 0; if(is_onset_number(scratchpad)) { error = 36; goto END; } else { time_tmp = get_long_time(scratchpad); if(i) { if(discontinuous) { if((time_tmp-elapsedtime)<data_record_duration) { error = 4; goto END; } } else { if((time_tmp-elapsedtime)!=data_record_duration) { error = 3; goto END; } } } else { if(time_tmp>=TIME_DIMENSION) { error = 2; goto END; } else { edf_hdr->starttime_offset = time_tmp; } } elapsedtime = time_tmp; error = 0; break; } } } } for(k=0; k<max; k++) { scratchpad[n] = cnv_buf[p + k]; if(!scratchpad[n]) { if(!zero) { if(k) { if(cnv_buf[p + k - 1]!=20) { error = 33; goto END; } } n = 0; onset = 0; duration = 0; duration_start = 0; scratchpad[0] = 0; annots_in_tal = 0; } zero++; continue; } if(zero>1) { error = 34; goto END; } zero = 0; if((scratchpad[n]==20)||(scratchpad[n]==21)) { if(scratchpad[n]==21) { if(duration||duration_start||onset||annots_in_tal) { /* it's not allowed to have multiple duration fields */ error = 35; /* in one TAL or to have a duration field which is */ goto END; /* not immediately behind the onsetfield */ } duration_start = 1; } if((scratchpad[n]==20)&&onset&&(!duration_start)) { if(r||annots_in_record) { if(n >= 0) { new_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(new_annotation==NULL) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred while reading annotations."); messagewindow.exec(); free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(1); } new_annotation->next_annotation = NULL; new_annotation->file_num = file_num; new_annotation->annotation[0] = 0; if(duration) strcpy(new_annotation->duration, duration_in_txt); else new_annotation->duration[0] = 0; for(j=0; j<n; j++) { if(j==MAX_ANNOTATION_LEN) break; new_annotation->annotation[j] = scratchpad[j]; } new_annotation->annotation[j] = 0; new_annotation->file_num = edf_hdr->file_num; new_annotation->onset = get_long_time(time_in_txt); if(*annotslist!=NULL) { temp_annotation = *annotslist; while(temp_annotation->next_annotation) temp_annotation = temp_annotation->next_annotation; new_annotation->former_annotation = temp_annotation; temp_annotation->next_annotation = new_annotation; } else { new_annotation->former_annotation = NULL; *annotslist = new_annotation; } } } annots_in_tal++; annots_in_record++; n = 0; continue; } if(!onset) { scratchpad[n] = 0; if(is_onset_number(scratchpad)) { error = 36; goto END; } onset = 1; n = 0; strcpy(time_in_txt, scratchpad); continue; } if(duration_start) { scratchpad[n] = 0; if(is_duration_number(scratchpad)) { error = 37; goto END; } for(j=0; j<n; j++) { if(j==15) break; duration_in_txt[j] = scratchpad[j]; if((duration_in_txt[j]<32)||(duration_in_txt[j]>126)) { duration_in_txt[j] = '.'; } } duration_in_txt[j] = 0; duration = 1; duration_start = 0; n = 0; continue; } } n++; } END: /****************** end ************************/ if(error) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "Can not read annotations because there is an EDF or BDF incompatibility in this file.\n" "For more information, run the EDF/BDF compatibility checker in the Tools menu."); messagewindow.exec(); free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(9); } } /************** process NK triggers ****************/ if(nk_triggers_enabled) { if(nk_triggers_cnt < 100000) { for(k=0; k<nk_triggers_smpls; k++) { nk_triggerfields = *((unsigned char *)cnv_buf + nk_triggers_bufoffset + (k * 2) + 1); nk_triggerfields <<= 8; nk_triggerfields += *((unsigned char *)cnv_buf + nk_triggers_bufoffset + (k * 2)); for(j=0; j<14; j++) { if((nk_triggerfields & (1 << j)) && (!(nk_old_triggerfields & (1 << j)))) { nk_triggers_cnt++; new_annotation = (struct annotationblock *)calloc(1, sizeof(struct annotationblock)); if(new_annotation==NULL) { progress.reset(); QMessageBox messagewindow(QMessageBox::Critical, "Error", "A memory allocation error occurred while reading annotations."); messagewindow.exec(); free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(1); } new_annotation->file_num = edf_hdr->file_num; new_annotation->next_annotation = NULL; new_annotation->file_num = file_num; strcpy(new_annotation->annotation, nk_triggerlabel[j]); new_annotation->onset = ((long long)i * data_record_duration) + ((long long)k * nk_trigger_sample_duration); new_annotation->onset += edf_hdr->starttime_offset; new_annotation->ident = (1 << ANNOT_ID_NK_TRIGGER); if(*annotslist!=NULL) { temp_annotation = *annotslist; while(temp_annotation->next_annotation) temp_annotation = temp_annotation->next_annotation; new_annotation->former_annotation = temp_annotation; temp_annotation->next_annotation = new_annotation; } else { new_annotation->former_annotation = NULL; *annotslist = new_annotation; } } } nk_old_triggerfields = nk_triggerfields; } } edf_hdr->nk_triggers_read = 1; } } edfplus_annotation_sort(&annotslist[file_num]); progress.reset(); free(cnv_buf); free(scratchpad); free(time_in_txt); free(duration_in_txt); return(0); }
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_Annotationswindow::updateList(void) { char str[MAX_ANNOTATION_LEN + 32], *str_tmp; int i, len, sequence_nr=0, jump=0, modified=0; QListWidgetItem *listitem; QString string; QByteArray ba; selected = -1; #ifdef Q_OS_WIN32 QFont specialfont("courier", 11, QFont::Normal, true); #else QFont specialfont("andale mono", 12, QFont::Normal, true); #endif specialfont.setPixelSize(12); list->clear(); edfplus_annotation_sort(&mainwindow->annotationlist[file_num]); annotation = mainwindow->annotationlist[file_num]; while(annotation != NULL) { if(annotation->hided_in_list) { annotation = annotation->next_annotation; sequence_nr++; continue; } string = QString::fromUtf8(annotation->annotation); ba = string.toUtf8(); str_tmp = ba.data(); len = 0; for(i=0; ; i++) { if(str_tmp[i]==0) break; if(((((unsigned char *)str_tmp)[i])&224)==192) len++; } for(i=0; i<len; i++) string.append(' '); if(relative) { if((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) < 0LL) { snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, " -%2i:%02i:%02i.%04i", (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600), (int)(((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60), (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60), (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL)); } else { snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, " %3i:%02i:%02i.%04i", (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600), (int)((((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60), (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60), (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL)); } } else { snprintf(str, MAX_ANNOTATION_LEN + 32, " %3i:%02i:%02i.%04i", (int)((((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) / TIME_DIMENSION)/ 3600) % 24), (int)((((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) / TIME_DIMENSION) % 3600) / 60), (int)(((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) / TIME_DIMENSION) % 60), (int)(((annotation->onset + mainwindow->edfheaderlist[file_num]->l_starttime) % TIME_DIMENSION) / 1000LL)); } str[MAX_ANNOTATION_LEN + 31] = 0; remove_trailing_zeros(str); if(string.size() < 20) { string = string.leftJustified(20, ' '); } string.append(QString::fromLatin1(str)); listitem = new QListWidgetItem(string, list); listitem->setData(Qt::UserRole, QVariant(sequence_nr)); if(annotation->modified==1) { listitem->setFont(specialfont); listitem->setForeground(Qt::red); modified = 1; } if((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) < 0LL) { snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, "onset: -%i:%02i:%02i.%04i", (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600), (int)(((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60), (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60), (int)((-(annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL)); } else { snprintf(str, (MAX_ANNOTATION_LEN + 32) / 2, "onset: %2i:%02i:%02i.%04i", (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION)/ 3600), (int)((((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 3600) / 60), (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) / TIME_DIMENSION) % 60), (int)(((annotation->onset - mainwindow->edfheaderlist[file_num]->starttime_offset) % TIME_DIMENSION) / 1000LL)); } if(annotation->duration[0]!=0) { snprintf(str + strlen(str), (MAX_ANNOTATION_LEN + 32) / 2, "\nduration: %s",annotation->duration); } str[MAX_ANNOTATION_LEN + 31] = 0; remove_trailing_zeros(str); strcat(str, "\n\n"); string = QString::fromLatin1(str); string.append(QString::fromUtf8(annotation->annotation)); listitem->setToolTip(string); if(annotation->selected) { selected = sequence_nr; annotation->selected = 0; if(annotation->jump) { jump = 1; annotation->jump = 0; } } annotation = annotation->next_annotation; sequence_nr++; } if(mainwindow->annot_editor_active) { if(selected>=0) { list->setCurrentRow(selected, QItemSelectionModel::ClearAndSelect); mainwindow->annotationEditDock->set_selected_annotation(file_num, selected); if(jump) { jump = 0; annotation_selected(list->currentItem()); } selected = -1; } if(modified) { mainwindow->annotations_edited = 1; mainwindow->save_act->setEnabled(true); } } }
void UI_ReduceSignalsWindow::StartConversion() { int i, j, k, n, new_edfsignals, datarecords=0, annot_smp_per_record, annot_recordsize, timestamp_digits=0, timestamp_decimals=0, annot_len, tallen=0, len, annot_cnt, annots_per_datrec=0, smplrt, tmp, val, progress_steps, datrecs_processed; char *readbuf=NULL, scratchpad[256]; long long new_starttime, time_diff, onset_diff, taltime, l_temp, endtime=0, l_tmp; struct date_time_struct dts; struct annotationblock *new_annot_list=NULL, *root_new_annot_list=NULL, *annot_list=NULL; union { unsigned int one; signed int one_signed; unsigned short two[2]; signed short two_signed[2]; unsigned char four[4]; } var; QProgressDialog progress("Processing file...", "Abort", 0, 1); progress.setWindowModality(Qt::WindowModal); progress.setMinimumDuration(200); pushButton3->setEnabled(false); pushButton4->setEnabled(false); pushButton5->setEnabled(false); pushButton6->setEnabled(false); spinBox1->setEnabled(false); spinBox2->setEnabled(false); spinBox3->setEnabled(false); spinBox4->setEnabled(false); radioButton1->setEnabled(false); radioButton2->setEnabled(false); label2->setEnabled(false); label3->setEnabled(false); if(edfhdr==NULL) { return; } if(file_num < 0) { return; } new_edfsignals = 0; annot_smp_per_record = 0; annot_cnt = 0; aa_filter_order = spinBox4->value() - 1; time_diff = (long long)(spinBox1->value() - 1) * edfhdr->long_data_record_duration; taltime = (time_diff + edfhdr->starttime_offset) % TIME_DIMENSION; endtime = (long long)(spinBox2->value() - (spinBox1->value() - 1)) * edfhdr->long_data_record_duration + taltime; for(i=0; i<edfhdr->edfsignals; i++) { if(!edfhdr->edfparam[i].annotation) { if(((QCheckBox *)(SignalsTablewidget->cellWidget(i, 0)))->checkState()==Qt::Checked) { signalslist[new_edfsignals] = i; dividerlist[new_edfsignals] = ((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->itemData(((QComboBox *)(SignalsTablewidget->cellWidget(i, 1)))->currentIndex()).toInt(); new_edfsignals++; } } } datarecords = spinBox2->value() - spinBox1->value() + 1; if(edfhdr->edfplus || edfhdr->bdfplus) { timestamp_decimals = get_tal_timestamp_decimal_cnt(edfhdr); if(timestamp_decimals < 0) { showpopupmessage("Error", "Internal error, get_tal_timestamp_decimal_cnt("); goto END_1; } timestamp_digits = get_tal_timestamp_digit_cnt(edfhdr); if(timestamp_digits < 0) { showpopupmessage("Error", "Internal error, get_tal_timestamp_digit_cnt("); goto END_1; } annot_list = mainwindow->annotationlist[file_num]; while(annot_list != NULL) { l_temp = annot_list->onset - time_diff; if((l_temp >= 0LL) && (l_temp <= endtime)) { annot_cnt++; edfplus_annotation_add_copy(&new_annot_list, annot_list); } annot_list = annot_list->next_annotation; } annot_list = new_annot_list; root_new_annot_list = new_annot_list; new_starttime = edfhdr->utc_starttime + ((time_diff + edfhdr->starttime_offset) / TIME_DIMENSION); onset_diff = (new_starttime - edfhdr->utc_starttime) * TIME_DIMENSION; while(annot_list != NULL) { annot_list->onset -= onset_diff; annot_list = annot_list->next_annotation; } edfplus_annotation_sort(&new_annot_list); annots_per_datrec = annot_cnt / datarecords; if(annot_cnt % datarecords) { annots_per_datrec++; } annot_len = get_max_annotation_strlen(&new_annot_list); if(!annot_cnt) { annots_per_datrec = 0; } annot_recordsize = (annot_len * annots_per_datrec) + timestamp_digits + timestamp_decimals + 4; if(timestamp_decimals) { annot_recordsize++; } if(edfhdr->edf) { annot_smp_per_record = annot_recordsize / 2; if(annot_recordsize % annot_smp_per_record) { annot_smp_per_record++; annot_recordsize = annot_smp_per_record * 2; } } else { annot_smp_per_record = annot_recordsize / 3; if(annot_recordsize % annot_smp_per_record) { annot_smp_per_record++; annot_recordsize = annot_smp_per_record * 3; } } } else { annot_smp_per_record = 0; annot_recordsize = 0; } readbuf = (char *)malloc(edfhdr->recordsize); if(readbuf==NULL) { showpopupmessage("Error", "Malloc error, (readbuf)."); goto END_2; } /////////////////////////////////////////////////////////////////// for(i=0; i<new_edfsignals; i++) { if(dividerlist[i] > 1) { for(j=0; j<aa_filter_order; j++) { filterlist[i][j] = create_ravg_filter(1, dividerlist[i]); if(filterlist[i][j] == NULL) { showpopupmessage("Error", "Malloc error, (create_ravg_filter())."); goto END_3; } } } } /////////////////////////////////////////////////////////////////// outputpath[0] = 0; if(recent_savedir[0]!=0) { strcpy(outputpath, recent_savedir); strcat(outputpath, "/"); } len = strlen(outputpath); get_filename_from_path(outputpath + len, inputpath, MAX_PATH_LENGTH - len); remove_extension_from_filename(outputpath); if(edfhdr->edf) { strcat(outputpath, "_reduced.edf"); strcpy(outputpath, QFileDialog::getSaveFileName(0, "Save file", QString::fromLocal8Bit(outputpath), "EDF files (*.edf *.EDF)").toLocal8Bit().data()); } else { strcat(outputpath, "_reduced.bdf"); strcpy(outputpath, QFileDialog::getSaveFileName(0, "Save file", QString::fromLocal8Bit(outputpath), "BDF files (*.bdf *.BDF)").toLocal8Bit().data()); } if(!strcmp(outputpath, "")) { goto END_3; } get_directory_from_path(recent_savedir, outputpath, MAX_PATH_LENGTH); if(mainwindow->file_is_opened(outputpath)) { showpopupmessage("Reduce signals", "Error, selected file is in use."); goto END_3; } outputfile = fopeno(outputpath, "wb"); if(outputfile==NULL) { showpopupmessage("Error", "Can not open outputfile for writing."); goto END_3; } new_starttime = edfhdr->utc_starttime + ((time_diff + edfhdr->starttime_offset) / TIME_DIMENSION); utc_to_date_time(new_starttime, &dts); rewind(inputfile); if(fread(scratchpad, 168, 1, inputfile)!=1) { showpopupmessage("Error", "Read error (1)."); goto END_4; } if(edfhdr->edfplus || edfhdr->bdfplus) { if(scratchpad[98] != 'X') { sprintf(scratchpad + 98, "%02i-%s-%04i", dts.day, dts.month_str, dts.year); scratchpad[109] = ' '; } } if(fwrite(scratchpad, 168, 1, outputfile)!=1) { showpopupmessage("Error", "Write error (1)."); goto END_4; } fprintf(outputfile, "%02i.%02i.%02i%02i.%02i.%02i", dts.day, dts.month, dts.year % 100, dts.hour, dts.minute, dts.second); if(edfhdr->edfplus || edfhdr->bdfplus) { fprintf(outputfile, "%-8i", new_edfsignals * 256 + 512); } else { fprintf(outputfile, "%-8i", new_edfsignals * 256 + 256); } if(edfhdr->edfplus) { fprintf(outputfile, "EDF+C"); for(i=0; i<39; i++) { fputc(' ', outputfile); } } if(edfhdr->bdfplus) { fprintf(outputfile, "BDF+C"); for(i=0; i<39; i++) { fputc(' ', outputfile); } } if((!edfhdr->edfplus) && (!edfhdr->bdfplus)) { for(i=0; i<44; i++) { fputc(' ', outputfile); } } fprintf(outputfile, "%-8i", datarecords); snprintf(scratchpad, 256, "%f", edfhdr->data_record_duration); convert_trailing_zeros_to_spaces(scratchpad); if(scratchpad[7]=='.') { scratchpad[7] = ' '; } scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); if(edfhdr->edfplus || edfhdr->bdfplus) { fprintf(outputfile, "%-4i", new_edfsignals + 1); } else { fprintf(outputfile, "%-4i", new_edfsignals); } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].label); } if(edfhdr->edfplus) { fprintf(outputfile, "EDF Annotations "); } if(edfhdr->bdfplus) { fprintf(outputfile, "BDF Annotations "); } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].transducer); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<80; i++) { fputc(' ', outputfile); } } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].physdimension); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<8; i++) { fputc(' ', outputfile); } } for(i=0; i<new_edfsignals; i++) { snprintf(scratchpad, 256, "%f", edfhdr->edfparam[signalslist[i]].phys_min); convert_trailing_zeros_to_spaces(scratchpad); if(scratchpad[7]=='.') { scratchpad[7] = ' '; } scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); } if(edfhdr->edfplus || edfhdr->bdfplus) { fprintf(outputfile, "-1 "); } for(i=0; i<new_edfsignals; i++) { snprintf(scratchpad, 256, "%f", edfhdr->edfparam[signalslist[i]].phys_max); convert_trailing_zeros_to_spaces(scratchpad); if(scratchpad[7]=='.') { scratchpad[7] = ' '; } scratchpad[8] = 0; fprintf(outputfile, "%s", scratchpad); } if(edfhdr->edfplus || edfhdr->bdfplus) { fprintf(outputfile, "1 "); } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].dig_min); } if(edfhdr->edfplus) { fprintf(outputfile, "-32768 "); } if(edfhdr->bdfplus) { fprintf(outputfile, "-8388608"); } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].dig_max); } if(edfhdr->edfplus) { fprintf(outputfile, "32767 "); } if(edfhdr->bdfplus) { fprintf(outputfile, "8388607 "); } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%s", edfhdr->edfparam[signalslist[i]].prefilter); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<80; i++) { fputc(' ', outputfile); } } for(i=0; i<new_edfsignals; i++) { fprintf(outputfile, "%-8i", edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i]); } if(edfhdr->edfplus || edfhdr->bdfplus) { fprintf(outputfile, "%-8i", annot_smp_per_record); } for(i=0; i<(new_edfsignals * 32); i++) { fputc(' ', outputfile); } if(edfhdr->edfplus || edfhdr->bdfplus) { for(i=0; i<32; i++) { fputc(' ', outputfile); } } /////////////////////////////////////////////////////////////////// progress.setRange(0, datarecords); progress.setValue(0); progress_steps = datarecords / 100; if(progress_steps < 1) { progress_steps = 1; } fseeko(inputfile, (long long)edfhdr->hdrsize + ((long long)(spinBox1->value() - 1) * (long long)edfhdr->recordsize), SEEK_SET); for(datrecs_processed=0; datrecs_processed<datarecords; datrecs_processed++) { if(!(datrecs_processed % progress_steps)) { progress.setValue(datrecs_processed); qApp->processEvents(); if(progress.wasCanceled() == true) { goto END_4; } } if(fread(readbuf, edfhdr->recordsize, 1, inputfile) != 1) { progress.reset(); showpopupmessage("Error", "Read error (2)."); goto END_4; } if(edfhdr->edf) { for(i=0; i<new_edfsignals; i++) { if(dividerlist[i] == 1) { smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record; for(j=0; j<smplrt; j++) { fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 2)], outputfile); if(fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 2) + 1], outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (4)."); goto END_4; } } } else { smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i]; for(j=0; j<smplrt; j++) { tmp = 0; for(k=0; k<dividerlist[i]; k++) { val = *(((signed short *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset)) + (dividerlist[i] * j) + k); for(n=0; n<aa_filter_order; n++) { val = run_ravg_filter(val, filterlist[i][n]); } tmp += val; } tmp /= dividerlist[i]; fputc(tmp & 0xff, outputfile); if(fputc((tmp >> 8) & 0xff, outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (4)."); goto END_4; } } } } } else { for(i=0; i<new_edfsignals; i++) { if(dividerlist[i] == 1) { smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record; for(j=0; j<smplrt; j++) { fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3)], outputfile); fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 1], outputfile); if(fputc(readbuf[edfhdr->edfparam[signalslist[i]].buf_offset + (j * 3) + 2], outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (4)."); goto END_4; } } } else { smplrt = edfhdr->edfparam[signalslist[i]].smp_per_record / dividerlist[i]; for(j=0; j<smplrt; j++) { l_tmp = 0LL; for(k=0; k<dividerlist[i]; k++) { var.two[0] = *((unsigned short *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset + (dividerlist[i] * j * 3) + (k * 3))); var.four[2] = *((unsigned char *)(readbuf + edfhdr->edfparam[signalslist[i]].buf_offset + (dividerlist[i] * j * 3) + (k * 3) + 2)); if(var.four[2]&0x80) { var.four[3] = 0xff; } else { var.four[3] = 0x00; } for(n=0; n<aa_filter_order; n++) { var.one_signed = run_ravg_filter(var.one_signed, filterlist[i][n]); } l_tmp += var.one_signed; } l_tmp /= dividerlist[i]; fputc(l_tmp & 0xff, outputfile); fputc((l_tmp >> 8) & 0xff, outputfile); if(fputc((l_tmp >> 16) & 0xff, outputfile)==EOF) { progress.reset(); showpopupmessage("Error", "Write error (4)."); goto END_4; } } } } } if(edfhdr->edfplus || edfhdr->bdfplus) { switch(timestamp_decimals) { case 0 : tallen = fprintf(outputfile, "+%i", (int)(taltime / TIME_DIMENSION)); break; case 1 : tallen = fprintf(outputfile, "+%i.%01i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 1000000LL)); break; case 2 : tallen = fprintf(outputfile, "+%i.%02i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 100000LL)); break; case 3 : tallen = fprintf(outputfile, "+%i.%03i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 10000LL)); break; case 4 : tallen = fprintf(outputfile, "+%i.%04i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 1000LL)); break; case 5 : tallen = fprintf(outputfile, "+%i.%05i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 100LL)); break; case 6 : tallen = fprintf(outputfile, "+%i.%06i", (int)(taltime / TIME_DIMENSION), (int)((taltime % TIME_DIMENSION) / 10LL)); break; case 7 : tallen = fprintf(outputfile, "+%i.%07i", (int)(taltime / TIME_DIMENSION), (int)(taltime % TIME_DIMENSION)); break; } fputc(20, outputfile); fputc(20, outputfile); fputc(0, outputfile); tallen += 3; if(new_annot_list != NULL) { for(i=0; i<annots_per_datrec; i++) { if(new_annot_list != NULL) { len = snprintf(scratchpad, 256, "%+i.%07i", (int)(new_annot_list->onset / TIME_DIMENSION), (int)(new_annot_list->onset % TIME_DIMENSION)); for(j=0; j<7; j++) { if(scratchpad[len - j - 1] != '0') { break; } } if(j) { len -= j; if(j == 7) { len--; } } if(fwrite(scratchpad, len, 1, outputfile) != 1) { progress.reset(); showpopupmessage("Error", "Write error (5)."); goto END_4; } tallen += len; if(new_annot_list->duration[0]!=0) { fputc(21, outputfile); tallen++; tallen += fprintf(outputfile, "%s", new_annot_list->duration); } fputc(20, outputfile); tallen++; tallen += fprintf(outputfile, "%s", new_annot_list->annotation); fputc(20, outputfile); fputc(0, outputfile); tallen += 2; new_annot_list = new_annot_list->next_annotation; } } } for(k=tallen; k<annot_recordsize; k++) { fputc(0, outputfile); } taltime += edfhdr->long_data_record_duration; } }